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


##########
fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/ExpressionAnalyzer.java:
##########
@@ -306,14 +306,39 @@ 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();
+        AnalysisException thisScopeBindException = null;
+        List<? extends Expression> bounded;
+        int thisScopeExactPrefixLength = 0;
+        try {
+            bounded = bindSlotByThisScope(unboundSlot);
+            if (!bounded.isEmpty()) {
+                thisScopeExactPrefixLength = 
getExactSlotPrefixLength(unboundSlot, getScope());
+            }
+        } catch (AnalysisException e) {
+            if (bindSlotInOuterScope && outerScope.isPresent() && 
unboundSlot.getNameParts().size() > 1) {
+                bounded = ImmutableList.of();
+                thisScopeBindException = e;
+            } else {
+                throw e;
+            }
+        }
+        boolean foundInThisScope = !bounded.isEmpty();
         // Currently only looking for symbols on the previous level.
-        if (bindSlotInOuterScope && !foundInThisScope && 
outerScope.isPresent()) {
-            boundedOpt = Optional.of(bindSlotByScope(unboundSlot, 
outerScope.get()));
+        if (bindSlotInOuterScope && outerScope.isPresent()) {
+            if (!foundInThisScope) {
+                bounded = bindSlotByScope(unboundSlot, outerScope.get());
+            } else if (unboundSlot.getNameParts().size() > 1
+                    && getExactSlotPrefixLength(unboundSlot, outerScope.get()) 
> thisScopeExactPrefixLength) {
+                // Current-scope nested-field fallback should not shadow a 
correlated table alias,

Review Comment:
   This condition decides to prefer the outer scope from prefix length alone, 
before verifying that the outer scope can bind the full multipart reference. 
That can reject a valid current-scope nested-field reference. For example, if 
the outer query has table alias `s` with column `v INT`, and the subquery has a 
local column `s STRUCT<v:STRUCT<x:INT>>`, then `s.v.x` first binds successfully 
in the current scope with prefix length 1. The outer prefix probe returns 2 for 
`s.v`, so this branch calls `bindSlotByScope` on the outer scope, which then 
throws `No such field 'x' in 'v'` even though the local `s.v.x` binding is 
valid and should shadow the unusable outer candidate. Please only replace the 
current binding after the full outer bind succeeds, or catch the outer 
nested-field failure and keep the current-scope result when it was already 
bound. Add a regression case for this shadowing direction as well.



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