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"));
+ }
}