Skip to content

Commit 4b51bbe

Browse files
authored
Don't optimize null_equals_null case (#12404)
1 parent 23f3a8f commit 4b51bbe

File tree

2 files changed

+12
-15
lines changed

2 files changed

+12
-15
lines changed

datafusion/optimizer/src/filter_null_join_keys.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ use datafusion_expr::utils::conjunction;
2626
use datafusion_expr::{logical_plan::Filter, Expr, ExprSchemable, LogicalPlan};
2727
use std::sync::Arc;
2828

29-
/// The FilterNullJoinKeys rule will identify joins with equi-join conditions
29+
/// The FilterNullJoinKeys rule will identify joins with equi-join conditions
3030
/// where the join key is nullable and then insert an `IsNotNull` filter on the nullable side since null values
3131
/// can never match.
3232
#[derive(Default)]
@@ -50,7 +50,9 @@ impl OptimizerRule for FilterNullJoinKeys {
5050
return Ok(Transformed::no(plan));
5151
}
5252
match plan {
53-
LogicalPlan::Join(mut join) if !join.on.is_empty() => {
53+
LogicalPlan::Join(mut join)
54+
if !join.on.is_empty() && !join.null_equals_null =>
55+
{
5456
let (left_preserved, right_preserved) =
5557
on_lr_is_preserved(join.join_type);
5658

datafusion/optimizer/tests/optimizer_integration.rs

+8-13
Original file line numberDiff line numberDiff line change
@@ -177,15 +177,12 @@ fn intersect() -> Result<()> {
177177
let plan = test_sql(sql)?;
178178
let expected =
179179
"LeftSemi Join: test.col_int32 = test.col_int32, test.col_utf8 = test.col_utf8\
180-
\n Aggregate: groupBy=[[test.col_int32, test.col_utf8]], aggr=[[]]\
181-
\n LeftSemi Join: test.col_int32 = test.col_int32, test.col_utf8 = test.col_utf8\
182-
\n Aggregate: groupBy=[[test.col_int32, test.col_utf8]], aggr=[[]]\
183-
\n Filter: test.col_int32 IS NOT NULL AND test.col_utf8 IS NOT NULL\
184-
\n TableScan: test projection=[col_int32, col_utf8]\
185-
\n Filter: test.col_int32 IS NOT NULL AND test.col_utf8 IS NOT NULL\
186-
\n TableScan: test projection=[col_int32, col_utf8]\
187-
\n Filter: test.col_int32 IS NOT NULL AND test.col_utf8 IS NOT NULL\
188-
\n TableScan: test projection=[col_int32, col_utf8]";
180+
\n Aggregate: groupBy=[[test.col_int32, test.col_utf8]], aggr=[[]]\
181+
\n LeftSemi Join: test.col_int32 = test.col_int32, test.col_utf8 = test.col_utf8\
182+
\n Aggregate: groupBy=[[test.col_int32, test.col_utf8]], aggr=[[]]\
183+
\n TableScan: test projection=[col_int32, col_utf8]\
184+
\n TableScan: test projection=[col_int32, col_utf8]\
185+
\n TableScan: test projection=[col_int32, col_utf8]";
189186
assert_eq!(expected, format!("{plan}"));
190187
Ok(())
191188
}
@@ -281,11 +278,9 @@ fn test_same_name_but_not_ambiguous() {
281278
let expected = "LeftSemi Join: t1.col_int32 = t2.col_int32\
282279
\n Aggregate: groupBy=[[t1.col_int32]], aggr=[[]]\
283280
\n SubqueryAlias: t1\
284-
\n Filter: test.col_int32 IS NOT NULL\
285-
\n TableScan: test projection=[col_int32]\
281+
\n TableScan: test projection=[col_int32]\
286282
\n SubqueryAlias: t2\
287-
\n Filter: test.col_int32 IS NOT NULL\
288-
\n TableScan: test projection=[col_int32]";
283+
\n TableScan: test projection=[col_int32]";
289284
assert_eq!(expected, format!("{plan}"));
290285
}
291286

0 commit comments

Comments
 (0)