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 ad95d407845 fix ShardingSphereResultSet bug. (#21768)
ad95d407845 is described below

commit ad95d407845e2b0dd5d81b24da20770d5c8fd1e9
Author: fang1025 <[email protected]>
AuthorDate: Wed Nov 23 09:31:03 2022 +0800

    fix ShardingSphereResultSet bug. (#21768)
    
    * fix ShardingSphereResultSet bug.
    
    * fix ShardingSphereResultSet bug.
    
    * fix ShardingSphereResultSet bug.
    
    * merge actualColumns and resultSetColumns to one field
    
    * test ShorthandProjection.resultSetColumns
    
    * fix ProjectionEngineTest&ShorthandProjection code style
    
    * fix ShorthandProjection code style
---
 .../select/projection/ProjectionsContext.java      |  6 ++--
 .../select/projection/engine/ProjectionEngine.java | 31 +++++++++++----------
 .../projection/impl/ShorthandProjection.java       | 25 +++++++++++++----
 .../projection/engine/ProjectionEngineTest.java    | 32 ++++++++++++++++++++++
 4 files changed, 71 insertions(+), 23 deletions(-)

diff --git 
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/projection/ProjectionsContext.java
 
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/projection/ProjectionsContext.java
index 97784c192e6..a5cc6c6cb4f 100644
--- 
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/projection/ProjectionsContext.java
+++ 
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/projection/ProjectionsContext.java
@@ -78,7 +78,7 @@ public final class ProjectionsContext {
         List<Projection> result = new ArrayList<>();
         for (Projection each : projections) {
             if (each instanceof ShorthandProjection) {
-                result.addAll(((ShorthandProjection) 
each).getActualColumns().values());
+                result.addAll(((ShorthandProjection) 
each).getResultSetColumns().values());
             } else if (!(each instanceof DerivedProjection)) {
                 result.add(each);
             }
@@ -107,8 +107,8 @@ public final class ProjectionsContext {
      */
     public Optional<String> findAlias(final String projectionName) {
         for (Projection each : projections) {
-            if (each instanceof ShorthandProjection && ((ShorthandProjection) 
each).getActualColumns().containsKey(projectionName.toLowerCase())) {
-                return ((ShorthandProjection) 
each).getActualColumns().get(projectionName.toLowerCase()).getAlias();
+            if (each instanceof ShorthandProjection && ((ShorthandProjection) 
each).getResultSetColumns().containsKey(projectionName.toLowerCase())) {
+                return ((ShorthandProjection) 
each).getResultSetColumns().get(projectionName.toLowerCase()).getAlias();
             }
             if 
(projectionName.equalsIgnoreCase(SQLUtil.getExactlyValue(each.getExpression())))
 {
                 return each.getAlias();
diff --git 
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/projection/engine/ProjectionEngine.java
 
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/projection/engine/ProjectionEngine.java
index 8f144f0d97e..3709a34a869 100644
--- 
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/projection/engine/ProjectionEngine.java
+++ 
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/projection/engine/ProjectionEngine.java
@@ -115,11 +115,11 @@ public final class ProjectionEngine {
     
     private ShorthandProjection createProjection(final TableSegment table, 
final ShorthandProjectionSegment projectionSegment) {
         String owner = projectionSegment.getOwner().map(optional -> 
optional.getIdentifier().getValue()).orElse(null);
-        Collection<ColumnProjection> columnProjections = new LinkedHashSet<>();
-        
columnProjections.addAll(getShorthandColumnsFromSimpleTableSegment(table, 
owner));
-        
columnProjections.addAll(getShorthandColumnsFromSubqueryTableSegment(table));
-        
columnProjections.addAll(getShorthandColumnsFromJoinTableSegment(table, 
projectionSegment));
-        return new ShorthandProjection(owner, columnProjections);
+        Collection<Projection> projections = new LinkedHashSet<>();
+        projections.addAll(getShorthandColumnsFromSimpleTableSegment(table, 
owner));
+        projections.addAll(getShorthandColumnsFromSubqueryTableSegment(table));
+        projections.addAll(getShorthandColumnsFromJoinTableSegment(table, 
projectionSegment));
+        return new ShorthandProjection(owner, projections);
     }
     
     private ColumnProjection createProjection(final ColumnProjectionSegment 
projectionSegment) {
@@ -171,34 +171,35 @@ public final class ProjectionEngine {
         return result;
     }
     
-    private Collection<ColumnProjection> 
getShorthandColumnsFromSubqueryTableSegment(final TableSegment table) {
+    private Collection<Projection> 
getShorthandColumnsFromSubqueryTableSegment(final TableSegment table) {
         if (!(table instanceof SubqueryTableSegment)) {
             return Collections.emptyList();
         }
         SelectStatement subSelectStatement = ((SubqueryTableSegment) 
table).getSubquery().getSelect();
         Collection<Projection> projections = 
subSelectStatement.getProjections().getProjections().stream().map(each -> 
createProjection(subSelectStatement.getFrom(), each).orElse(null))
                 .filter(Objects::nonNull).collect(Collectors.toList());
-        return getColumnProjections(projections);
+        return getResultSetProjections(projections);
     }
     
-    private Collection<ColumnProjection> 
getShorthandColumnsFromJoinTableSegment(final TableSegment table, final 
ProjectionSegment projectionSegment) {
+    private Collection<Projection> 
getShorthandColumnsFromJoinTableSegment(final TableSegment table, final 
ProjectionSegment projectionSegment) {
         if (!(table instanceof JoinTableSegment)) {
             return Collections.emptyList();
         }
         Collection<Projection> projections = new LinkedList<>();
         createProjection(((JoinTableSegment) table).getLeft(), 
projectionSegment).ifPresent(projections::add);
         createProjection(((JoinTableSegment) table).getRight(), 
projectionSegment).ifPresent(projections::add);
-        return getColumnProjections(projections);
+        return getResultSetProjections(projections);
     }
     
-    private Collection<ColumnProjection> getColumnProjections(final 
Collection<Projection> projections) {
-        Collection<ColumnProjection> result = new LinkedList<>();
+    private Collection<Projection> getResultSetProjections(final 
Collection<Projection> projections) {
+        Collection<Projection> result = new LinkedList<>();
         for (Projection each : projections) {
             if (each instanceof ColumnProjection) {
-                result.add((ColumnProjection) each);
-            }
-            if (each instanceof ShorthandProjection) {
-                result.addAll(((ShorthandProjection) 
each).getActualColumns().values());
+                result.add(each);
+            } else if (each instanceof ExpressionProjection) {
+                result.add(each);
+            } else if (each instanceof ShorthandProjection) {
+                result.addAll(((ShorthandProjection) 
each).getResultSetColumns().values());
             }
         }
         return result;
diff --git 
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/projection/impl/ShorthandProjection.java
 
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/projection/impl/ShorthandProjection.java
index 4be24043b54..44f70ca4a13 100644
--- 
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/projection/impl/ShorthandProjection.java
+++ 
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/projection/impl/ShorthandProjection.java
@@ -37,12 +37,12 @@ import java.util.Optional;
 public final class ShorthandProjection implements Projection {
     
     private final String owner;
-    
-    private final Map<String, ColumnProjection> actualColumns = new 
LinkedHashMap<>();
-    
-    public ShorthandProjection(final String owner, final 
Collection<ColumnProjection> columnProjections) {
+
+    private final Map<String, Projection> resultSetColumns = new 
LinkedHashMap<>();
+
+    public ShorthandProjection(final String owner, final 
Collection<Projection> projections) {
         this.owner = owner;
-        columnProjections.forEach(each -> 
actualColumns.put(each.getExpression().toLowerCase(), each));
+        projections.forEach(each -> 
resultSetColumns.put(each.getExpression().toLowerCase(), each));
     }
     
     @Override
@@ -68,4 +68,19 @@ public final class ShorthandProjection implements Projection 
{
     public Optional<String> getOwner() {
         return Optional.ofNullable(owner);
     }
+
+    /**
+     * get actualColumns, exclude ExpressionProjection.
+     *
+     * @return actualColumns
+     */
+    public Map<String, ColumnProjection> getActualColumns() {
+        Map<String, ColumnProjection> actualColumns = new LinkedHashMap<>();
+        for (Map.Entry<String, Projection> entry : 
resultSetColumns.entrySet()) {
+            if (entry.getValue() instanceof ColumnProjection) {
+                actualColumns.put(entry.getKey(), (ColumnProjection) 
entry.getValue());
+            }
+        }
+        return actualColumns;
+    }
 }
diff --git 
a/infra/binder/src/test/java/org/apache/shardingsphere/infra/binder/segment/select/projection/engine/ProjectionEngineTest.java
 
b/infra/binder/src/test/java/org/apache/shardingsphere/infra/binder/segment/select/projection/engine/ProjectionEngineTest.java
index e63bacd51f4..8493ce69abe 100644
--- 
a/infra/binder/src/test/java/org/apache/shardingsphere/infra/binder/segment/select/projection/engine/ProjectionEngineTest.java
+++ 
b/infra/binder/src/test/java/org/apache/shardingsphere/infra/binder/segment/select/projection/engine/ProjectionEngineTest.java
@@ -32,18 +32,22 @@ import 
org.apache.shardingsphere.sql.parser.sql.common.enums.AggregationType;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.column.ColumnSegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.complex.CommonExpressionSegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.simple.ParameterMarkerExpressionSegment;
+import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.subquery.SubquerySegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.item.AggregationDistinctProjectionSegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.item.AggregationProjectionSegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.item.ColumnProjectionSegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.item.ExpressionProjectionSegment;
+import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.item.ProjectionsSegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.item.ShorthandProjectionSegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.generic.AliasSegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.generic.OwnerSegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.JoinTableSegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.SimpleTableSegment;
+import 
org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.SubqueryTableSegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.TableNameSegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.TableSegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.value.identifier.IdentifierValue;
+import 
org.apache.shardingsphere.sql.parser.sql.dialect.statement.oracle.dml.OracleSelectStatement;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
@@ -201,4 +205,32 @@ public final class ProjectionEngineTest {
         ShorthandProjectionSegment shorthandProjectionSegment = new 
ShorthandProjectionSegment(0, 0);
         new ProjectionEngine(DefaultDatabase.LOGIC_NAME, 
Collections.singletonMap(DefaultDatabase.LOGIC_NAME, schema), 
databaseType).createProjection(tableSegment, shorthandProjectionSegment);
     }
+
+    @Test
+    public void 
assertResultSetColumnsWithColumnProjectionAndExpressionProjectionOfShorthandProjection()
 {
+        ProjectionsSegment subQuerySegment = new ProjectionsSegment(0, 0);
+        ColumnSegment columnSegment = new ColumnSegment(0, 0, new 
IdentifierValue("name"));
+        subQuerySegment.getProjections().add(new 
ColumnProjectionSegment(columnSegment));
+        ExpressionProjectionSegment expressionProjectionSegment = new 
ExpressionProjectionSegment(0, 0, "nvl(leave_date, '20991231')");
+        expressionProjectionSegment.setAlias(new AliasSegment(0, 0, new 
IdentifierValue("leave_date")));
+        subQuerySegment.getProjections().add(expressionProjectionSegment);
+        OracleSelectStatement subSelectStatement = new OracleSelectStatement();
+        subSelectStatement.setProjections(subQuerySegment);
+        subSelectStatement.setFrom(new SimpleTableSegment(new 
TableNameSegment(0, 0, new IdentifierValue("staff_info"))));
+        ShorthandProjectionSegment shorthandProjectionSegment = new 
ShorthandProjectionSegment(0, 0);
+        SubqueryTableSegment subqueryTableSegment = new 
SubqueryTableSegment(new SubquerySegment(0, 0, subSelectStatement));
+        Optional<Projection> actual = new 
ProjectionEngine(DefaultDatabase.LOGIC_NAME, 
Collections.singletonMap(DefaultDatabase.LOGIC_NAME, schema), databaseType)
+                .createProjection(subqueryTableSegment, 
shorthandProjectionSegment);
+        assertTrue(actual.isPresent());
+        assertThat(actual.get(), instanceOf(ShorthandProjection.class));
+        assertThat(((ShorthandProjection) 
actual.get()).getActualColumns().size(), is(1));
+        assertThat(((ShorthandProjection) 
actual.get()).getResultSetColumns().size(), is(2));
+        Map<String, ColumnProjection> actualColumns = new LinkedHashMap<>();
+        actualColumns.put("name", new ColumnProjection(null, "name", null));
+        assertThat(((ShorthandProjection) actual.get()).getActualColumns(), 
is(actualColumns));
+        Map<String, Projection> resultSetColumns = new LinkedHashMap<>();
+        resultSetColumns.put("name", new ColumnProjection(null, "name", null));
+        resultSetColumns.put("nvl(leave_date, '20991231')", new 
ExpressionProjection("nvl(leave_date, '20991231')", "leave_date"));
+        assertThat(((ShorthandProjection) actual.get()).getResultSetColumns(), 
is(resultSetColumns));
+    }
 }

Reply via email to