Commit 82f1b36
authored
fix: NOT IN with NULL subquery returns wrong results under SortMergeJoin (#22810)
## Problem
`NOT IN (subquery)` is a null-aware anti join: when the subquery yields
a NULL the predicate is never TRUE, so the query must return zero rows.
With `prefer_hash_join = false` and multiple partitions, the planner
routed the null-aware anti join to `SortMergeJoinExec`, which is not
null-aware, so it returned wrong results. HashJoin (the default) was
already correct.
## Proof
```sql
set datafusion.optimizer.prefer_hash_join = false;
create table t1(x int) as values (1);
create table t2(y int) as values (NULL);
select x from t1 where x not in (select y from t2);
```
Expected 0 rows (the subquery contains a NULL). Before this change it
returned `1`. With `prefer_hash_join = true` it correctly returned 0
rows. `EXPLAIN` showed the wrong config selecting `SortMergeJoinExec:
join_type=LeftAnti`.
## Solution
The planner already requires null-aware joins to use the CollectLeft
HashJoin, and the HashJoin branch guards on `!null_aware`. The
SortMergeJoin branch was missing the same guard, so this adds `&&
!*null_aware` to it. Null-aware anti joins now fall through to the
CollectLeft HashJoin regardless of `prefer_hash_join`.
`SortMergeJoinExec` has no `null_aware` parameter and cannot honor these
semantics.
Added a regression test in `subquery.slt` (under `prefer_hash_join =
false`) covering both a null-containing subquery (zero rows) and a
null-free subquery (normal anti join). All 61 SortMergeJoin unit tests
pass.1 parent b8d3b0b commit 82f1b36
2 files changed
Lines changed: 63 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1803 | 1803 | | |
1804 | 1804 | | |
1805 | 1805 | | |
| 1806 | + | |
| 1807 | + | |
| 1808 | + | |
| 1809 | + | |
| 1810 | + | |
1806 | 1811 | | |
1807 | 1812 | | |
1808 | 1813 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2599 | 2599 | | |
2600 | 2600 | | |
2601 | 2601 | | |
| 2602 | + | |
| 2603 | + | |
| 2604 | + | |
| 2605 | + | |
| 2606 | + | |
| 2607 | + | |
| 2608 | + | |
| 2609 | + | |
| 2610 | + | |
| 2611 | + | |
| 2612 | + | |
| 2613 | + | |
| 2614 | + | |
| 2615 | + | |
| 2616 | + | |
| 2617 | + | |
| 2618 | + | |
| 2619 | + | |
| 2620 | + | |
| 2621 | + | |
| 2622 | + | |
| 2623 | + | |
| 2624 | + | |
| 2625 | + | |
| 2626 | + | |
| 2627 | + | |
| 2628 | + | |
| 2629 | + | |
| 2630 | + | |
| 2631 | + | |
| 2632 | + | |
| 2633 | + | |
| 2634 | + | |
| 2635 | + | |
| 2636 | + | |
| 2637 | + | |
| 2638 | + | |
| 2639 | + | |
| 2640 | + | |
| 2641 | + | |
| 2642 | + | |
| 2643 | + | |
| 2644 | + | |
| 2645 | + | |
| 2646 | + | |
| 2647 | + | |
| 2648 | + | |
| 2649 | + | |
| 2650 | + | |
| 2651 | + | |
| 2652 | + | |
| 2653 | + | |
| 2654 | + | |
| 2655 | + | |
| 2656 | + | |
| 2657 | + | |
| 2658 | + | |
| 2659 | + | |
0 commit comments