jayzhan211 commented on code in PR #25273:
URL: https://github.com/apache/datafusion/pull/25273#discussion_r4358256659


##########
datafusion/optimizer/src/decorrelate.rs:
##########
@@ -968,6 +968,60 @@ fn collect_local_correlated_cols(
     }
 }
 
+/// Extracts correlated predicates, such as a comparison between a column from 
the
+/// subquery and a column from the outer scope.
+///
+/// Preserves [`Expr::OuterReferenceColumn`] markers so callers can distinguish
+/// inner and outer columns when qualifying join filters (see 
[`build_join_filter`]).
+///
+/// # Arguments
+///
+/// * `exprs` - Subquery filter predicates to classify.
+///
+/// # Return value
+///
+/// Tuple of (correlated join filters, remaining subquery filters). Correlated
+/// self-equalities are discarded from both lists.
+pub(crate) fn find_join_exprs(exprs: Vec<&Expr>) -> (Vec<Expr>, Vec<Expr>) {
+    let mut joins = vec![];
+    let mut others = vec![];
+    for filter in exprs {
+        // Predicates containing outer references become join filters.
+        if filter.contains_outer() {
+            // Check equality before stripping markers: inner and outer columns

Review Comment:
   nit: this function doesn't remove the markers any more, so "before stripping 
markers" reads a little oddly here. Maybe: "Compare with the outer-reference 
markers intact: inner and outer columns with the same qualified name belong to 
different scopes."
   



##########
datafusion/optimizer/src/decorrelate.rs:
##########
@@ -984,6 +1038,7 @@ fn remove_duplicated_filter(
 
     Ok(filters
         .into_iter()
+        .map(strip_outer_reference)

Review Comment:
   nit: this removes the outer-reference markers from the filters that are 
kept, not only for the comparison. So on the `IN` path they're gone again 
before `build_join_filter` gets to rename to the alias, which is the same issue 
this PR fixes. SQL can't hit it because inner columns shadow outer ones, but a 
hand-built plan can. Removing the markers from a copy keeps them intact, and 
the optimizer tests and `subquery*.slt` still pass with this:
   
   ```diff
        Ok(filters
            .into_iter()
   -        .map(strip_outer_reference)
            .filter(|filter| {
   +            let filter = &strip_outer_reference(filter.clone());
                if filter == in_predicate {
   ```
   



-- 
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