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

chengzhang 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 3298333af39 Enhance ExpressionProjection and SubqueryProjection 
getColumnName and getColumnLabel logic (#27918)
3298333af39 is described below

commit 3298333af39e6560a49dcd2b98a78a31cfbcdfbf
Author: Zhengqiang Duan <[email protected]>
AuthorDate: Fri Aug 4 17:16:34 2023 +0800

    Enhance ExpressionProjection and SubqueryProjection getColumnName and 
getColumnLabel logic (#27918)
---
 .../select/projection/engine/ProjectionEngine.java |  4 +--
 .../projection/impl/ExpressionProjection.java      | 15 ++++++++--
 .../select/projection/impl/SubqueryProjection.java | 17 +++++++----
 .../select/projection/util/ProjectionUtils.java    | 35 +++++++++++++++++++++-
 .../select/projection/ProjectionsContextTest.java  |  8 +++--
 .../generic/SubstitutableColumnNameTokenTest.java  | 11 ++++---
 6 files changed, 72 insertions(+), 18 deletions(-)

diff --git 
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/context/segment/select/projection/engine/ProjectionEngine.java
 
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/context/segment/select/projection/engine/ProjectionEngine.java
index 4746fa90a86..472f7f60ba4 100644
--- 
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/context/segment/select/projection/engine/ProjectionEngine.java
+++ 
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/context/segment/select/projection/engine/ProjectionEngine.java
@@ -97,7 +97,7 @@ public final class ProjectionEngine {
     private SubqueryProjection createProjection(final TableSegment table, 
final SubqueryProjectionSegment projectionSegment) {
         Projection subqueryProjection = createProjection(table, 
projectionSegment.getSubquery().getSelect().getProjections().getProjections().iterator().next())
                 .orElseThrow(() -> new IllegalArgumentException("Subquery 
projection must have at least one projection column."));
-        return new SubqueryProjection(projectionSegment.getText(), 
subqueryProjection, projectionSegment.getAlias().orElse(null), databaseType);
+        return new SubqueryProjection(projectionSegment, subqueryProjection, 
projectionSegment.getAlias().orElse(null), databaseType);
     }
     
     private ShorthandProjection createProjection(final TableSegment table, 
final ShorthandProjectionSegment projectionSegment) {
@@ -117,7 +117,7 @@ public final class ProjectionEngine {
     }
     
     private ExpressionProjection createProjection(final 
ExpressionProjectionSegment projectionSegment) {
-        return new ExpressionProjection(projectionSegment.getText(), 
projectionSegment.getAlias().orElse(null));
+        return new ExpressionProjection(projectionSegment, 
projectionSegment.getAlias().orElse(null), databaseType);
     }
     
     private AggregationDistinctProjection createProjection(final 
AggregationDistinctProjectionSegment projectionSegment) {
diff --git 
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/context/segment/select/projection/impl/ExpressionProjection.java
 
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/context/segment/select/projection/impl/ExpressionProjection.java
index e441dc535b8..9c0b1aca4a2 100644
--- 
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/context/segment/select/projection/impl/ExpressionProjection.java
+++ 
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/context/segment/select/projection/impl/ExpressionProjection.java
@@ -22,6 +22,9 @@ import lombok.Getter;
 import lombok.RequiredArgsConstructor;
 import lombok.ToString;
 import 
org.apache.shardingsphere.infra.binder.context.segment.select.projection.Projection;
+import 
org.apache.shardingsphere.infra.binder.context.segment.select.projection.util.ProjectionUtils;
+import org.apache.shardingsphere.infra.database.core.type.DatabaseType;
+import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.item.ExpressionProjectionSegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.value.identifier.IdentifierValue;
 
 import java.util.Optional;
@@ -35,10 +38,12 @@ import java.util.Optional;
 @ToString
 public final class ExpressionProjection implements Projection {
     
-    private final String expression;
+    private final ExpressionProjectionSegment expressionSegment;
     
     private final IdentifierValue alias;
     
+    private final DatabaseType databaseType;
+    
     @Override
     public String getColumnName() {
         return getColumnLabel();
@@ -46,7 +51,13 @@ public final class ExpressionProjection implements 
Projection {
     
     @Override
     public String getColumnLabel() {
-        return getAlias().map(IdentifierValue::getValue).orElse(expression);
+        return getAlias().isPresent() ? 
ProjectionUtils.getColumnLabelFromAlias(getAlias().get(), databaseType)
+                : 
ProjectionUtils.getColumnNameFromExpression(expressionSegment.getText(), 
databaseType);
+    }
+    
+    @Override
+    public String getExpression() {
+        return expressionSegment.getText();
     }
     
     @Override
diff --git 
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/context/segment/select/projection/impl/SubqueryProjection.java
 
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/context/segment/select/projection/impl/SubqueryProjection.java
index 6a5c883678f..3c39a567297 100644
--- 
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/context/segment/select/projection/impl/SubqueryProjection.java
+++ 
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/context/segment/select/projection/impl/SubqueryProjection.java
@@ -22,8 +22,10 @@ import lombok.Getter;
 import lombok.RequiredArgsConstructor;
 import lombok.ToString;
 import 
org.apache.shardingsphere.infra.binder.context.segment.select.projection.Projection;
-import org.apache.shardingsphere.infra.database.oracle.type.OracleDatabaseType;
+import 
org.apache.shardingsphere.infra.binder.context.segment.select.projection.util.ProjectionUtils;
 import org.apache.shardingsphere.infra.database.core.type.DatabaseType;
+import org.apache.shardingsphere.infra.database.oracle.type.OracleDatabaseType;
+import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.item.SubqueryProjectionSegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.value.identifier.IdentifierValue;
 
 import java.util.Optional;
@@ -37,7 +39,7 @@ import java.util.Optional;
 @ToString
 public final class SubqueryProjection implements Projection {
     
-    private final String expression;
+    private final SubqueryProjectionSegment subquerySegment;
     
     private final Projection projection;
     
@@ -52,7 +54,7 @@ public final class SubqueryProjection implements Projection {
     
     @Override
     public String getColumnLabel() {
-        return getAlias().map(IdentifierValue::getValue).orElse(expression);
+        return getAlias().isPresent() ? 
ProjectionUtils.getColumnLabelFromAlias(getAlias().get(), databaseType) : 
ProjectionUtils.getColumnNameFromSubquery(subquerySegment, databaseType);
     }
     
     @Override
@@ -62,8 +64,13 @@ public final class SubqueryProjection implements Projection {
     
     private Optional<IdentifierValue> buildDefaultAlias(final DatabaseType 
databaseType) {
         if (databaseType instanceof OracleDatabaseType) {
-            return Optional.of(new IdentifierValue(expression.replace(" ", 
"").toUpperCase()));
+            return Optional.of(new 
IdentifierValue(subquerySegment.getText().replace(" ", "").toUpperCase()));
         }
-        return Optional.of(new IdentifierValue(expression));
+        return Optional.of(new IdentifierValue(subquerySegment.getText()));
+    }
+    
+    @Override
+    public String getExpression() {
+        return subquerySegment.getText();
     }
 }
diff --git 
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/context/segment/select/projection/util/ProjectionUtils.java
 
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/context/segment/select/projection/util/ProjectionUtils.java
index dba2a93224d..59cabcca66f 100644
--- 
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/context/segment/select/projection/util/ProjectionUtils.java
+++ 
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/context/segment/select/projection/util/ProjectionUtils.java
@@ -19,11 +19,12 @@ package 
org.apache.shardingsphere.infra.binder.context.segment.select.projection
 
 import lombok.AccessLevel;
 import lombok.NoArgsConstructor;
-import org.apache.shardingsphere.infra.database.core.type.DatabaseType;
 import 
org.apache.shardingsphere.infra.database.core.metadata.database.enums.QuoteCharacter;
+import org.apache.shardingsphere.infra.database.core.type.DatabaseType;
 import 
org.apache.shardingsphere.infra.database.opengauss.type.OpenGaussDatabaseType;
 import org.apache.shardingsphere.infra.database.oracle.type.OracleDatabaseType;
 import 
org.apache.shardingsphere.infra.database.postgresql.type.PostgreSQLDatabaseType;
+import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.item.SubqueryProjectionSegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.value.identifier.IdentifierValue;
 
 /**
@@ -84,4 +85,36 @@ public final class ProjectionUtils {
         }
         return functionExpression;
     }
+    
+    /**
+     * Get column name from expression.
+     * 
+     * @param expression expression
+     * @param databaseType database type
+     * @return column name
+     */
+    public static String getColumnNameFromExpression(final String expression, 
final DatabaseType databaseType) {
+        if (databaseType instanceof PostgreSQLDatabaseType || databaseType 
instanceof OpenGaussDatabaseType) {
+            return "?column?";
+        }
+        if (databaseType instanceof OracleDatabaseType) {
+            return expression.replace(" ", "").toUpperCase();
+        }
+        return expression;
+    }
+    
+    /**
+     * Get column name from subquery segment.
+     * 
+     * @param subquerySegment subquery segment
+     * @param databaseType database type
+     * @return column name
+     */
+    public static String getColumnNameFromSubquery(final 
SubqueryProjectionSegment subquerySegment, final DatabaseType databaseType) {
+        // TODO support postgresql subquery projection
+        if (databaseType instanceof OracleDatabaseType) {
+            return subquerySegment.getText().replace(" ", "").toUpperCase();
+        }
+        return subquerySegment.getText();
+    }
 }
diff --git 
a/infra/binder/src/test/java/org/apache/shardingsphere/infra/binder/context/segment/select/projection/ProjectionsContextTest.java
 
b/infra/binder/src/test/java/org/apache/shardingsphere/infra/binder/context/segment/select/projection/ProjectionsContextTest.java
index 50dd9872be8..8ad09136e9b 100644
--- 
a/infra/binder/src/test/java/org/apache/shardingsphere/infra/binder/context/segment/select/projection/ProjectionsContextTest.java
+++ 
b/infra/binder/src/test/java/org/apache/shardingsphere/infra/binder/context/segment/select/projection/ProjectionsContextTest.java
@@ -24,7 +24,9 @@ import 
org.apache.shardingsphere.infra.binder.context.segment.select.projection.
 import 
org.apache.shardingsphere.infra.binder.context.segment.select.projection.impl.ExpressionProjection;
 import 
org.apache.shardingsphere.infra.binder.context.segment.select.projection.impl.ShorthandProjection;
 import org.apache.shardingsphere.infra.database.core.type.DatabaseType;
+import org.apache.shardingsphere.infra.database.mysql.type.MySQLDatabaseType;
 import org.apache.shardingsphere.sql.parser.sql.common.enums.AggregationType;
+import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.item.ExpressionProjectionSegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.value.identifier.IdentifierValue;
 import org.junit.jupiter.api.Test;
 
@@ -150,9 +152,11 @@ class ProjectionsContextTest {
     
     @Test
     void assertIsContainsLastInsertIdProjection() {
-        ProjectionsContext lastInsertIdProjection = new ProjectionsContext(0, 
0, false, Collections.singletonList(new 
ExpressionProjection("LAST_INSERT_ID()", new IdentifierValue("id"))));
+        ProjectionsContext lastInsertIdProjection = new ProjectionsContext(0, 
0, false,
+                Collections.singletonList(new ExpressionProjection(new 
ExpressionProjectionSegment(0, 0, "LAST_INSERT_ID()"), new 
IdentifierValue("id"), new MySQLDatabaseType())));
         assertTrue(lastInsertIdProjection.isContainsLastInsertIdProjection());
-        ProjectionsContext maxProjection = new ProjectionsContext(0, 0, false, 
Collections.singletonList(new ExpressionProjection("MAX(id)", new 
IdentifierValue("max"))));
+        ProjectionsContext maxProjection = new ProjectionsContext(0, 0, false,
+                Collections.singletonList(new ExpressionProjection(new 
ExpressionProjectionSegment(0, 0, "MAX(id)"), new IdentifierValue("max"), new 
MySQLDatabaseType())));
         assertFalse(maxProjection.isContainsLastInsertIdProjection());
     }
 }
diff --git 
a/infra/rewrite/src/test/java/org/apache/shardingsphere/infra/rewrite/sql/token/pojo/generic/SubstitutableColumnNameTokenTest.java
 
b/infra/rewrite/src/test/java/org/apache/shardingsphere/infra/rewrite/sql/token/pojo/generic/SubstitutableColumnNameTokenTest.java
index 86a27173d78..3aee39b4c57 100644
--- 
a/infra/rewrite/src/test/java/org/apache/shardingsphere/infra/rewrite/sql/token/pojo/generic/SubstitutableColumnNameTokenTest.java
+++ 
b/infra/rewrite/src/test/java/org/apache/shardingsphere/infra/rewrite/sql/token/pojo/generic/SubstitutableColumnNameTokenTest.java
@@ -20,10 +20,10 @@ package 
org.apache.shardingsphere.infra.rewrite.sql.token.pojo.generic;
 import 
org.apache.shardingsphere.infra.binder.context.segment.select.projection.Projection;
 import 
org.apache.shardingsphere.infra.binder.context.segment.select.projection.impl.ColumnProjection;
 import 
org.apache.shardingsphere.infra.binder.context.segment.select.projection.impl.SubqueryProjection;
+import 
org.apache.shardingsphere.infra.database.core.metadata.database.enums.QuoteCharacter;
 import org.apache.shardingsphere.infra.database.core.type.DatabaseType;
 import org.apache.shardingsphere.infra.route.context.RouteUnit;
-import 
org.apache.shardingsphere.infra.database.core.metadata.database.enums.QuoteCharacter;
-import org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader;
+import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.item.SubqueryProjectionSegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.value.identifier.IdentifierValue;
 import org.junit.jupiter.api.Test;
 
@@ -64,9 +64,8 @@ class SubstitutableColumnNameTokenTest {
     void assertToStringWithSubqueryProjection() {
         Collection<Projection> projections = Arrays.asList(new 
ColumnProjection(new IdentifierValue("temp", QuoteCharacter.BACK_QUOTE),
                 new IdentifierValue("id", QuoteCharacter.BACK_QUOTE), new 
IdentifierValue("id", QuoteCharacter.BACK_QUOTE), mock(DatabaseType.class)),
-                new SubqueryProjection("(SELECT name FROM t_order)", new 
ColumnProjection(null, "name", null, mock(DatabaseType.class)), new 
IdentifierValue("name"),
-                        TypedSPILoader.getService(DatabaseType.class, 
"Oracle")));
-        assertThat(new SubstitutableColumnNameToken(0, 1, projections, 
QuoteCharacter.BACK_QUOTE).toString(mock(RouteUnit.class)),
-                is("`temp`.`id` AS `id`, `name`"));
+                new SubqueryProjection(new SubqueryProjectionSegment(null, 
"(SELECT name FROM t_order)"), new ColumnProjection(null, "name", null, 
mock(DatabaseType.class)),
+                        new IdentifierValue("name"), 
mock(DatabaseType.class)));
+        assertThat(new SubstitutableColumnNameToken(0, 1, projections, 
QuoteCharacter.BACK_QUOTE).toString(mock(RouteUnit.class)), is("`temp`.`id` AS 
`id`, `name`"));
     }
 }

Reply via email to