Skip to content

Eliminate outer joins with empty relations via null-padded projection#21321

Open
SubhamSinghal wants to merge 4 commits intoapache:mainfrom
SubhamSinghal:propagate-empty-outer-join-null-pad
Open

Eliminate outer joins with empty relations via null-padded projection#21321
SubhamSinghal wants to merge 4 commits intoapache:mainfrom
SubhamSinghal:propagate-empty-outer-join-null-pad

Conversation

@SubhamSinghal
Copy link
Copy Markdown
Contributor

Which issue does this PR close?

Rationale for this change

When one side of a LEFT/RIGHT/FULL outer join is an EmptyRelation, the current PropagateEmptyRelation optimizer rule leaves the join untouched. This means the engine still builds a hash table for the empty side, probes every row from the non-empty side, finds zero matches, and pads NULLs — all wasted work.

The TODO at lines 76-80 of propagate_empty_relation.rs explicitly called out this gap:

// TODO: For LeftOut/Full Join, if the right side is empty, the Join can be eliminated
// with a Projection with left side columns + right side columns replaced with null values.
// For RightOut/Full Join, if the left side is empty, the Join can be eliminated
// with a Projection with right side columns + left side columns replaced with null values.

What changes are included in this PR?

Extends the PropagateEmptyRelation rule to handle 4 previously unoptimized cases by replacing the join with a Projection that null-pads the empty side's columns:

Are these changes tested?

Yes. 4 new unit tests added:

Are there any user-facing changes?

No API changes.

@github-actions github-actions bot added optimizer Optimizer rules sqllogictest SQL Logic Tests (.slt) labels Apr 2, 2026
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.

PropagateEmptyRelation does not eliminate outer joins when one side is empty

2 participants