apache / apache/datafusion-sqlparser-rs
The way BinaryOp works on `XOR` is different from `AND` and `OR`
- Langage dominant
- Rust
- Étoiles
- 3.5k
- Forks
- 772
- Merge moyen
- 4 j 9 h
- PR mergées (30 j)
- 17
Description
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 })]
```
Guide de contribution
Aucun guide de contribution indexé pour ce dépôt
Piste de recherche
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.
Rédigé par le modèle d'indexation à partir du texte de l'issue.
Évaluation
- Stack technique
- rust
- Domaine
- compilers
- Type d'issue
- Bug
- Difficulté
- 3/5
- Temps estimé
- 1-2 jours
- Activité
- À l'abandon
- Clarté
- Plutôt claire
- Accessibilité débutants
- 35/100