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


##########
datafusion/sqllogictest/test_files/subquery.slt:
##########
@@ -4077,6 +4077,29 @@ DROP TABLE nested_agg_outer;
 statement ok
 DROP TABLE nested_agg_inner;
 
+# A set comparison in a projection without an alias must not change the 
projection's
+# output field name. `RewriteSetComparison` replaces `x > ALL (…)` with a 
`CASE` whose
+# display name differs from the field name, and rebuilding the projection from 
the
+# expression names failed the optimizer's "schema is invariant" check with an 
internal
+# error instead of returning the answer.
+query B
+select 2 > all (select v from (values (1), (0)) t(v));
+----
+true
+
+query BI
+select 2 > all (select v from (values (1), (0)) t(v)), 9 as k;

Review Comment:
   Optional: could you add a case with a qualified column next to the set 
comparison? It fails on `main` with the same internal error and passes here:
   
   ```sql
   statement ok
   create table t_qual(k int) as values (1), (2);
   
   query IB
   select t_qual.k, t_qual.k > all (select v from (values (1), (0)) s(v)) from 
t_qual order by t_qual.k;
   ----
   1 false
   2 true
   
   statement ok
   drop table t_qual;
   ```



##########
datafusion/optimizer/src/decorrelate_predicate_subquery.rs:
##########
@@ -78,10 +78,21 @@ impl OptimizerRule for DecorrelatePredicateSubquery {
             }
 
             let original_projection = projection.clone();
+            // The projection's own schema is the authority for its output 
field names.
+            // Earlier rules rewrite expressions with `map_expressions`, which 
keeps the
+            // schema but can leave an expression whose display name no longer 
matches its
+            // field name (`RewriteSetComparison` turns `x > ALL (…)` into a 
`CASE` and does

Review Comment:
   Since `RewriteSetComparison` is what leaves the stale name, could you fix it 
there with `NamePreserver`, the same way `simplify_exprs` and `type_coercion` 
wrap `map_expressions`? With this, the change to this file isn't needed: on 
`main`'s version of this file plus the diff below, your new slt cases, 
`subquery*.slt`, `merge_into.slt`, `null_aware_mark_join.slt` and the optimizer 
unit tests all pass. It also stops this rule leaving mismatched names in 
Aggregate/Window nodes.
   
   ```diff
   +use datafusion_expr::expr_rewriter::NamePreserver;
    ...
   +        let name_preserver = NamePreserver::new(&plan);
            plan.map_expressions(|expr| {
   +            let original_name = name_preserver.save(&expr);
                expr.transform_up(|expr| rewrite_set_comparison(expr, &schema))
   +                .map(|t| t.update_data(|expr| original_name.restore(expr)))
            })
   ```



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