This is an automated email from the ASF dual-hosted git repository.

duanzhengqiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shardingsphere.git


The following commit(s) were added to refs/heads/master by this push:
     new 4c718634ec0 Fix same alias subquery bind (#28409)
4c718634ec0 is described below

commit 4c718634ec0aafdf35b41080a7431f33150670ee
Author: Chuxin Chen <[email protected]>
AuthorDate: Mon Sep 11 17:24:26 2023 +0800

    Fix same alias subquery bind (#28409)
---
 .../expression/ExpressionSegmentBinder.java        |  2 +-
 .../expression/impl/ColumnSegmentBinder.java       |  6 +++++-
 .../projection/ProjectionsSegmentBinder.java       |  2 +-
 .../expression/impl/ColumnSegmentBinderTest.java   | 23 ++++++++++++++++++++++
 4 files changed, 30 insertions(+), 3 deletions(-)

diff --git 
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/expression/ExpressionSegmentBinder.java
 
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/expression/ExpressionSegmentBinder.java
index 3c1c50cf07b..06384e0a6d0 100644
--- 
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/expression/ExpressionSegmentBinder.java
+++ 
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/expression/ExpressionSegmentBinder.java
@@ -67,8 +67,8 @@ public final class ExpressionSegmentBinder {
         }
         if (segment instanceof SubqueryExpressionSegment) {
             Map<String, TableSegmentBinderContext> newOuterTableBinderContexts 
= new LinkedHashMap<>();
-            newOuterTableBinderContexts.putAll(tableBinderContexts);
             newOuterTableBinderContexts.putAll(outerTableBinderContexts);
+            newOuterTableBinderContexts.putAll(tableBinderContexts);
             return 
SubqueryExpressionSegmentBinder.bind((SubqueryExpressionSegment) segment, 
statementBinderContext, newOuterTableBinderContexts);
         }
         if (segment instanceof InExpression) {
diff --git 
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/expression/impl/ColumnSegmentBinder.java
 
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/expression/impl/ColumnSegmentBinder.java
index c6f46604f96..cf11560d320 100644
--- 
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/expression/impl/ColumnSegmentBinder.java
+++ 
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/expression/impl/ColumnSegmentBinder.java
@@ -32,12 +32,14 @@ import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.item.Projecti
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.generic.bounded.ColumnSegmentBoundedInfo;
 import 
org.apache.shardingsphere.sql.parser.sql.common.value.identifier.IdentifierValue;
 
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Iterator;
 import java.util.LinkedHashSet;
 import java.util.LinkedList;
+import java.util.ListIterator;
 import java.util.Map;
 import java.util.Optional;
 
@@ -153,7 +155,9 @@ public final class ColumnSegmentBinder {
     }
     
     private static Optional<ProjectionSegment> 
findInputColumnSegmentFromOuterTable(final ColumnSegment segment, final 
Map<String, TableSegmentBinderContext> outerTableBinderContexts) {
-        for (TableSegmentBinderContext each : 
outerTableBinderContexts.values()) {
+        ListIterator<TableSegmentBinderContext> listIterator = new 
ArrayList<>(outerTableBinderContexts.values()).listIterator(outerTableBinderContexts.size());
+        while (listIterator.hasPrevious()) {
+            TableSegmentBinderContext each = listIterator.previous();
             ProjectionSegment projectionSegment = 
each.getProjectionSegmentByColumnLabel(segment.getIdentifier().getValue());
             if (null != projectionSegment) {
                 return Optional.of(projectionSegment);
diff --git 
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/projection/ProjectionsSegmentBinder.java
 
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/projection/ProjectionsSegmentBinder.java
index 375d59d8694..62cd4b7e67f 100644
--- 
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/projection/ProjectionsSegmentBinder.java
+++ 
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/projection/ProjectionsSegmentBinder.java
@@ -69,8 +69,8 @@ public final class ProjectionsSegmentBinder {
         }
         if (projectionSegment instanceof SubqueryProjectionSegment) {
             Map<String, TableSegmentBinderContext> newOuterTableBinderContexts 
= new LinkedHashMap<>();
-            newOuterTableBinderContexts.putAll(tableBinderContexts);
             newOuterTableBinderContexts.putAll(outerTableBinderContexts);
+            newOuterTableBinderContexts.putAll(tableBinderContexts);
             return 
SubqueryProjectionSegmentBinder.bind((SubqueryProjectionSegment) 
projectionSegment, statementBinderContext, newOuterTableBinderContexts);
         }
         // TODO support more ProjectionSegment bind
diff --git 
a/infra/binder/src/test/java/org/apache/shardingsphere/infra/binder/segment/expression/impl/ColumnSegmentBinderTest.java
 
b/infra/binder/src/test/java/org/apache/shardingsphere/infra/binder/segment/expression/impl/ColumnSegmentBinderTest.java
index 9df73cfb5cb..0de5d321033 100644
--- 
a/infra/binder/src/test/java/org/apache/shardingsphere/infra/binder/segment/expression/impl/ColumnSegmentBinderTest.java
+++ 
b/infra/binder/src/test/java/org/apache/shardingsphere/infra/binder/segment/expression/impl/ColumnSegmentBinderTest.java
@@ -64,4 +64,27 @@ class ColumnSegmentBinderTest {
         
assertThat(actual.getColumnBoundedInfo().getOriginalTable().getValue(), 
is("t_order"));
         
assertThat(actual.getColumnBoundedInfo().getOriginalColumn().getValue(), 
is("order_id"));
     }
+    
+    @Test
+    void assertBindFromOuterTable() {
+        Map<String, TableSegmentBinderContext> outerTableBinderContexts = new 
LinkedHashMap<>();
+        ColumnSegment boundedOrderStatusColumn = new ColumnSegment(0, 0, new 
IdentifierValue("status"));
+        boundedOrderStatusColumn.setColumnBoundedInfo(new 
ColumnSegmentBoundedInfo(new IdentifierValue(DefaultDatabase.LOGIC_NAME), new 
IdentifierValue(DefaultDatabase.LOGIC_NAME),
+                new IdentifierValue("t_order"), new 
IdentifierValue("status")));
+        outerTableBinderContexts.put("t_order", new 
TableSegmentBinderContext(Collections.singleton(new 
ColumnProjectionSegment(boundedOrderStatusColumn))));
+        ColumnSegment boundedOrderItemStatusColumn = new ColumnSegment(0, 0, 
new IdentifierValue("status"));
+        boundedOrderItemStatusColumn.setColumnBoundedInfo(new 
ColumnSegmentBoundedInfo(new IdentifierValue(DefaultDatabase.LOGIC_NAME), new 
IdentifierValue(DefaultDatabase.LOGIC_NAME),
+                new IdentifierValue("t_order_item"), new 
IdentifierValue("status")));
+        outerTableBinderContexts.put("t_order_item", new 
TableSegmentBinderContext(Collections.singleton(new 
ColumnProjectionSegment(boundedOrderItemStatusColumn))));
+        SQLStatementBinderContext statementBinderContext =
+                new 
SQLStatementBinderContext(mock(ShardingSphereMetaData.class), 
DefaultDatabase.LOGIC_NAME, TypedSPILoader.getService(DatabaseType.class, 
"FIXTURE"), Collections.emptySet());
+        ColumnSegment columnSegment = new ColumnSegment(0, 0, new 
IdentifierValue("status"));
+        ColumnSegment actual = ColumnSegmentBinder.bind(columnSegment, 
SegmentType.PROJECTION, statementBinderContext, Collections.emptyMap(), 
outerTableBinderContexts);
+        assertNotNull(actual.getColumnBoundedInfo());
+        assertNull(actual.getOtherUsingColumnBoundedInfo());
+        
assertThat(actual.getColumnBoundedInfo().getOriginalDatabase().getValue(), 
is(DefaultDatabase.LOGIC_NAME));
+        
assertThat(actual.getColumnBoundedInfo().getOriginalSchema().getValue(), 
is(DefaultDatabase.LOGIC_NAME));
+        
assertThat(actual.getColumnBoundedInfo().getOriginalTable().getValue(), 
is("t_order_item"));
+        
assertThat(actual.getColumnBoundedInfo().getOriginalColumn().getValue(), 
is("status"));
+    }
 }

Reply via email to