This is an automated email from the ASF dual-hosted git repository.
zhaojinchao 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 eb9e41a7024 Fix shorthand expand wrong column name when subquery
projection contains alias (#27592)
eb9e41a7024 is described below
commit eb9e41a70245e647a7363a556b2eee6848acf18c
Author: Zhengqiang Duan <[email protected]>
AuthorDate: Mon Jul 31 20:47:27 2023 +0800
Fix shorthand expand wrong column name when subquery projection contains
alias (#27592)
---
.../from/impl/SubqueryTableSegmentBinder.java | 20 +++++++------
.../from/impl/SubqueryTableSegmentBinderTest.java | 33 ++++++++++++++++++++--
2 files changed, 42 insertions(+), 11 deletions(-)
diff --git
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/from/impl/SubqueryTableSegmentBinder.java
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/from/impl/SubqueryTableSegmentBinder.java
index a87dccb9eaa..a5f706d60b6 100644
---
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/from/impl/SubqueryTableSegmentBinder.java
+++
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/from/impl/SubqueryTableSegmentBinder.java
@@ -17,6 +17,7 @@
package org.apache.shardingsphere.infra.binder.segment.from.impl;
+import com.google.common.base.Strings;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import
org.apache.shardingsphere.infra.binder.segment.from.TableSegmentBinderContext;
@@ -78,16 +79,17 @@ public final class SubqueryTableSegmentBinder {
return result;
}
- private static ColumnProjectionSegment createColumnProjection(final
ColumnProjectionSegment originalColumnProjection, final IdentifierValue
subqueryTableName) {
- ColumnSegment originalColumnSegment =
originalColumnProjection.getColumn();
- ColumnSegment newColumnSegment = new ColumnSegment(0, 0,
originalColumnSegment.getIdentifier());
- newColumnSegment.setOwner(new OwnerSegment(0, 0, subqueryTableName));
-
newColumnSegment.setOriginalColumn(originalColumnSegment.getOriginalColumn());
-
newColumnSegment.setOriginalTable(originalColumnSegment.getOriginalTable());
-
newColumnSegment.setOriginalSchema(originalColumnSegment.getOriginalSchema());
-
newColumnSegment.setOriginalDatabase(originalColumnSegment.getOriginalDatabase());
+ private static ColumnProjectionSegment createColumnProjection(final
ColumnProjectionSegment originalColumn, final IdentifierValue
subqueryTableName) {
+ ColumnSegment newColumnSegment = new ColumnSegment(0, 0,
originalColumn.getAlias().orElseGet(() ->
originalColumn.getColumn().getIdentifier()));
+ if (!Strings.isNullOrEmpty(subqueryTableName.getValue())) {
+ newColumnSegment.setOwner(new OwnerSegment(0, 0,
subqueryTableName));
+ }
+
newColumnSegment.setOriginalColumn(originalColumn.getColumn().getOriginalColumn());
+
newColumnSegment.setOriginalTable(originalColumn.getColumn().getOriginalTable());
+
newColumnSegment.setOriginalSchema(originalColumn.getColumn().getOriginalSchema());
+
newColumnSegment.setOriginalDatabase(originalColumn.getColumn().getOriginalDatabase());
ColumnProjectionSegment result = new
ColumnProjectionSegment(newColumnSegment);
- result.setVisible(originalColumnProjection.isVisible());
+ result.setVisible(originalColumn.isVisible());
return result;
}
}
diff --git
a/infra/binder/src/test/java/org/apache/shardingsphere/infra/binder/segment/from/impl/SubqueryTableSegmentBinderTest.java
b/infra/binder/src/test/java/org/apache/shardingsphere/infra/binder/segment/from/impl/SubqueryTableSegmentBinderTest.java
index 60be9eec76c..d4b802e1028 100644
---
a/infra/binder/src/test/java/org/apache/shardingsphere/infra/binder/segment/from/impl/SubqueryTableSegmentBinderTest.java
+++
b/infra/binder/src/test/java/org/apache/shardingsphere/infra/binder/segment/from/impl/SubqueryTableSegmentBinderTest.java
@@ -25,6 +25,7 @@ import
org.apache.shardingsphere.infra.metadata.ShardingSphereMetaData;
import
org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereColumn;
import
org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereSchema;
import org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader;
+import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.column.ColumnSegment;
import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.subquery.SubquerySegment;
import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.item.ColumnProjectionSegment;
import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.item.ProjectionSegment;
@@ -57,7 +58,7 @@ class SubqueryTableSegmentBinderTest {
private final DatabaseType databaseType =
TypedSPILoader.getService(DatabaseType.class, "FIXTURE");
@Test
- void assertBindWithAlias() {
+ void assertBindWithSubqueryTableAlias() {
MySQLSelectStatement selectStatement =
mock(MySQLSelectStatement.class);
when(selectStatement.getDatabaseType()).thenReturn(databaseType);
when(selectStatement.getFrom()).thenReturn(new SimpleTableSegment(new
TableNameSegment(0, 0, new IdentifierValue("t_order"))));
@@ -76,16 +77,44 @@ class SubqueryTableSegmentBinderTest {
assertTrue(projectionSegments.get(0) instanceof
ColumnProjectionSegment);
assertTrue(((ColumnProjectionSegment)
projectionSegments.get(0)).getColumn().getOwner().isPresent());
assertThat(((ColumnProjectionSegment)
projectionSegments.get(0)).getColumn().getOwner().get().getIdentifier().getValue(),
is("temp"));
+ assertThat(((ColumnProjectionSegment)
projectionSegments.get(0)).getColumn().getIdentifier().getValue(),
is("order_id"));
assertTrue(projectionSegments.get(1) instanceof
ColumnProjectionSegment);
assertTrue(((ColumnProjectionSegment)
projectionSegments.get(1)).getColumn().getOwner().isPresent());
assertThat(((ColumnProjectionSegment)
projectionSegments.get(1)).getColumn().getOwner().get().getIdentifier().getValue(),
is("temp"));
+ assertThat(((ColumnProjectionSegment)
projectionSegments.get(1)).getColumn().getIdentifier().getValue(),
is("user_id"));
assertTrue(projectionSegments.get(2) instanceof
ColumnProjectionSegment);
assertTrue(((ColumnProjectionSegment)
projectionSegments.get(2)).getColumn().getOwner().isPresent());
assertThat(((ColumnProjectionSegment)
projectionSegments.get(2)).getColumn().getOwner().get().getIdentifier().getValue(),
is("temp"));
+ assertThat(((ColumnProjectionSegment)
projectionSegments.get(2)).getColumn().getIdentifier().getValue(),
is("status"));
}
@Test
- void assertBindWithoutAlias() {
+ void assertBindWithSubqueryProjectionAlias() {
+ MySQLSelectStatement selectStatement =
mock(MySQLSelectStatement.class);
+ when(selectStatement.getDatabaseType()).thenReturn(databaseType);
+ when(selectStatement.getFrom()).thenReturn(new SimpleTableSegment(new
TableNameSegment(0, 0, new IdentifierValue("t_order"))));
+ ProjectionsSegment projectionsSegment = new ProjectionsSegment(0, 0);
+ ColumnProjectionSegment columnProjectionSegment = new
ColumnProjectionSegment(new ColumnSegment(0, 0, new
IdentifierValue("order_id")));
+ columnProjectionSegment.setAlias(new AliasSegment(0, 0, new
IdentifierValue("order_id_alias")));
+ projectionsSegment.getProjections().add(columnProjectionSegment);
+ when(selectStatement.getProjections()).thenReturn(projectionsSegment);
+ SubqueryTableSegment subqueryTableSegment = new
SubqueryTableSegment(new SubquerySegment(0, 0, selectStatement));
+ subqueryTableSegment.setAlias(new AliasSegment(0, 0, new
IdentifierValue("temp")));
+ ShardingSphereMetaData metaData = createMetaData();
+ Map<String, TableSegmentBinderContext> tableBinderContexts = new
CaseInsensitiveMap<>();
+ SubqueryTableSegment actual =
SubqueryTableSegmentBinder.bind(subqueryTableSegment, metaData,
DefaultDatabase.LOGIC_NAME, tableBinderContexts);
+ assertTrue(actual.getAlias().isPresent());
+ assertTrue(tableBinderContexts.containsKey("temp"));
+ List<ProjectionSegment> projectionSegments = new
ArrayList<>(tableBinderContexts.get("temp").getProjectionSegments());
+ assertThat(projectionSegments.size(), is(1));
+ assertTrue(projectionSegments.get(0) instanceof
ColumnProjectionSegment);
+ assertTrue(((ColumnProjectionSegment)
projectionSegments.get(0)).getColumn().getOwner().isPresent());
+ assertThat(((ColumnProjectionSegment)
projectionSegments.get(0)).getColumn().getOwner().get().getIdentifier().getValue(),
is("temp"));
+ assertThat(((ColumnProjectionSegment)
projectionSegments.get(0)).getColumn().getIdentifier().getValue(),
is("order_id_alias"));
+ }
+
+ @Test
+ void assertBindWithoutSubqueryTableAlias() {
MySQLSelectStatement selectStatement =
mock(MySQLSelectStatement.class);
when(selectStatement.getDatabaseType()).thenReturn(databaseType);
when(selectStatement.getFrom()).thenReturn(new SimpleTableSegment(new
TableNameSegment(0, 0, new IdentifierValue("t_order"))));