apache / apache/datafusion-sqlparser-rs
The way BinaryOp works on `XOR` is different from `AND` and `OR`
- Vorherrschende Sprache
- Rust
- Sterne
- 3.5k
- Forks
- 772
- Ø Merge
- 4 T. 9 Std.
- Gemergte PRs (30 T.)
- 17
Beschreibung
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 })]
```
Beitragsleitfaden
Für dieses Repository ist kein Beitragsleitfaden indexiert
Rechercherichtung
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.
Vom Indexierungsmodell aus dem Issue-Text verfasst.
Bewertung
- Tech-Stack
- rust
- Bereich
- compilers
- Issue-Typ
- Bug
- Schwierigkeit
- 3/5
- Geschätzter Aufwand
- 1-2 Tage
- Aktivitätsstatus
- Veraltet
- Klarheit
- Größtenteils klar
- Anfängerfreundlichkeit
- 35/100