apache / apache/datafusion-sqlparser-rs

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

Abierto
#544 6 comentarios 0 reacciones 0 asignados Ver en GitHub
Lenguaje dominante
Rust
Estrellas
3.5k
Forks
772
Merge medio
4 d 9 h
PR fusionados (30 d)
17

Descripción

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 })]
```

Guía de contribución

No hay ninguna guía de contribución indexada para este repositorio

Línea de trabajo

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.

Escrito por el modelo de indexación a partir del texto del issue.

Evaluación

Stack tecnológico
rust
Área
compilers
Tipo de issue
Error
Dificultad
3/5
Tiempo estimado
1-2 días
Estado de actividad
Estancado
Claridad
Bastante claro
Aptitud para principiantes
35/100

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.