You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@datafusion.apache.org by gi...@apache.org on 2026/06/25 01:57:41 UTC

(datafusion) branch gh-readonly-queue/main/pr-23078-afdc003af99b4e2ab31942d4cd4340a173661e99 created (now a00f7499e1)

This is an automated email from the ASF dual-hosted git repository.

github-merge-queue[bot] pushed a change to branch gh-readonly-queue/main/pr-23078-afdc003af99b4e2ab31942d4cd4340a173661e99
in repository https://gitbox.apache.org/repos/asf/datafusion.git


      at a00f7499e1 fix: add assert to `HashJoinExec::swap_inputs` (#23078)

This branch includes the following new commits:

     new a00f7499e1 fix: add assert to `HashJoinExec::swap_inputs` (#23078)

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



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


(datafusion) 01/01: fix: add assert to `HashJoinExec::swap_inputs` (#23078)

Posted by gi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

github-merge-queue[bot] pushed a commit to branch gh-readonly-queue/main/pr-23078-afdc003af99b4e2ab31942d4cd4340a173661e99
in repository https://gitbox.apache.org/repos/asf/datafusion.git

commit a00f7499e139c29e13b8b94baba262435bef417b
Author: Huaijin <ha...@gmail.com>
AuthorDate: Thu Jun 25 09:57:20 2026 +0800

    fix: add assert to `HashJoinExec::swap_inputs` (#23078)
    
    ## 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 #23077
    
    ## Rationale for this change
    
    Dynamic filters are runtime state tied to the probe side. `swap_inputs`
    changes the probe side, so preserving the old filter is unsafe and can
    lead to wrong column references.
    
    
    ## What changes are included in this PR?
    
    
    remove the `dynamic_filter` while swap inputs in `HashJoinExec`:
    
    ```rust
    .with_dynamic_filter(None)
    ```
    
    ## Are these changes tested?
    
    yes, add one test case
    
    ## Are there any user-facing changes?
    
    no
---
 .../physical-plan/src/joins/hash_join/exec.rs      | 45 ++++++++++++++++++++++
 1 file changed, 45 insertions(+)

diff --git a/datafusion/physical-plan/src/joins/hash_join/exec.rs b/datafusion/physical-plan/src/joins/hash_join/exec.rs
index b1d387ea74..a5da391ee7 100644
--- a/datafusion/physical-plan/src/joins/hash_join/exec.rs
+++ b/datafusion/physical-plan/src/joins/hash_join/exec.rs
@@ -1092,6 +1092,12 @@ impl HashJoinExec {
         &self,
         partition_mode: PartitionMode,
     ) -> Result<Arc<dyn ExecutionPlan>> {
+        assert_or_internal_err!(
+            self.dynamic_filter.is_none(),
+            "Cannot swap HashJoinExec inputs after dynamic filters have been constructed. \
+             Optimizer rules that reorder join inputs must run before optimizer rules `FilterPushdown::new_post_optimization()`"
+        );
+
         let left = self.left();
         let right = self.right();
         let new_join = self
@@ -6627,6 +6633,45 @@ mod tests {
         Ok(())
     }
 
+    #[test]
+    fn test_swap_inputs_rejects_dynamic_filter() -> Result<()> {
+        let left = build_table(
+            ("l_key", &vec![1]),
+            ("l_payload", &vec![10]),
+            ("l_other", &vec![100]),
+        );
+        let right = build_table(
+            ("r_payload", &vec![20]),
+            ("r_key", &vec![1]),
+            ("r_other", &vec![200]),
+        );
+        let on = vec![(
+            Arc::new(Column::new_with_schema("l_key", &left.schema())?) as _,
+            Arc::new(Column::new_with_schema("r_key", &right.schema())?) as _,
+        )];
+
+        let dynamic_filter = HashJoinExec::create_dynamic_filter(&on);
+        let join = HashJoinExec::try_new(
+            left,
+            right,
+            on,
+            None,
+            &JoinType::LeftSemi,
+            None,
+            PartitionMode::CollectLeft,
+            NullEquality::NullEqualsNothing,
+            false,
+        )?
+        .with_dynamic_filter_expr(dynamic_filter)?;
+
+        let err = join.swap_inputs(PartitionMode::CollectLeft).unwrap_err();
+        assert_contains!(
+            err.to_string(),
+            "Cannot swap HashJoinExec inputs after dynamic filters have been constructed"
+        );
+        Ok(())
+    }
+
     #[test]
     fn test_dynamic_filter_pushdown_rejects_null_equal_join() -> Result<()> {
         let (_, _, on) = build_schema_and_on()?;


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