Incorrect parentheses in expression display with NOT operator
- Dominant language
- Rust
- Stars
- 9.3k
- Forks
- 2.4k
- Avg merge
- 3d 7h
- Merged PRs (30d)
- 344
Description
### Describe the bug
If we have the binary expression `(a OR b) AND NOT (a AND b)`, it is displayed incorrectly as `(a OR b) AND NOT a AND b` (relevant code [here](https://github.com/apache/datafusion/blob/2a7f64a85e3d98c51c106607a425d73d2b839e82/datafusion/expr/src/expr.rs#L508) and [here](https://github.com/apache/datafusion/blob/2a7f64a85e3d98c51c106607a425d73d2b839e82/datafusion/expr/src/expr.rs#L3028)). This implies that the NOT is only on `a`, rather than on the full binary expression `a AND b`.
This also applies for other expressions, such as IS NULL, IS NOT NULL, IS TRUE, etc. (in the code section linked). These all do not handle precedence properly / do not add parentheses when needed.
### To Reproduce
Run [this](https://github.com/apache/datafusion/blob/20bb7e6901e755d06ae18ec19ff2a0f05e088848/datafusion/substrait/tests/cases/consumer_integration.rs#L541) test and notice that it passes, because the displayed statement has no brackets around `a AND b` - it displays like this:
```
Projection: a, b, (a OR b) AND NOT a AND b AS result
Values: (Boolean(true), Boolean(true)), (Boolean(true), Boolean(false)), (Boolean(false), Boolean(true)), (Boolean(false), Boolean(false))
```
### Expected behavior
When applying a NOT operator to a binary expression, parentheses should be inserted around the entire expression to preserve correct logical grouping - `NOT (a AND b)` should not be displayed as `NOT a AND b`.
### Additional context
_No response_
Contributor guide
Assessment
This issue has not been assessed yet.