kosiew commented on code in PR #17518:
URL: https://github.com/apache/datafusion/pull/17518#discussion_r2358531411


##########
datafusion/common/src/join_type.rs:
##########
@@ -111,6 +117,64 @@ impl JoinType {
                 | JoinType::RightAnti
         )
     }
+
+    /// Returns true if this join type preserves all rows from the specified 
`side`.
+    pub fn preserves(self, side: JoinSide) -> bool {
+        match side {
+            JoinSide::Left => LEFT_PRESERVING.contains(&self),
+            JoinSide::Right => RIGHT_PRESERVING.contains(&self),
+            JoinSide::None => false,
+        }
+    }
+
+    /// Returns true if this join type preserves all rows from its left input.
+    ///
+    /// For [`JoinType::Left`], [`JoinType::Full`], and [`JoinType::LeftMark`] 
joins
+    /// every row from the left side will appear in the output at least once.
+    pub fn preserves_left(self) -> bool {
+        self.preserves(JoinSide::Left)
+    }
+
+    /// Returns true if this join type preserves all rows from its right input.
+    ///
+    /// For [`JoinType::Right`], [`JoinType::Full`], and 
[`JoinType::RightMark`] joins
+    /// every row from the right side will appear in the output at least once.
+    pub fn preserves_right(self) -> bool {
+        self.preserves(JoinSide::Right)
+    }
+
+    /// Returns the input side eligible for dynamic filter pushdown.
+    ///
+    /// The side returned here can have a `DynamicFilterPhysicalExpr` pushed
+    /// into it, allowing values read from the opposite input to prune rows
+    /// before the join executes. When both inputs must be preserved,
+    /// dynamic filter pushdown is not supported and [`JoinSide::None`] is
+    /// returned.
+    ///
+    /// If neither input is preserving (for example with [`JoinType::Inner`],
+    /// [`JoinType::LeftSemi`], [`JoinType::RightSemi`],
+    /// [`JoinType::LeftAnti`], or [`JoinType::RightAnti`]), either side could
+    /// in principle receive the pushed filter. DataFusion selects the probe
+    /// side: for [`JoinType::LeftSemi`] and [`JoinType::LeftAnti`] this is the
+    /// left input, for [`JoinType::RightSemi`] and [`JoinType::RightAnti`] it
+    /// is the right input, and for other joins the right input is used by
+    /// default as joins typically treat the right as the probe side.
+    pub fn dynamic_filter_side(self) -> JoinSide {

Review Comment:
   The helper is really just reusing the existing preserves_left/right 
semantics to figure out which side can legally accept a pushed predicate, so it 
doesn’t need to live on JoinType as a dynamic-filter–specific API. I’ll move 
that logic back into the dynamic-filter optimizer (or, alternatively, expose a 
more neutrally named helper that just reports the non-preserving side) and let 
the rule decide what to do with it there



-- 
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: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to