1 个不稳定版本
0.32.0 | 2023年3月24日 |
---|
1202 在 解析器实现 中
1,885 次每月下载
690KB
15K SLoC
Rust 的可扩展 SQL 词法和解析器
本软件包包含一个符合 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 节点的Serialize
和Deserialize
添加 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查询引擎、LocustDB、Ballista、GlueSQL和Opteryx等查询引擎使用。
如果您的项目正在使用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 test
、cargo fmt
和cargo clippy
通过,您在提交PR之前可能需要在本地运行所有三个命令。
如果您无法提交补丁,请随时提交问题。请尝试包括
- 您希望支持或修复的语法的几个代表性示例;
- 如果该语法是 SQL:2016 的一部分,相关的语法部分 SQL 语法;以及
- 指向支持该特性的几个最受欢迎的数据库的文档链接。
如果您需要支持某个特性,您可能需要自己实现它。作为维护者,我们的目标是促进来自不同贡献者的各种特性的集成,但不是我们自己提供实现,因为我们没有这样的资源。
许可协议
本存储库中的所有代码均根据 Apache 软件许可证 2.0 许可。
除非您明确说明,否则您提交给作品以供包括在内的任何贡献,根据 Apache-2.0 许可证的定义,应按照上述方式许可,不附加任何额外条款或条件。
依赖关系
~46–500KB
~11K SLoC