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

Reply via email to