You are viewing a plain text version of this content. The canonical link for it is here.
Posted to github@datafusion.apache.org by "simonvandel (via GitHub)" <gi...@apache.org> on 2026/07/14 12:47:41 UTC

[PR] feat: eliminate LEFT JOINs whose right side is unused [datafusion]

simonvandel opened a new pull request, #23566:
URL: https://github.com/apache/datafusion/pull/23566

   ## Which issue does this PR close?
   
   <!--
   We generally require a GitHub issue to be filed for all bug fixes and enhancements and this helps us generate change logs for our releases. You can link an issue to this PR using the GitHub syntax. For example `Closes #123` indicates that this PR will close issue #123.
   -->
   
   - Closes #.
   
   ## Rationale for this change
   
   Join elimination is useful in e.g. generated queries or views, where joined columns can end up not being used.
   
   An explanation of when the optimization is valid, can be seen in the docs update for `EliminateJoin`.
   
   <!--
    Why are you proposing this change? If this is already explained clearly in the issue then this section is not needed.
    Explaining clearly why changes are proposed helps reviewers understand your changes and offer better suggestions for fixes.  
   -->
   
   ## What changes are included in this PR?
   
   Builds upon the analysis that https://github.com/apache/datafusion/pull/22652 introduced for the `EliminateJoin` optimization pass. We use it to detect when the right-side of a left-join can be removed.
   
   First commit adds test cases.
   Second commit adds the optimization change, and shows how it affects the added tests.
   
   <!--
   There is no need to duplicate the description in the issue here but it is sometimes worth providing a summary of the individual changes in this PR.
   -->
   
   ## Are these changes tested?
   
   Yes, SLT additions that test the feature end-to-end.
   
   <!--
   We typically require tests for all PRs in order to:
   1. Prevent the code from being accidentally broken by subsequent changes
   2. Serve as another way to document the expected behavior of the code
   
   If tests are not included in your PR, please explain why (for example, are they covered by existing tests)?
   -->
   
   ## Are there any user-facing changes?
   Yes, faster queries!
   <!--
   If there are user-facing changes then we may require documentation to be updated before approving the PR.
   -->
   
   <!--
   If there are any breaking changes to public APIs, please add the `api change` label.
   -->
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: github-unsubscribe@datafusion.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: github-unsubscribe@datafusion.apache.org
For additional commands, e-mail: github-help@datafusion.apache.org


Re: [PR] feat: eliminate LEFT JOINs whose right side is unused [datafusion]

Posted by "simonvandel (via GitHub)" <gi...@apache.org>.
simonvandel commented on code in PR #23566:
URL: https://github.com/apache/datafusion/pull/23566#discussion_r3647781648


##########
datafusion/sqllogictest/test_files/joins.slt:
##########
@@ -5608,3 +5608,316 @@ set datafusion.execution.target_partitions = 4;
 
 statement ok
 reset datafusion.execution.batch_size;
+
+##########
+# Eliminate unused LEFT JOINs (`EliminateJoin` rule)

Review Comment:
   Added some tests in https://github.com/apache/datafusion/pull/23566/commits/342134be61e91045e7534becc29c642e574d17d1



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: github-unsubscribe@datafusion.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: github-unsubscribe@datafusion.apache.org
For additional commands, e-mail: github-help@datafusion.apache.org


Re: [PR] feat: eliminate LEFT/RIGHT JOINs with redundant sides [datafusion]

Posted by "simonvandel (via GitHub)" <gi...@apache.org>.
simonvandel commented on PR #23566:
URL: https://github.com/apache/datafusion/pull/23566#issuecomment-5169523040

   @neilconway I have resolved the conflicts and decided to keep the tests as-is (coverage in SLT)


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: github-unsubscribe@datafusion.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: github-unsubscribe@datafusion.apache.org
For additional commands, e-mail: github-help@datafusion.apache.org


Re: [PR] feat: eliminate LEFT/RIGHT JOINs with redundant sides [datafusion]

Posted by "neilconway (via GitHub)" <gi...@apache.org>.
neilconway merged PR #23566:
URL: https://github.com/apache/datafusion/pull/23566


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: github-unsubscribe@datafusion.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: github-unsubscribe@datafusion.apache.org
For additional commands, e-mail: github-help@datafusion.apache.org


