apache / apache/datafusion-sqlparser-rs
The way BinaryOp works on `XOR` is different from `AND` and `OR`
- 主要言語
- Rust
- スター
- 3.5k
- フォーク
- 772
- 平均マージ
- 4日 9時間
- マージ済み PR(30日)
- 17
説明
When you run `a > 10 OR b < 10`, `BinaryOp`s wrap around `(a > 10)`, `(b < 10)`, and `(a > 10) OR (b < 10)`.
However, when you run `a > 10 XOR b < 10`, `BinaryOp`s wrap around `(10 XOR b)`, `(a > (10 XOR b))`, `((a > (10 XOR b)) < 10)`. Which is really confusing and hard to predict.
Can someone explain why, or fix it if this is a bug?
Please check the code below for more info.
```rust
let sql = "SELECT a FROM table_1 WHERE a > 10 XOR b < 10";
let dialect = GenericDialect {};
let ast = Parser::parse_sql(&dialect, sql).unwrap();
println!("AST: {:?}", ast);
// AST: [Query(Query { with: None, body: Select(Select { distinct: false, top: None, projection: [UnnamedExpr(Identifier(Ident { value: "a", quote_style: None }))], into: None, from: [TableWithJoins { relation: Table { name: ObjectName([Ident { value: "table_1", quote_style: None }]), alias: None, args: None, with_hints: [] }, joins: [] }], lateral_views: [], selection: Some(BinaryOp { left: BinaryOp { left: Identifier(Ident { value: "a", quote_style: None }), op: Gt, right: BinaryOp { left: Value(Number("10", false)), op: Xor, right: Identifier(Ident { value: "b", quote_style: None }) } }, op: Lt, right: Value(Number("10", false)) }), group_by: [], cluster_by: [], distribute_by: [], sort_by: [], having: None, qualify: None }), order_by: [], limit: None, offset: None, fetch: None, lock: None })]
```
```rust
let sql = "SELECT a FROM table_1 WHERE a > 10 OR b < 10";
let dialect = GenericDialect {};
let ast = Parser::parse_sql(&dialect, sql).unwrap();
println!("AST: {:?}", ast);
// AST: [Query(Query { with: None, body: Select(Select { distinct: false, top: None, projection: [UnnamedExpr(Identifier(Ident { value: "a", quote_style: None }))], into: None, from: [TableWithJoins { relation: Table { name: ObjectName([Ident { value: "table_1", quote_style: None }]), alias: None, args: None, with_hints: [] }, joins: [] }], lateral_views: [], selection: Some(BinaryOp { left: BinaryOp { left: Identifier(Ident { value: "a", quote_style: None }), op: Gt, right: Value(Number("10", false)) }, op: Or, right: BinaryOp { left: Identifier(Ident { value: "b", quote_style: None }), op: Lt, right: Value(Number("10", false)) } }), group_by: [], cluster_by: [], distribute_by: [], sort_by: [], having: None, qualify: None }), order_by: [], limit: None, offset: None, fetch: None, lock: None })]
```
コントリビューションガイド
このリポジトリのコントリビューションガイドは索引されていません
調査の方向性
Start at the Parser::parse_sql entry point and trace how expressions containing XOR, AND, and OR are parsed into BinaryOp nodes. Compare the ASTs for the two SQL examples and determine the intended XOR precedence; done means the behavior is explained or corrected and the examples produce an intentional, consistent AST.
索引モデルが issue の本文から書いたものです。
評価
- 技術スタック
- rust
- 領域
- compilers
- issue の種類
- バグ
- 難易度
- 3/5
- 見積もり時間
- 1〜2日
- 活発さ
- 停滞
- 明瞭さ
- おおむね明確
- 初心者へのやさしさ
- 35/100