Commit cab75e0
authored
feat: warn on NULL equality predicates (#22948)
## Which issue does this PR close?
- Closes #14434.
## Rationale for this change
SQL comparisons such as `expr = NULL` and `expr <> NULL` evaluate to
`NULL` under SQL three-valued logic, not to `true` or `false`. When
those comparisons appear in predicate contexts such as `WHERE`, `JOIN
ON`, or `HAVING`, they are almost always a user mistake where `IS NULL`
or `IS NOT NULL` was intended.
This PR emits non-fatal diagnostic warnings for those cases so callers
that surface `Diagnostic` information can help users find and fix the
query without changing planning success or query semantics.
## What changes are included in this PR?
- Adds warning collection to `SqlToRel`, with
`SqlToRel::take_warnings()` to drain non-fatal planning diagnostics
after planning.
- Adds predicate-scoped detection for `= NULL` and `<> NULL`
comparisons.
- Wires detection into `WHERE`, `JOIN ON`, and `HAVING` planning paths.
- Recursively checks predicate expression structure such as nested `AND`
/ `OR` binary predicates and `CASE WHEN` conditions, without warning for
projection-only expressions like `SELECT col = NULL`.
- Creates `Diagnostic::new_warning` entries with a primary span on the
comparison expression and help pointing at the `NULL` literal when spans
are available.
## Are these changes tested?
Yes. Added regression coverage in
`datafusion/sql/tests/cases/diagnostic.rs` for:
- `WHERE col = NULL`
- `WHERE NULL = col`
- `WHERE col <> NULL`
- `JOIN ... ON col = NULL`
- `HAVING ... = NULL`
- nested `CASE WHEN col = NULL` inside a predicate
- no warning for `IS NULL`
- no warning for projection-only `SELECT col = NULL`
- multiple warnings in one predicate
Validation run locally:
```shell
cargo fmt --all
cargo test -p datafusion-sql --test sql_integration diagnostic
cargo test -p datafusion-sql
cargo clippy -p datafusion-sql --all-targets --all-features -- -D warnings
cargo clippy --all-targets --all-features -- -D warnings
git diff main..HEAD --check
```
## Are there any user-facing changes?
Yes, but non-breaking. SQL planning can now collect warning diagnostics
for likely mistaken `NULL` equality predicates. Consumers can retrieve
them with `SqlToRel::take_warnings()` and decide how to present them.
Planning still succeeds and query semantics are unchanged.1 parent 933297b commit cab75e0
5 files changed
Lines changed: 342 additions & 7 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
15 | 15 | | |
16 | 16 | | |
17 | 17 | | |
| 18 | + | |
| 19 | + | |
18 | 20 | | |
19 | 21 | | |
20 | 22 | | |
21 | 23 | | |
22 | 24 | | |
23 | 25 | | |
24 | 26 | | |
25 | | - | |
26 | | - | |
| 27 | + | |
| 28 | + | |
27 | 29 | | |
| 30 | + | |
28 | 31 | | |
29 | 32 | | |
30 | | - | |
31 | | - | |
| 33 | + | |
| 34 | + | |
32 | 35 | | |
33 | 36 | | |
34 | 37 | | |
| |||
54 | 57 | | |
55 | 58 | | |
56 | 59 | | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
57 | 134 | | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
58 | 140 | | |
59 | 141 | | |
60 | 142 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
18 | 18 | | |
19 | 19 | | |
20 | 20 | | |
21 | | - | |
| 21 | + | |
22 | 22 | | |
23 | 23 | | |
24 | 24 | | |
| |||
455 | 455 | | |
456 | 456 | | |
457 | 457 | | |
| 458 | + | |
458 | 459 | | |
459 | 460 | | |
460 | 461 | | |
| |||
477 | 478 | | |
478 | 479 | | |
479 | 480 | | |
| 481 | + | |
480 | 482 | | |
481 | 483 | | |
482 | 484 | | |
| 485 | + | |
| 486 | + | |
| 487 | + | |
| 488 | + | |
| 489 | + | |
| 490 | + | |
| 491 | + | |
| 492 | + | |
| 493 | + | |
| 494 | + | |
| 495 | + | |
| 496 | + | |
| 497 | + | |
| 498 | + | |
| 499 | + | |
| 500 | + | |
| 501 | + | |
483 | 502 | | |
484 | 503 | | |
485 | 504 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
122 | 122 | | |
123 | 123 | | |
124 | 124 | | |
| 125 | + | |
125 | 126 | | |
126 | 127 | | |
127 | 128 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
198 | 198 | | |
199 | 199 | | |
200 | 200 | | |
| 201 | + | |
201 | 202 | | |
202 | 203 | | |
203 | 204 | | |
| |||
865 | 866 | | |
866 | 867 | | |
867 | 868 | | |
| 869 | + | |
868 | 870 | | |
869 | 871 | | |
870 | 872 | | |
| |||
0 commit comments