apache / apache/datafusion-sqlparser-rs

The way BinaryOp works on `XOR` is different from `AND` and `OR`

Ouverte
#544 6 commentaires 0 réactions 0 personnes assignées Voir sur GitHub
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

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.