github-actions[bot] commented on code in PR #67438:
URL: https://github.com/apache/doris/pull/67438#discussion_r3913311254


##########
fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/ExpressionAnalyzer.java:
##########
@@ -309,14 +310,31 @@ public Expression visitElementAt(ElementAt elementAt, 
ExpressionRewriteContext c
     @Override
     public Expression visitUnboundSlot(UnboundSlot unboundSlot, 
ExpressionRewriteContext context) {
         Optional<Scope> outerScope = getScope().getOuterScope();
-        Optional<List<? extends Expression>> boundedOpt = 
Optional.of(bindSlotByThisScope(unboundSlot));
-        boolean foundInThisScope = !boundedOpt.get().isEmpty();
+        List<? extends Expression> bounded = ImmutableList.of();
+        boolean foundInThisScope = false;
+        boolean canBindOuterScope = bindSlotInOuterScope && 
outerScope.isPresent();
+
+        // A multipart name can be either a relation-qualified column (t.col) 
or a nested field
+        // reference (col.field). In a correlated subquery, try the 
relation-qualified interpretation
+        // in both visible scopes first, so an inner column named "t" does not 
hide an outer alias "t".
+        if (canBindOuterScope && shouldPrioritizeRelationQualifier()
+                && unboundSlot.getNameParts().size() > 1) {
+            bounded = bindSlotByRelationQualifierInThisScope(unboundSlot);
+            foundInThisScope = !bounded.isEmpty();
+            if (!foundInThisScope) {
+                bounded = bindSlotByRelationQualifier(unboundSlot, 
outerScope.get());

Review Comment:
   **[P1] Preserve the nearer scope before probing the outer alias**
   
   Reduced binding shape:
   
   ```text
   Filter[EXISTS]
     Scan outer_table AS t(value)
     Subquery:
       Filter[t.value = 1]
         Scan inner_table AS t(t STRUCT<value:INT>)
   ```
   
   The local relation-only lookup searches for column `value` and returns empty 
even though qualifier `t` is occupied. This line then binds outer `t.value`, 
skips the complete local binder, and produces 
`LogicalApply(correlation=[outer.value])`; on the base path the local physical 
column `t` was dereferenced instead, so rows can change. Please distinguish "no 
local qualifier" from "local qualifier present but column absent," and only 
search outward in the former case. Add an ordinary-filter test for this 
alias/column collision; the HAVING/QUALIFY cases cover only `t.id`, which 
exists locally.



##########
regression-test/suites/query_p0/test_dereference.groovy:
##########
@@ -66,4 +66,116 @@ suite("test_dereference") {
         sql "select s.a from test_dereference2"
         exception "No such struct field 'a' in 's'"
     }
-}
\ No newline at end of file
+
+    multi_sql """
+        drop table if exists test_correlated_dereference_outer;
+        drop table if exists test_correlated_dereference_inner_scalar;
+        drop table if exists test_correlated_dereference_inner_struct;
+        create table test_correlated_dereference_outer(
+          id int,
+          value int,
+          `@event_name` varchar(32),
+          payload struct<k:int>,
+          items array<struct<value:int>>
+        )
+        distributed by hash(id)
+        properties('replication_num'='1');
+
+        create table test_correlated_dereference_inner_scalar(
+          id int,
+          t1 int
+        )
+        distributed by hash(id)
+        properties('replication_num'='1');
+
+        create table test_correlated_dereference_inner_struct(
+          id int,
+          outer_alias struct<value:int>
+        )
+        distributed by hash(id)
+        properties('replication_num'='1');
+
+        insert into test_correlated_dereference_outer values
+            (1, 10, 'blocked', struct(1), array(struct(1), struct(2))),
+            (2, 20, 'kept', struct(2), array(struct(3)));
+        insert into test_correlated_dereference_inner_scalar values (1, 0);
+        insert into test_correlated_dereference_inner_struct values (1, 
struct(10));
+        """
+
+    test {
+        sql """
+            select t1.id, t1.`@event_name`
+            from test_correlated_dereference_outer t1
+            where not exists (
+                select 1 from test_correlated_dereference_inner_scalar 
inner_alias
+                where t1.`@event_name` = 'blocked'
+            )
+            order by t1.id
+            """

Review Comment:
   **[P2] Generate snapshots for these deterministic results**
   
   This and the other five new success cases use `result(...)`, which the 
framework checks with `Assert.assertEquals`. The current regression-test rules 
require determined results to use named `qt`/`order_qt` cases and generated 
`.out` output. Please convert the six success cases and generate the snapshot; 
keep inline `test { ... }` for cases that need explicit exception/control 
behavior.



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