#lexer #sql-parser #sql #sql-query #parser #ansi #query-engine

no-std sqlparser-lance

sqlparser-rs 项目的分支

1 个不稳定版本

0.32.0 2023年3月24日

1202解析器实现

Download history 28/week @ 2024-03-23 14/week @ 2024-03-30 1/week @ 2024-04-06

1,885 次每月下载

Apache-2.0

690KB
15K SLoC

Rust 的可扩展 SQL 词法和解析器

License Version Build Status Coverage Status Gitter Chat

本软件包包含一个符合 ANSI/ISO SQL 标准和其他方言的 SQL 词法和解析器。本软件包用作 SQL 查询引擎、特定供应商的解析器和各种 SQL 分析的基础。

示例

解析一个简单的 SELECT 语句

use sqlparser::dialect::GenericDialect;
use sqlparser::parser::Parser;

let sql = "SELECT a, b, 123, myfunc(b) \
           FROM table_1 \
           WHERE a > b AND b < 100 \
           ORDER BY a DESC, b";

let dialect = GenericDialect {}; // or AnsiDialect, or your own dialect ...

let ast = Parser::parse_sql(&dialect, sql).unwrap();

println!("AST: {:?}", ast);

输出如下

AST: [Query(Query { ctes: [], body: Select(Select { distinct: false, projection: [UnnamedExpr(Identifier("a")), UnnamedExpr(Identifier("b")), UnnamedExpr(Value(Long(123))), UnnamedExpr(Function(Function { name: ObjectName(["myfunc"]), args: [Identifier("b")], over: None, distinct: false }))], from: [TableWithJoins { relation: Table { name: ObjectName(["table_1"]), alias: None, args: [], with_hints: [] }, joins: [] }], selection: Some(BinaryOp { left: BinaryOp { left: Identifier("a"), op: Gt, right: Identifier("b") }, op: And, right: BinaryOp { left: Identifier("b"), op: Lt, right: Value(Long(100)) } }), group_by: [], having: None }), order_by: [OrderByExpr { expr: Identifier("a"), asc: Some(false) }, OrderByExpr { expr: Identifier("b"), asc: None }], limit: None, offset: None, fetch: None })]

功能

以下可选的 软件包功能 可用:

  • serde:通过实现所有 AST 节点的 SerializeDeserialize 添加 Serde 支持。
  • visitor:添加一个能够递归遍历 AST 树的 Visitor

语法与语义

本软件包仅提供语法解析器,并尽量不应用任何 SQL 语义,接受特定数据库会拒绝的查询,即使在使用该数据库特定的 Dialect 的情况下。例如,CREATE TABLE(x int, x int) 被本软件包接受,尽管大多数 SQL 引擎会由于重复的列名 x 而拒绝此语句。

由于语义分析在方言和实现之间差异很大,本软件包避免了语义分析。如果您想进行语义分析,请随时使用此项目作为基础。

SQL 兼容性

SQL 首次于 1987 年标准化,并且自那时以来定期发布了标准的修订版。大多数修订版都为语言添加了重要的新功能,因此没有数据库声称支持该语言的全套功能。此解析器目前支持 SQL-92 的大多数语法,以及一些已明确请求的新版本语法,以及一些 MSSQL、PostgreSQL 和其他特定方言的语法。尽可能使用 在线 SQL:2016 语法 来指导接受哪些语法。

不幸的是,对合规性做更具体的说明是比较困难的。没有公开可用的测试套件可以自动评估合规性,而手动进行则会消耗项目有限的资源。尽管如此,我们最终希望支持完整的SQL方言,并且我们正在逐步构建自己的测试套件。

如果您正在评估该项目是否适合您的需求,您可能需要通过实验验证它是否支持您需要的SQL子集。请提交您发现的任何不受支持的查询的问题。这样做有助于我们优先支持实际使用的标准部分。请注意,如果您急需支持某个功能,您可能需要自己编写实现。有关详细信息,请参阅贡献部分。

命令行

此crate包含一个CLI程序,可以解析文件并将结果以JSON格式输出

$ cargo run --features json_example --example cli FILENAME.sql [--dialectname]

用户

此解析器目前正在被DataFusion查询引擎、LocustDBBallistaGlueSQLOpteryx等查询引擎使用。

如果您的项目正在使用sqlparser-rs,请随意提交PR将其添加到此列表。

设计

核心表达式解析器使用Pratt解析器设计,这是一种自顶向下操作符优先(TDOP)解析器,而周围的SQL语句解析器是一个传统的、手动编写的递归下降解析器。如果您对TDOP解析器技术感兴趣,Eli Bendersky有一个很好的教程

我们喜欢这种设计模式胜过解析器生成器,原因如下

  • 代码易于编写,可以简洁且优雅
  • 性能通常优于解析器生成器生成的代码
  • 手动编写的代码更容易调试
  • 与使用解析器生成器相比,扩展和创建特定方言的扩展要容易得多

支持自定义SQL方言

这是一个正在进行中的工作,但我们有一些关于编写自定义SQL解析器的笔记。

贡献

我们非常欢迎贡献!然而,我们维护此crate的带宽相当有限。

提交的PR如果添加了对SQL标准中某个功能的支持或修复了某个流行RDBMS(如Microsoft SQL Server或PostgreSQL)中某个功能的bug,则可能经过简要审查后被接受。

当前维护者目前不计划对此crate的API进行任何重大更改。因此,提议重大重构的PR可能不会被接受。

请注意,虽然我们希望以合理的时间审查PR,但可能需要一段时间。为了加快进程,请确保PR通过所有CI检查,并包含演示您的代码按预期工作的测试(以及避免回归)。请记住,也要测试错误路径。

没有测试的PR将不会被审查或合并。由于CI确保cargo testcargo fmtcargo clippy通过,您在提交PR之前可能需要在本地运行所有三个命令。

如果您无法提交补丁,请随时提交问题。请尝试包括

  • 您希望支持或修复的语法的几个代表性示例;
  • 如果该语法是 SQL:2016 的一部分,相关的语法部分 SQL 语法;以及
  • 指向支持该特性的几个最受欢迎的数据库的文档链接。

如果您需要支持某个特性,您可能需要自己实现它。作为维护者,我们的目标是促进来自不同贡献者的各种特性的集成,但不是我们自己提供实现,因为我们没有这样的资源。

许可协议

本存储库中的所有代码均根据 Apache 软件许可证 2.0 许可。

除非您明确说明,否则您提交给作品以供包括在内的任何贡献,根据 Apache-2.0 许可证的定义,应按照上述方式许可,不附加任何额外条款或条件。

依赖关系

~46–500KB
~11K SLoC