8 个版本 (4 个重大更改)
0.39.0 | 2023 年 10 月 29 日 |
---|---|
0.38.4 | 2023 年 10 月 23 日 |
0.28.1 | 2022 年 12 月 6 日 |
0.27.1 | 2022 年 11 月 29 日 |
0.26.1 | 2022 年 10 月 30 日 |
#10 in #query-parser
每月 62 次下载
1MB
19K 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")], filter: None, 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(https://github.com/apache/arrow-datafusion)、LocustDB(https://github.com/cswinter/LocustDB)、Ballista(https://github.com/apache/arrow-ballista)、GlueSQL(https://github.com/gluesql/gluesql)、Opteryx(https://github.com/mabel-dev/opteryx)和JumpWire(https://github.com/extragoodlabs/jumpwire)。
如果您正在使用sqlparser-rs,请随时提交PR将其添加到此列表。
设计
核心表达式解析器采用Pratt解析器设计,这是一种自顶向下的运算符优先(TDOP)解析器,而周围的SQL语句解析器是一个传统的、手工编写的递归下降解析器。Eli Bendersky有一个很好的TDOP解析器教程,如果您想了解更多关于这种技术,请参阅。
我们更喜欢这种设计模式而不是解析器生成器,以下是一些原因:
- 代码简单易写,可以简洁优雅。
- 性能通常优于解析器生成器生成的代码。
- 使用手工代码进行调试要容易得多。
- 与使用解析器生成器相比,扩展和创建特定方言的扩展要容易得多。
支持自定义SQL方言
这是一个正在进行中的工作,但我们有一些关于编写自定义SQL解析器的笔记。
贡献
我们非常欢迎贡献!然而,我们维护此crate的带宽有限。请仔细阅读以下部分。
新语法
最常接受的PR是添加对SQL标准或流行的RDBMS(如Microsoft SQL Server或PostgreSQL)中的功能的支持或修复一个功能中的错误。任何特定方言的SQL功能都应该由相关的Dialect
以及GenericDialect
解析。
重大API更改
当前维护者不计划对此crate的API进行任何重大更改。不打算接受的PR是提议进行重大重构的。
测试
虽然我们希望尽快审查PR,但可能需要一周或更长时间。为了加快进程,请确保PR通过了所有CI检查,并包括测试以证明您的代码按预期工作(并避免回归)。请记住还要测试错误路径。
没有测试的PR将不会被审查或合并。由于CI确保了cargo test
、cargo fmt
和cargo clippy
都通过,你应该在提交PR之前本地运行这三个命令。
提交问题
如果你无法提交补丁,请随意提交一个问题。请尽量包括
- 你希望支持或修复的语法的代表性示例;
- 如果该语法是SQL:2016的一部分,则相关SQL语法的部分;以及
- 支持该特性的几个最受欢迎的数据库的文档链接。
不幸的是,如果你需要支持某个特性,你可能需要自己实现它,或者提交一个描述足够好的ticket,以便社区的其他成员可以这样做。作为维护者,我们的目标是促进从各种贡献者那里集成各种特性,但不是我们自己提供实现,因为我们没有这样的资源。
许可
此存储库中的所有代码均根据Apache Software License 2.0授权。
除非你明确声明,否则根据Apache-2.0许可定义的,任何有意提交以包含在你工作的贡献,都应按上述方式授权,不附加任何额外条款或条件。
依赖关系
~46–710KB
~16K SLoC