Skip to content

fix: inferred predicates for null-aware anti joins#23411

Open
847850277 wants to merge 2 commits into
apache:mainfrom
847850277:issues_23410
Open

fix: inferred predicates for null-aware anti joins#23411
847850277 wants to merge 2 commits into
apache:mainfrom
847850277:issues_23410

Conversation

@847850277

Copy link
Copy Markdown

Which issue does this PR close?

Rationale for this change

NOT IN must preserve SQL NULL semantics. If the subquery result contains NULL, then comparisons like a NOT IN (SELECT k FROM u) can evaluate to UNKNOWN, and rows should not be returned by WHERE.

DataFusion rewrites NOT IN into a null-aware anti join. However, predicate pushdown inferred a predicate across that join and could filter out right-side NULL values, changing the query result incorrectly.

What changes are included in this PR?

This PR avoids inferring predicates across null-aware left anti joins.

It also adds a sqllogictest regression case covering NOT IN with a right-side NULL and an additional left-side filter.

Are these changes tested?

Yes.

cargo fmt --all
git diff --check
cargo test --profile=ci --test sqllogictests -- not_in_null_pushdown.slt
cargo clippy --all-targets --all-features -- -D warnings

Are there any user-facing changes?

Copilot AI review requested due to automatic review settings July 9, 2026 08:16
@github-actions github-actions Bot added optimizer Optimizer rules sqllogictest SQL Logic Tests (.slt) labels Jul 9, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes incorrect SQL NOT IN semantics when the subquery can produce NULL by preventing inferred predicate pushdown across null-aware left anti joins (which could otherwise filter out right-side NULLs and change results).

Changes:

  • Disable join predicate inference for JoinType::LeftAnti joins marked null_aware.
  • Add a sqllogictest regression covering NOT IN with a right-side NULL plus an additional left-side filter.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
datafusion/optimizer/src/push_down_filter.rs Skips inferred predicate generation for null-aware left anti joins to preserve NOT IN null semantics.
datafusion/sqllogictest/test_files/not_in_null_pushdown.slt Adds regression test ensuring right-side NULL is not removed by inferred predicate pushdown.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +592 to +596
// Null-aware anti joins implement NOT IN semantics, where NULLs on the
// right side affect the result. Inferring predicates across the join can
// incorrectly filter those NULLs.
if join_type == JoinType::LeftAnti && join.null_aware {
return Ok(vec![]);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

optimizer Optimizer rules sqllogictest SQL Logic Tests (.slt)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Incorrect NOT IN result due to inferred predicate pushdown over null-aware anti join

2 participants