Re: [PR] feat: eliminate LEFT JOINs whose right side is unused [datafusion]

Posted by "simonvandel (via GitHub)" <gi...@apache.org>.
simonvandel commented on code in PR #23566:
URL: https://github.com/apache/datafusion/pull/23566#discussion_r3647777324


##########
datafusion/optimizer/src/eliminate_join.rs:
##########
@@ -394,6 +406,30 @@ fn rewrite_join(
 
     let (visible_left, visible_right) = split_join_output_columns(&join, live);
 
+    // A LEFT JOIN preserves every left row, so when nothing above the join
+    // references the right side's columns and the right side cannot multiply
+    // left rows (the ancestors are duplicate-insensitive, or the right side
+    // is unique on the join keys), the join has no observable effect and can
+    // be replaced by its left input. A join filter cannot prevent this: it
+    // only decides whether a left row is matched or null-padded, and either
+    // way the row is emitted.
+    if join.join_type == JoinType::Left
+        && visible_right.is_empty()
+        && (duplicate_insensitive
+            || side_unique_on_join(
+                join.right.schema(),
+                join.on.iter().map(|(_, right)| right),
+                join.null_equality,
+            ))

Review Comment:
   Good idea, I ended up doing a slight refactor instead of your suggestion: https://github.com/apache/datafusion/pull/23566/commits/87a7037cab9d5c274bb40ae9396f1c0dcc5fac0b
   
   so basically pushed the left-join elimination inside `rewritten_join_type`



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: github-unsubscribe@datafusion.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: github-unsubscribe@datafusion.apache.org
For additional commands, e-mail: github-help@datafusion.apache.org


Re: [PR] feat: eliminate LEFT/RIGHT JOINs with redundant sides [datafusion]

Posted by "neilconway (via GitHub)" <gi...@apache.org>.
neilconway commented on PR #23566:
URL: https://github.com/apache/datafusion/pull/23566#issuecomment-5147991332

   @simonvandel Sorry for the delay in responding here!
   
   > It's true that eliminate_join.rs has no unit tests added in this PR, so in that sense there is a gap. But I have added SLT tests for the optimization which show positive/negative cases. Do you still want unit tests as well, even if that means we now test the code redundantly?
   
   It's probably fine to skip, although the existing `EliminateJoin` codepaths have both unit and SLT tests, so there is precedent. I don't feel super strongly about it though.
   
   If you can you fix the merge conflict and make a call on if you'd like to add unit tests, and I think we're good to land this.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: github-unsubscribe@datafusion.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: github-unsubscribe@datafusion.apache.org
For additional commands, e-mail: github-help@datafusion.apache.org


Re: [PR] feat: eliminate LEFT JOINs whose right side is unused [datafusion]

Posted by "neilconway (via GitHub)" <gi...@apache.org>.
neilconway commented on code in PR #23566:
URL: https://github.com/apache/datafusion/pull/23566#discussion_r3596758392


##########
datafusion/optimizer/src/eliminate_join.rs:
##########
@@ -394,6 +406,30 @@ fn rewrite_join(
 
     let (visible_left, visible_right) = split_join_output_columns(&join, live);
 
+    // A LEFT JOIN preserves every left row, so when nothing above the join
+    // references the right side's columns and the right side cannot multiply
+    // left rows (the ancestors are duplicate-insensitive, or the right side
+    // is unique on the join keys), the join has no observable effect and can
+    // be replaced by its left input. A join filter cannot prevent this: it
+    // only decides whether a left row is matched or null-padded, and either
+    // way the row is emitted.
+    if join.join_type == JoinType::Left
+        && visible_right.is_empty()
+        && (duplicate_insensitive
+            || side_unique_on_join(
+                join.right.schema(),
+                join.on.iter().map(|(_, right)| right),
+                join.null_equality,
+            ))

Review Comment:
   Consider refactoring this into a helper, so we can use it here and also in `rewritten_join_type`?



##########
datafusion/optimizer/src/eliminate_join.rs:
##########
@@ -394,6 +406,30 @@ fn rewrite_join(
 
     let (visible_left, visible_right) = split_join_output_columns(&join, live);
 
+    // A LEFT JOIN preserves every left row, so when nothing above the join
+    // references the right side's columns and the right side cannot multiply
+    // left rows (the ancestors are duplicate-insensitive, or the right side
+    // is unique on the join keys), the join has no observable effect and can
+    // be replaced by its left input. A join filter cannot prevent this: it
+    // only decides whether a left row is matched or null-padded, and either
+    // way the row is emitted.
+    if join.join_type == JoinType::Left

Review Comment:
   What about supporting `RIGHT JOIN`s as well?



##########
datafusion/sqllogictest/test_files/joins.slt:
##########
@@ -5608,3 +5608,316 @@ set datafusion.execution.target_partitions = 4;
 
 statement ok
 reset datafusion.execution.batch_size;
+
+##########
+# Eliminate unused LEFT JOINs (`EliminateJoin` rule)

Review Comment:
   Can we add test cases for `LIMIT` and `LEFT JOIN LATERAL`?



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: github-unsubscribe@datafusion.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: github-unsubscribe@datafusion.apache.org
For additional commands, e-mail: github-help@datafusion.apache.org


Re: [PR] feat: eliminate LEFT JOINs whose right side is unused [datafusion]

Posted by "neilconway (via GitHub)" <gi...@apache.org>.
neilconway commented on code in PR #23566:
URL: https://github.com/apache/datafusion/pull/23566#discussion_r3603579321


##########
datafusion/optimizer/src/eliminate_join.rs:
##########
@@ -394,6 +406,30 @@ fn rewrite_join(
 
     let (visible_left, visible_right) = split_join_output_columns(&join, live);
 
+    // A LEFT JOIN preserves every left row, so when nothing above the join
+    // references the right side's columns and the right side cannot multiply
+    // left rows (the ancestors are duplicate-insensitive, or the right side
+    // is unique on the join keys), the join has no observable effect and can
+    // be replaced by its left input. A join filter cannot prevent this: it
+    // only decides whether a left row is matched or null-padded, and either
+    // way the row is emitted.
+    if join.join_type == JoinType::Left

Review Comment:
   I'm not sure there's a rush to land left-join support super fast 😊 But sure, if you'd prefer to split this into two PRs, that's fine with me.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: github-unsubscribe@datafusion.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: github-unsubscribe@datafusion.apache.org
For additional commands, e-mail: github-help@datafusion.apache.org


Re: [PR] feat: eliminate LEFT JOINs whose right side is unused [datafusion]

Posted by "simonvandel (via GitHub)" <gi...@apache.org>.
simonvandel commented on code in PR #23566:
URL: https://github.com/apache/datafusion/pull/23566#discussion_r3647780311


##########
datafusion/optimizer/src/eliminate_join.rs:
##########
@@ -394,6 +406,30 @@ fn rewrite_join(
 
     let (visible_left, visible_right) = split_join_output_columns(&join, live);
 
+    // A LEFT JOIN preserves every left row, so when nothing above the join
+    // references the right side's columns and the right side cannot multiply
+    // left rows (the ancestors are duplicate-insensitive, or the right side
+    // is unique on the join keys), the join has no observable effect and can
+    // be replaced by its left input. A join filter cannot prevent this: it
+    // only decides whether a left row is matched or null-padded, and either
+    // way the row is emitted.
+    if join.join_type == JoinType::Left

Review Comment:
   I have now implemented right-join support in https://github.com/apache/datafusion/pull/23566/commits/c88044402221d5649dc284a27185cc24f8039579



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: github-unsubscribe@datafusion.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: github-unsubscribe@datafusion.apache.org
For additional commands, e-mail: github-help@datafusion.apache.org


Re: [PR] feat: eliminate LEFT/RIGHT JOINs with redundant sides [datafusion]

Posted by "codecov-commenter (via GitHub)" <gi...@apache.org>.
codecov-commenter commented on PR #23566:
URL: https://github.com/apache/datafusion/pull/23566#issuecomment-5074022297

   ## [Codecov](https://app.codecov.io/gh/apache/datafusion/pull/23566?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) Report
   :x: Patch coverage is `95.55556%` with `2 lines` in your changes missing coverage. Please review.
   :white_check_mark: Project coverage is 80.71%. Comparing base ([`efa84e8`](https://app.codecov.io/gh/apache/datafusion/commit/efa84e8309ced6614e62d1607899c47ed0b6b08a?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache)) to head ([`342134b`](https://app.codecov.io/gh/apache/datafusion/commit/342134be61e91045e7534becc29c642e574d17d1?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache)).
   :warning: Report is 2 commits behind head on main.
   
   | [Files with missing lines](https://app.codecov.io/gh/apache/datafusion/pull/23566?dropdown=coverage&src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) | Patch % | Lines |
   |---|---|---|
   | [datafusion/optimizer/src/eliminate\_join.rs](https://app.codecov.io/gh/apache/datafusion/pull/23566?src=pr&el=tree&filepath=datafusion%2Foptimizer%2Fsrc%2Feliminate_join.rs&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache#diff-ZGF0YWZ1c2lvbi9vcHRpbWl6ZXIvc3JjL2VsaW1pbmF0ZV9qb2luLnJz) | 95.55% | [2 Missing :warning: ](https://app.codecov.io/gh/apache/datafusion/pull/23566?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) |
   
   <details><summary>Additional details and impacted files</summary>
   
   
   
   ```diff
   @@            Coverage Diff             @@
   ##             main   #23566      +/-   ##
   ==========================================
   - Coverage   80.71%   80.71%   -0.01%     
   ==========================================
     Files        1090     1090              
     Lines      370384   370395      +11     
     Branches   370384   370395      +11     
   ==========================================
   + Hits       298961   298965       +4     
   - Misses      53603    53604       +1     
   - Partials    17820    17826       +6     
   ```
   </details>
   
   [:umbrella: View full report in Codecov by Harness](https://app.codecov.io/gh/apache/datafusion/pull/23566?dropdown=coverage&src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache).   
   :loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache).
   <details><summary> :rocket: New features to boost your workflow: </summary>
   
   - :snowflake: [Test Analytics](https://docs.codecov.com/docs/test-analytics): Detect flaky tests, report on failures, and find test suite problems.
   - :package: [JS Bundle Analysis](https://docs.codecov.com/docs/javascript-bundle-analysis): Save yourself from yourself by tracking and limiting bundle sizes in JS merges.
   </details>


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: github-unsubscribe@datafusion.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: github-unsubscribe@datafusion.apache.org
For additional commands, e-mail: github-help@datafusion.apache.org


Re: [PR] feat: eliminate LEFT/RIGHT JOINs with redundant sides [datafusion]

Posted by "simonvandel (via GitHub)" <gi...@apache.org>.
simonvandel commented on PR #23566:
URL: https://github.com/apache/datafusion/pull/23566#issuecomment-5073845129

   Thank you for your review @neilconway. I have responded to your comments, and adjusted the PR description to not mention individual commits.
   
   > The existing analysis has both unit tests and SLTs; can you take a look at whether any of the existing unit tests should be extended to cover outer joins?
   
   It's true that eliminate_join.rs has no unit tests added in this PR, so in that sense there is a gap. But I have added SLT tests for the optimization which show positive/negative cases. Do you still want unit tests as well, even if that means we now test the code redundantly?


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: github-unsubscribe@datafusion.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: github-unsubscribe@datafusion.apache.org
For additional commands, e-mail: github-help@datafusion.apache.org


Re: [PR] feat: eliminate LEFT JOINs whose right side is unused [datafusion]

Posted by "simonvandel (via GitHub)" <gi...@apache.org>.
simonvandel commented on code in PR #23566:
URL: https://github.com/apache/datafusion/pull/23566#discussion_r3597299766


##########
datafusion/optimizer/src/eliminate_join.rs:
##########
@@ -394,6 +406,30 @@ fn rewrite_join(
 
     let (visible_left, visible_right) = split_join_output_columns(&join, live);
 
+    // A LEFT JOIN preserves every left row, so when nothing above the join
+    // references the right side's columns and the right side cannot multiply
+    // left rows (the ancestors are duplicate-insensitive, or the right side
+    // is unique on the join keys), the join has no observable effect and can
+    // be replaced by its left input. A join filter cannot prevent this: it
+    // only decides whether a left row is matched or null-padded, and either
+    // way the row is emitted.
+    if join.join_type == JoinType::Left

Review Comment:
   Sure, would you be okay with this being a follow-up task? Then we could land the left-join support faster



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: github-unsubscribe@datafusion.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: github-unsubscribe@datafusion.apache.org
For additional commands, e-mail: github-help@datafusion.apache.org