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 841fda87c4f Fix wrong shorthand projection when subquery contains same 
column name projection and join statement (#26813)
841fda87c4f is described below

commit 841fda87c4f04d724b1c7bb15552a3eca177b5f4
Author: Zhengqiang Duan <duanzhengqi...@apache.org>
AuthorDate: Fri Jul 7 18:15:26 2023 +0800

    Fix wrong shorthand projection when subquery contains same column name 
projection and join statement (#26813)
    
    * Fix wrong shorthand projection when subquery contains same column name 
projection and join statement
    
    * fix rewrite it
    
    * Fix wrong rewrite result when from segment contains multi subquery table 
join
    
    * Fix wrong rewrite result when from segment contains multi subquery table 
join
    
    * Fix wrong rewrite result when from segment contains multi subquery table 
join
    
    * fix checkstyle
    
    * fix unit test
    
    * fix unit test
    
    * fix build error
    
    * Fix unit test
    
    * Fix unit test
    
    * fix build error
    
    * remove useless file
---
 .../encrypt/merge/dql/EncryptMergedResult.java     | 12 ++++----
 .../EncryptOrderByItemTokenGenerator.java          |  6 ++--
 .../generator/EncryptProjectionTokenGenerator.java | 18 ++++++++++--
 .../segment/select/projection/Projection.java      |  8 ++++--
 .../select/projection/ProjectionsContext.java      | 10 +++++--
 .../select/projection/engine/ProjectionEngine.java | 21 ++++++++------
 .../impl/AggregationDistinctProjection.java        |  9 ++++--
 .../projection/impl/AggregationProjection.java     |  7 +++--
 .../select/projection/impl/ColumnProjection.java   | 33 ++++++++++++++++++++--
 .../select/projection/impl/DerivedProjection.java  |  5 ++--
 .../projection/impl/ExpressionProjection.java      |  6 ++--
 .../projection/impl/ParameterMarkerProjection.java |  6 ++--
 .../projection/impl/ShorthandProjection.java       |  6 ++--
 .../select/projection/impl/SubqueryProjection.java |  5 ++--
 .../projection/engine/ProjectionEngineTest.java    |  5 ++--
 .../prepare/MySQLComStmtPrepareExecutor.java       |  5 ++--
 .../dml/select/select-subquery.xml                 | 24 ++++++++--------
 .../dml/select/select-subquery.xml                 | 16 +++++------
 18 files changed, 134 insertions(+), 68 deletions(-)

diff --git 
a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/merge/dql/EncryptMergedResult.java
 
b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/merge/dql/EncryptMergedResult.java
index 038bfff8733..a700d62bdf2 100644
--- 
a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/merge/dql/EncryptMergedResult.java
+++ 
b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/merge/dql/EncryptMergedResult.java
@@ -63,17 +63,19 @@ public final class EncryptMergedResult implements 
MergedResult {
         TablesContext tablesContext = 
selectStatementContext.getTablesContext();
         String schemaName = tablesContext.getSchemaName()
                 .orElseGet(() -> 
DatabaseTypeEngine.getDefaultSchemaName(selectStatementContext.getDatabaseType(),
 database.getName()));
-        Map<String, String> expressionTableNames = 
tablesContext.findTableNamesByColumnProjection(Collections.singleton(columnProjection.get()),
 database.getSchema(schemaName));
-        Optional<String> tableName = findTableName(columnProjection.get(), 
expressionTableNames);
+        ColumnProjection originalColumn = new 
ColumnProjection(columnProjection.get().getOriginalOwner(), 
columnProjection.get().getOriginalName(), null);
+        Map<String, String> expressionTableNames = 
tablesContext.findTableNamesByColumnProjection(Collections.singletonList(originalColumn),
 database.getSchema(schemaName));
+        Optional<String> tableName = findTableName(originalColumn, 
expressionTableNames);
+        String originalColumnName = originalColumn.getName();
         if (!tableName.isPresent()) {
             return mergedResult.getValue(columnIndex, type);
         }
-        if (!encryptRule.findEncryptTable(tableName.get()).map(optional -> 
optional.isEncryptColumn(columnProjection.get().getName())).orElse(false)) {
+        if (!encryptRule.findEncryptTable(tableName.get()).map(optional -> 
optional.isEncryptColumn(originalColumnName)).orElse(false)) {
             return mergedResult.getValue(columnIndex, type);
         }
         Object cipherValue = mergedResult.getValue(columnIndex, Object.class);
-        EncryptColumn encryptColumn = 
encryptRule.getEncryptTable(tableName.get()).getEncryptColumn(columnProjection.get().getName());
-        return encryptColumn.getCipher().decrypt(database.getName(), 
schemaName, tableName.get(), columnProjection.get().getName(), cipherValue);
+        EncryptColumn encryptColumn = 
encryptRule.getEncryptTable(tableName.get()).getEncryptColumn(originalColumnName);
+        return encryptColumn.getCipher().decrypt(database.getName(), 
schemaName, tableName.get(), originalColumnName, cipherValue);
     }
     
     private Optional<String> findTableName(final ColumnProjection 
columnProjection, final Map<String, String> columnTableNames) {
diff --git 
a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/EncryptOrderByItemTokenGenerator.java
 
b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/EncryptOrderByItemTokenGenerator.java
index 4575a7eeb17..e3b1df2e96a 100644
--- 
a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/EncryptOrderByItemTokenGenerator.java
+++ 
b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/EncryptOrderByItemTokenGenerator.java
@@ -103,7 +103,9 @@ public final class EncryptOrderByItemTokenGenerator 
implements CollectionSQLToke
         }
         Collection<OrderByItem> result = new LinkedList<>();
         SelectStatementContext statementContext = (SelectStatementContext) 
sqlStatementContext;
-        result.addAll(statementContext.getOrderByContext().getItems());
+        if (!statementContext.getOrderByContext().isGenerated()) {
+            result.addAll(statementContext.getOrderByContext().getItems());
+        }
         result.addAll(statementContext.getGroupByContext().getItems());
         for (SelectStatementContext each : 
statementContext.getSubqueryContexts().values()) {
             result.addAll(getOrderByItems(each));
@@ -116,7 +118,7 @@ public final class EncryptOrderByItemTokenGenerator 
implements CollectionSQLToke
             return false;
         }
         SelectStatementContext statementContext = (SelectStatementContext) 
sqlStatementContext;
-        if (!statementContext.getOrderByContext().getItems().isEmpty() || 
!statementContext.getGroupByContext().getItems().isEmpty()) {
+        if (!statementContext.getOrderByContext().getItems().isEmpty() && 
!statementContext.getOrderByContext().isGenerated() || 
!statementContext.getGroupByContext().getItems().isEmpty()) {
             return true;
         }
         for (SelectStatementContext each : 
statementContext.getSubqueryContexts().values()) {
diff --git 
a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/EncryptProjectionTokenGenerator.java
 
b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/EncryptProjectionTokenGenerator.java
index e0f12b6d497..c7f14e2e817 100644
--- 
a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/EncryptProjectionTokenGenerator.java
+++ 
b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/EncryptProjectionTokenGenerator.java
@@ -43,6 +43,8 @@ import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.item.Projecti
 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.SubqueryTableSegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.value.identifier.IdentifierValue;
 
 import java.util.Collection;
@@ -95,7 +97,7 @@ public final class EncryptProjectionTokenGenerator implements 
CollectionSQLToken
                     continue;
                 }
                 Optional<EncryptTable> encryptTable = 
encryptRule.findEncryptTable(tableName);
-                if (encryptTable.isPresent() && 
encryptTable.get().isEncryptColumn(columnProjection.getName())) {
+                if (encryptTable.isPresent() && 
encryptTable.get().isEncryptColumn(columnProjection.getName()) && 
!containsTableSubquery(selectStatementContext)) {
                     
sqlTokens.add(generateSQLToken(encryptTable.get().getEncryptColumn(columnProjection.getName()),
 columnSegment, columnProjection, subqueryType));
                 }
             }
@@ -123,7 +125,7 @@ public final class EncryptProjectionTokenGenerator 
implements CollectionSQLToken
         for (Projection each : actualColumns) {
             String tableName = columnTableNames.get(each.getExpression());
             Optional<EncryptTable> encryptTable = null == tableName ? 
Optional.empty() : encryptRule.findEncryptTable(tableName);
-            if (!encryptTable.isPresent() || 
!encryptTable.get().isEncryptColumn(each.getColumnLabel())) {
+            if (!encryptTable.isPresent() || 
!encryptTable.get().isEncryptColumn(each.getColumnLabel()) || 
containsTableSubquery(selectStatementContext)) {
                 projections.add(each.getAlias().map(optional -> (Projection) 
new ColumnProjection(null, optional, null)).orElse(each));
             } else if (each instanceof ColumnProjection) {
                 
projections.addAll(generateProjections(encryptTable.get().getEncryptColumn(((ColumnProjection)
 each).getName()), (ColumnProjection) each, subqueryType, true, segment));
@@ -134,6 +136,16 @@ public final class EncryptProjectionTokenGenerator 
implements CollectionSQLToken
         return new SubstitutableColumnNameToken(startIndex, 
segment.getStopIndex(), projections, 
selectStatementContext.getDatabaseType().getQuoteCharacter());
     }
     
+    private boolean containsTableSubquery(final SelectStatementContext 
selectStatementContext) {
+        if (selectStatementContext.getSqlStatement().getFrom() instanceof 
SubqueryTableSegment) {
+            return true;
+        } else if (selectStatementContext.getSqlStatement().getFrom() 
instanceof JoinTableSegment) {
+            JoinTableSegment joinTableSegment = (JoinTableSegment) 
selectStatementContext.getSqlStatement().getFrom();
+            return joinTableSegment.getLeft() instanceof SubqueryTableSegment 
|| joinTableSegment.getRight() instanceof SubqueryTableSegment;
+        }
+        return false;
+    }
+    
     private ColumnProjection buildColumnProjection(final 
ColumnProjectionSegment segment) {
         IdentifierValue owner = 
segment.getColumn().getOwner().map(OwnerSegment::getIdentifier).orElse(null);
         return new ColumnProjection(owner, 
segment.getColumn().getIdentifier(), segment.getAliasName().isPresent() ? 
segment.getAlias().map(AliasSegment::getIdentifier).orElse(null) : null);
@@ -188,7 +200,7 @@ public final class EncryptProjectionTokenGenerator 
implements CollectionSQLToken
     private Collection<ColumnProjection> 
generateTableSubqueryProjections(final EncryptColumn encryptColumn, final 
ColumnProjection column, final boolean shorthand) {
         Collection<ColumnProjection> result = new LinkedList<>();
         result.add(distinctOwner(new 
ColumnProjection(column.getOwnerIdentifier(), new 
IdentifierValue(encryptColumn.getCipher().getName(),
-                column.getNameIdentifier().getQuoteCharacter()), null), 
shorthand));
+                column.getNameIdentifier().getQuoteCharacter()), 
Optional.ofNullable(column.getAliasIdentifier()).orElse(column.getNameIdentifier())),
 shorthand));
         encryptColumn.getAssistedQuery().ifPresent(optional -> result.add(
                 new ColumnProjection(column.getOwnerIdentifier(), new 
IdentifierValue(optional.getName(), 
column.getNameIdentifier().getQuoteCharacter()), null)));
         return result;
diff --git 
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/projection/Projection.java
 
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/projection/Projection.java
index fcdca992712..ee6e71e4835 100644
--- 
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/projection/Projection.java
+++ 
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/projection/Projection.java
@@ -48,10 +48,12 @@ public interface Projection {
     String getColumnLabel();
     
     /**
-     * Clone with owner.
+     * Transform subquery projection.
      * 
-     * @param ownerIdentifier owner identifier
+     * @param subqueryTableAlias subquery table alias
+     * @param originalOwner original owner
+     * @param originalName original name
      * @return new projection
      */
-    Projection cloneWithOwner(IdentifierValue ownerIdentifier);
+    Projection transformSubqueryProjection(IdentifierValue subqueryTableAlias, 
IdentifierValue originalOwner, IdentifierValue originalName);
 }
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 28d93f73c23..8b9dd179279 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
@@ -21,6 +21,7 @@ import lombok.Getter;
 import lombok.ToString;
 import 
org.apache.shardingsphere.infra.binder.segment.select.projection.impl.AggregationDistinctProjection;
 import 
org.apache.shardingsphere.infra.binder.segment.select.projection.impl.AggregationProjection;
+import 
org.apache.shardingsphere.infra.binder.segment.select.projection.impl.ColumnProjection;
 import 
org.apache.shardingsphere.infra.binder.segment.select.projection.impl.DerivedProjection;
 import 
org.apache.shardingsphere.infra.binder.segment.select.projection.impl.ShorthandProjection;
 import org.apache.shardingsphere.sql.parser.sql.common.util.SQLUtils;
@@ -108,9 +109,10 @@ public final class ProjectionsContext {
     public Optional<String> findAlias(final String projectionName) {
         for (Projection each : projections) {
             if (each instanceof ShorthandProjection) {
-                Optional<Projection> projection = ((ShorthandProjection) 
each).getActualColumns().stream().filter(optional -> 
projectionName.equalsIgnoreCase(optional.getExpression())).findFirst();
+                Optional<Projection> projection =
+                        ((ShorthandProjection) 
each).getActualColumns().stream().filter(optional -> 
projectionName.equalsIgnoreCase(getOriginalColumnName(optional))).findFirst();
                 if (projection.isPresent()) {
-                    return projection.flatMap(Projection::getAlias);
+                    return projection.map(Projection::getExpression);
                 }
             }
             if 
(projectionName.equalsIgnoreCase(SQLUtils.getExactlyValue(each.getExpression())))
 {
@@ -120,6 +122,10 @@ public final class ProjectionsContext {
         return Optional.empty();
     }
     
+    private String getOriginalColumnName(final Projection projection) {
+        return projection instanceof ColumnProjection ? ((ColumnProjection) 
projection).getOriginalName().getValue() : projection.getExpression();
+    }
+    
     /**
      * Find projection index.
      * 
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 db43f0d67d2..806add4a88c 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
@@ -17,7 +17,6 @@
 
 package 
org.apache.shardingsphere.infra.binder.segment.select.projection.engine;
 
-import com.google.common.base.Strings;
 import lombok.RequiredArgsConstructor;
 import 
org.apache.shardingsphere.infra.binder.segment.select.projection.DerivedColumn;
 import 
org.apache.shardingsphere.infra.binder.segment.select.projection.Projection;
@@ -127,7 +126,7 @@ public final class ProjectionEngine {
         IdentifierValue owner = 
projectionSegment.getOwner().map(OwnerSegment::getIdentifier).orElse(null);
         Collection<Projection> projections = new LinkedHashSet<>();
         projections.addAll(getShorthandColumnsFromSimpleTableSegment(table, 
owner));
-        projections.addAll(getShorthandColumnsFromSubqueryTableSegment(table));
+        projections.addAll(getShorthandColumnsFromSubqueryTableSegment(table, 
owner));
         projections.addAll(getShorthandColumnsFromJoinTableSegment(table, 
owner, projectionSegment));
         return new ShorthandProjection(null == owner ? null : 
owner.getValue(), projections);
     }
@@ -184,26 +183,30 @@ public final class ProjectionEngine {
         return result;
     }
     
-    private Collection<Projection> 
getShorthandColumnsFromSubqueryTableSegment(final TableSegment table) {
-        if (!(table instanceof SubqueryTableSegment)) {
+    private Collection<Projection> 
getShorthandColumnsFromSubqueryTableSegment(final TableSegment table, final 
IdentifierValue owner) {
+        if (!(table instanceof SubqueryTableSegment) || 
isOwnerNotSameWithTableAlias(owner, table)) {
             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 getSubqueryTableActualProjections(projections, 
table.getAlias().map(AliasSegment::getIdentifier).orElse(null));
+        IdentifierValue subqueryTableAlias = 
table.getAlias().map(AliasSegment::getIdentifier).orElse(null);
+        return getSubqueryTableActualProjections(projections, 
subqueryTableAlias);
+    }
+    
+    private boolean isOwnerNotSameWithTableAlias(final IdentifierValue owner, 
final TableSegment table) {
+        return null != owner && table.getAliasName().isPresent() && 
!table.getAliasName().get().equals(owner.getValue());
     }
     
     private Collection<Projection> getSubqueryTableActualProjections(final 
Collection<Projection> projections, final IdentifierValue subqueryTableAlias) {
-        if (null == subqueryTableAlias || 
Strings.isNullOrEmpty(subqueryTableAlias.getValue())) {
-            return getActualProjections(projections);
-        }
         Collection<Projection> result = new LinkedList<>();
         for (Projection each : projections) {
             if (each instanceof ShorthandProjection) {
                 
result.addAll(getSubqueryTableActualProjections(((ShorthandProjection) 
each).getActualColumns(), subqueryTableAlias));
             } else if (!(each instanceof DerivedProjection)) {
-                result.add(each.cloneWithOwner(subqueryTableAlias));
+                IdentifierValue originalOwner = each instanceof 
ColumnProjection ? ((ColumnProjection) each).getOriginalOwner() : null;
+                IdentifierValue originalName = each instanceof 
ColumnProjection ? ((ColumnProjection) each).getOriginalName() : null;
+                
result.add(each.transformSubqueryProjection(subqueryTableAlias, originalOwner, 
originalName));
             }
         }
         return result;
diff --git 
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/projection/impl/AggregationDistinctProjection.java
 
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/projection/impl/AggregationDistinctProjection.java
index d3651f0966a..93fcd4e7b17 100644
--- 
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/projection/impl/AggregationDistinctProjection.java
+++ 
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/projection/impl/AggregationDistinctProjection.java
@@ -53,8 +53,11 @@ public final class AggregationDistinctProjection extends 
AggregationProjection {
     }
     
     @Override
-    public Projection cloneWithOwner(final IdentifierValue ownerIdentifier) {
-        // TODO replace column owner when AggregationDistinctProjection 
contains owner
-        return new AggregationDistinctProjection(startIndex, stopIndex, 
getType(), getInnerExpression(), getAlias().orElse(null), 
distinctInnerExpression, getDatabaseType());
+    public Projection transformSubqueryProjection(final IdentifierValue 
subqueryTableAlias, final IdentifierValue originalOwner, final IdentifierValue 
originalName) {
+        // TODO replace getAlias with aliasIdentifier
+        if (getAlias().isPresent()) {
+            return new ColumnProjection(subqueryTableAlias, new 
IdentifierValue(getAlias().get()), null);
+        }
+        return new AggregationDistinctProjection(startIndex, stopIndex, 
getType(), getInnerExpression(), null, distinctInnerExpression, 
getDatabaseType());
     }
 }
diff --git 
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/projection/impl/AggregationProjection.java
 
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/projection/impl/AggregationProjection.java
index f91ca5d9d1f..13f650071e9 100644
--- 
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/projection/impl/AggregationProjection.java
+++ 
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/projection/impl/AggregationProjection.java
@@ -75,8 +75,11 @@ public class AggregationProjection implements Projection {
     }
     
     @Override
-    public Projection cloneWithOwner(final IdentifierValue owner) {
-        // TODO replace column owner when AggregationProjection contains owner
+    public Projection transformSubqueryProjection(final IdentifierValue 
subqueryTableAlias, final IdentifierValue originalOwner, final IdentifierValue 
originalName) {
+        // TODO replace getAlias with aliasIdentifier
+        if (getAlias().isPresent()) {
+            return new ColumnProjection(subqueryTableAlias, new 
IdentifierValue(getAlias().get()), null);
+        }
         AggregationProjection result = new AggregationProjection(type, 
innerExpression, alias, databaseType);
         result.setIndex(index);
         
result.getDerivedAggregationProjections().addAll(derivedAggregationProjections);
diff --git 
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/projection/impl/ColumnProjection.java
 
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/projection/impl/ColumnProjection.java
index 65b074d0a48..1b12c8a8c60 100644
--- 
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/projection/impl/ColumnProjection.java
+++ 
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/projection/impl/ColumnProjection.java
@@ -20,6 +20,7 @@ package 
org.apache.shardingsphere.infra.binder.segment.select.projection.impl;
 import lombok.EqualsAndHashCode;
 import lombok.Getter;
 import lombok.RequiredArgsConstructor;
+import lombok.Setter;
 import lombok.ToString;
 import 
org.apache.shardingsphere.infra.binder.segment.select.projection.Projection;
 import org.apache.shardingsphere.sql.parser.sql.common.enums.QuoteCharacter;
@@ -32,7 +33,8 @@ import java.util.Optional;
  */
 @RequiredArgsConstructor
 @Getter
-@EqualsAndHashCode
+@Setter
+@EqualsAndHashCode(exclude = {"originalOwner", "originalName"})
 @ToString
 public final class ColumnProjection implements Projection {
     
@@ -42,6 +44,10 @@ public final class ColumnProjection implements Projection {
     
     private final IdentifierValue aliasIdentifier;
     
+    private IdentifierValue originalOwner;
+    
+    private IdentifierValue originalName;
+    
     public ColumnProjection(final String owner, final String name, final 
String alias) {
         this(null == owner ? null : new IdentifierValue(owner, 
QuoteCharacter.NONE), new IdentifierValue(name, QuoteCharacter.NONE),
                 null == alias ? null : new IdentifierValue(alias, 
QuoteCharacter.NONE));
@@ -81,7 +87,28 @@ public final class ColumnProjection implements Projection {
     }
     
     @Override
-    public Projection cloneWithOwner(final IdentifierValue ownerIdentifier) {
-        return new ColumnProjection(ownerIdentifier, nameIdentifier, 
aliasIdentifier);
+    public Projection transformSubqueryProjection(final IdentifierValue 
subqueryTableAlias, final IdentifierValue originalOwner, final IdentifierValue 
originalName) {
+        ColumnProjection result = null == aliasIdentifier ? new 
ColumnProjection(subqueryTableAlias, nameIdentifier, null) : new 
ColumnProjection(subqueryTableAlias, aliasIdentifier, null);
+        result.setOriginalOwner(originalOwner);
+        result.setOriginalName(originalName);
+        return result;
+    }
+    
+    /**
+     * Get original owner.
+     *
+     * @return original owner
+     */
+    public IdentifierValue getOriginalOwner() {
+        return null == originalOwner ? ownerIdentifier : originalOwner;
+    }
+    
+    /**
+     * Get original name.
+     * 
+     * @return original name
+     */
+    public IdentifierValue getOriginalName() {
+        return null == originalName ? nameIdentifier : originalName;
     }
 }
diff --git 
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/projection/impl/DerivedProjection.java
 
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/projection/impl/DerivedProjection.java
index f05b47aaf39..29b2d690fc5 100644
--- 
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/projection/impl/DerivedProjection.java
+++ 
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/projection/impl/DerivedProjection.java
@@ -53,7 +53,8 @@ public final class DerivedProjection implements Projection {
     }
     
     @Override
-    public Projection cloneWithOwner(final IdentifierValue ownerIdentifier) {
-        return new DerivedProjection(expression, alias, 
derivedProjectionSegment);
+    public Projection transformSubqueryProjection(final IdentifierValue 
subqueryTableAlias, final IdentifierValue originalOwner, final IdentifierValue 
originalName) {
+        // TODO replace getAlias with aliasIdentifier
+        return getAlias().isPresent() ? new 
ColumnProjection(subqueryTableAlias, new IdentifierValue(getAlias().get()), 
null) : new DerivedProjection(expression, alias, derivedProjectionSegment);
     }
 }
diff --git 
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/projection/impl/ExpressionProjection.java
 
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/projection/impl/ExpressionProjection.java
index 91ec030aac4..aa28aaa2ab3 100644
--- 
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/projection/impl/ExpressionProjection.java
+++ 
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/projection/impl/ExpressionProjection.java
@@ -50,8 +50,8 @@ public final class ExpressionProjection implements Projection 
{
     }
     
     @Override
-    public Projection cloneWithOwner(final IdentifierValue ownerIdentifier) {
-        // TODO replace column owner when ExpressionProjection contains owner
-        return new ExpressionProjection(expression, alias);
+    public Projection transformSubqueryProjection(final IdentifierValue 
subqueryTableAlias, final IdentifierValue originalOwner, final IdentifierValue 
originalName) {
+        // TODO replace getAlias with aliasIdentifier
+        return getAlias().isPresent() ? new 
ColumnProjection(subqueryTableAlias, new IdentifierValue(getAlias().get()), 
null) : new ExpressionProjection(expression, alias);
     }
 }
diff --git 
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/projection/impl/ParameterMarkerProjection.java
 
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/projection/impl/ParameterMarkerProjection.java
index 3c5609ac769..4f09d7e0c32 100644
--- 
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/projection/impl/ParameterMarkerProjection.java
+++ 
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/projection/impl/ParameterMarkerProjection.java
@@ -58,7 +58,9 @@ public final class ParameterMarkerProjection implements 
Projection {
     }
     
     @Override
-    public Projection cloneWithOwner(final IdentifierValue ownerIdentifier) {
-        return new ParameterMarkerProjection(parameterMarkerIndex, 
parameterMarkerType, alias);
+    public Projection transformSubqueryProjection(final IdentifierValue 
subqueryTableAlias, final IdentifierValue originalOwner, final IdentifierValue 
originalName) {
+        // TODO replace getAlias with aliasIdentifier
+        return getAlias().isPresent() ? new 
ColumnProjection(subqueryTableAlias, new IdentifierValue(getAlias().get()), 
null)
+                : new ParameterMarkerProjection(parameterMarkerIndex, 
parameterMarkerType, alias);
     }
 }
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 f503f04fa32..248413bb463 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
@@ -59,7 +59,7 @@ public final class ShorthandProjection implements Projection {
     
     /**
      * Get owner.
-     *
+     * 
      * @return owner
      */
     public Optional<String> getOwner() {
@@ -82,7 +82,7 @@ public final class ShorthandProjection implements Projection {
     }
     
     @Override
-    public Projection cloneWithOwner(final IdentifierValue ownerIdentifier) {
-        return new ShorthandProjection(ownerIdentifier.getValue(), 
actualColumns);
+    public Projection transformSubqueryProjection(final IdentifierValue 
subqueryTableAlias, final IdentifierValue originalOwner, final IdentifierValue 
originalName) {
+        return new ShorthandProjection(subqueryTableAlias.getValue(), 
actualColumns);
     }
 }
diff --git 
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/projection/impl/SubqueryProjection.java
 
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/projection/impl/SubqueryProjection.java
index b456eb08b61..4771a9c7cd2 100644
--- 
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/projection/impl/SubqueryProjection.java
+++ 
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/projection/impl/SubqueryProjection.java
@@ -64,7 +64,8 @@ public final class SubqueryProjection implements Projection {
     }
     
     @Override
-    public Projection cloneWithOwner(final IdentifierValue ownerIdentifier) {
-        return new SubqueryProjection(expression, projection, alias, 
databaseType);
+    public Projection transformSubqueryProjection(final IdentifierValue 
subqueryTableAlias, final IdentifierValue originalOwner, final IdentifierValue 
originalName) {
+        // TODO replace getAlias with aliasIdentifier
+        return getAlias().isPresent() ? new 
ColumnProjection(subqueryTableAlias, new IdentifierValue(getAlias().get()), 
null) : new SubqueryProjection(expression, projection, alias, databaseType);
     }
 }
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 5b9c6a11f00..80fcb57ef9d 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
@@ -233,14 +233,15 @@ class ProjectionEngineTest {
                 .createProjection(subqueryTableSegment, 
shorthandProjectionSegment);
         assertTrue(actual.isPresent());
         assertThat(actual.get(), instanceOf(ShorthandProjection.class));
-        assertThat(((ShorthandProjection) 
actual.get()).getColumnProjections().size(), is(1));
+        assertThat(((ShorthandProjection) 
actual.get()).getColumnProjections().size(), is(2));
         assertThat(((ShorthandProjection) 
actual.get()).getActualColumns().size(), is(2));
         Collection<ColumnProjection> columnProjections = new LinkedList<>();
         columnProjections.add(new ColumnProjection(null, "name", null));
+        columnProjections.add(new ColumnProjection(null, "leave_date", null));
         assertThat(((ShorthandProjection) 
actual.get()).getColumnProjections(), is(columnProjections));
         Collection<Projection> expectedColumnProjections = new 
LinkedHashSet<>();
         expectedColumnProjections.add(new ColumnProjection(null, "name", 
null));
-        expectedColumnProjections.add(new 
ExpressionProjection("nvl(leave_date, '20991231')", "leave_date"));
+        expectedColumnProjections.add(new ColumnProjection(null, "leave_date", 
null));
         assertThat(((ShorthandProjection) actual.get()).getActualColumns(), 
is(expectedColumnProjections));
     }
     
diff --git 
a/proxy/frontend/type/mysql/src/main/java/org/apache/shardingsphere/proxy/frontend/mysql/command/query/binary/prepare/MySQLComStmtPrepareExecutor.java
 
b/proxy/frontend/type/mysql/src/main/java/org/apache/shardingsphere/proxy/frontend/mysql/command/query/binary/prepare/MySQLComStmtPrepareExecutor.java
index f049bf431b1..cb69cf6a7f6 100644
--- 
a/proxy/frontend/type/mysql/src/main/java/org/apache/shardingsphere/proxy/frontend/mysql/command/query/binary/prepare/MySQLComStmtPrepareExecutor.java
+++ 
b/proxy/frontend/type/mysql/src/main/java/org/apache/shardingsphere/proxy/frontend/mysql/command/query/binary/prepare/MySQLComStmtPrepareExecutor.java
@@ -148,8 +148,9 @@ public final class MySQLComStmtPrepareExecutor implements 
CommandExecutor {
         Collection<MySQLPacket> result = new ArrayList<>(projections.size());
         for (Projection each : projections) {
             // TODO Calculate column definition flag for other projection types
-            if (each instanceof ColumnProjection) {
-                
result.add(Optional.ofNullable(columnToTableMap.get(each.getExpression())).map(schema::getTable).map(table
 -> table.getColumn(((ColumnProjection) each).getName()))
+            if (each instanceof ColumnProjection && null != 
((ColumnProjection) each).getOriginalName()) {
+                
result.add(Optional.ofNullable(columnToTableMap.get(each.getExpression())).map(schema::getTable)
+                        .map(table -> 
table.getColumns().get(((ColumnProjection) each).getOriginalName().getValue()))
                         .map(column -> 
createMySQLColumnDefinition41Packet(characterSet, 
calculateColumnDefinitionFlag(column), 
MySQLBinaryColumnType.valueOfJDBCType(column.getDataType())))
                         .orElseGet(() -> 
createMySQLColumnDefinition41Packet(characterSet, 0, 
MySQLBinaryColumnType.VAR_STRING)));
             } else {
diff --git 
a/test/it/rewriter/src/test/resources/scenario/encrypt/case/query-with-cipher/dml/select/select-subquery.xml
 
b/test/it/rewriter/src/test/resources/scenario/encrypt/case/query-with-cipher/dml/select/select-subquery.xml
index 94b726421b8..52f6d8768cc 100644
--- 
a/test/it/rewriter/src/test/resources/scenario/encrypt/case/query-with-cipher/dml/select/select-subquery.xml
+++ 
b/test/it/rewriter/src/test/resources/scenario/encrypt/case/query-with-cipher/dml/select/select-subquery.xml
@@ -24,32 +24,32 @@
 
     <rewrite-assertion id="select_not_nested_subquery_in_table_segment" 
db-types="MySQL">
         <input sql="SELECT u.amount, u.password, o.certificate_number FROM 
(SELECT certificate_number FROM t_account) o, t_account u WHERE 
o.certificate_number=u.certificate_number AND u.password=?" parameters="1" />
-        <output sql="SELECT u.cipher_amount AS amount, u.cipher_password AS 
password, o.cipher_certificate_number AS certificate_number FROM (SELECT 
cipher_certificate_number, assisted_query_certificate_number FROM t_account) o, 
t_account u WHERE 
o.assisted_query_certificate_number=u.assisted_query_certificate_number AND 
u.assisted_query_password=?" parameters="assisted_query_1" />
+        <output sql="SELECT u.amount, u.password, o.certificate_number FROM 
(SELECT cipher_certificate_number AS certificate_number, 
assisted_query_certificate_number FROM t_account) o, t_account u WHERE 
o.assisted_query_certificate_number=u.assisted_query_certificate_number AND 
u.assisted_query_password=?" parameters="assisted_query_1" />
     </rewrite-assertion>
 
     <rewrite-assertion id="select_not_nested_subquery_in_table_segment_refed" 
db-types="MySQL">
         <input sql="SELECT u.amount, u.password, o.certificate_number FROM 
(SELECT certificate_number FROM t_account_bak) o, t_account u WHERE 
o.certificate_number=u.certificate_number AND u.password=?" parameters="1" />
-        <output sql="SELECT u.cipher_amount AS amount, u.cipher_password AS 
password, o.cipher_certificate_number AS certificate_number FROM (SELECT 
cipher_certificate_number, assisted_query_certificate_number FROM 
t_account_bak) o, t_account u WHERE 
o.assisted_query_certificate_number=u.assisted_query_certificate_number AND 
u.assisted_query_password=?" parameters="assisted_query_1" />
+        <output sql="SELECT u.amount, u.password, o.certificate_number FROM 
(SELECT cipher_certificate_number AS certificate_number, 
assisted_query_certificate_number FROM t_account_bak) o, t_account u WHERE 
o.assisted_query_certificate_number=u.assisted_query_certificate_number AND 
u.assisted_query_password=?" parameters="assisted_query_1" />
     </rewrite-assertion>
 
     <rewrite-assertion id="select_not_nested_subquery_in_table_segment_alias" 
db-types="MySQL">
         <input sql="SELECT o.certificate_number FROM (SELECT 
a.certificate_number FROM t_account a) o" />
-        <output sql="SELECT o.cipher_certificate_number AS certificate_number 
FROM (SELECT a.cipher_certificate_number, a.assisted_query_certificate_number 
FROM t_account a) o" />
+        <output sql="SELECT o.certificate_number FROM (SELECT 
a.cipher_certificate_number AS certificate_number, 
a.assisted_query_certificate_number FROM t_account a) o" />
     </rewrite-assertion>
 
     <rewrite-assertion 
id="select_not_nested_subquery_in_table_segment_with_shorthand_project_alias" 
db-types="MySQL">
         <input sql="SELECT u.amount, u.password, o.certificate_number FROM 
(SELECT a.* FROM t_account a) o, t_account u WHERE 
o.certificate_number=u.certificate_number AND u.password=?" parameters="1" />
-        <output sql="SELECT u.cipher_amount AS amount, u.cipher_password AS 
password, o.cipher_certificate_number AS certificate_number FROM (SELECT 
a.`account_id`, a.`cipher_certificate_number`, 
a.`assisted_query_certificate_number`, a.`cipher_password`, 
a.`assisted_query_password`, a.`cipher_amount` FROM t_account a) o, t_account u 
WHERE o.assisted_query_certificate_number=u.assisted_query_certificate_number 
AND u.assisted_query_password=?" parameters="assisted_query_1" />
+        <output sql="SELECT u.amount, u.password, o.certificate_number FROM 
(SELECT a.`account_id`, a.`cipher_certificate_number` AS `certificate_number`, 
a.`assisted_query_certificate_number`, a.`cipher_password` AS `password`, 
a.`assisted_query_password`, a.`cipher_amount` AS `amount` FROM t_account a) o, 
t_account u WHERE 
o.assisted_query_certificate_number=u.assisted_query_certificate_number AND 
u.assisted_query_password=?" parameters="assisted_query_1" />
     </rewrite-assertion>
 
     <rewrite-assertion 
id="select_not_nested_subquery_in_table_segment_with_shorthand_project_alias_quote"
 db-types="MySQL">
         <input sql="SELECT u.amount, u.password, o.certificate_number FROM 
(SELECT a.* FROM t_account `a`) o, t_account u WHERE 
o.certificate_number=u.certificate_number AND u.password=?" parameters="1" />
-        <output sql="SELECT u.cipher_amount AS amount, u.cipher_password AS 
password, o.cipher_certificate_number AS certificate_number FROM (SELECT 
a.`account_id`, a.`cipher_certificate_number`, 
a.`assisted_query_certificate_number`, a.`cipher_password`, 
a.`assisted_query_password`, a.`cipher_amount` FROM t_account `a`) o, t_account 
u WHERE o.assisted_query_certificate_number=u.assisted_query_certificate_number 
AND u.assisted_query_password=?" parameters="assisted_query_1" />
+        <output sql="SELECT u.amount, u.password, o.certificate_number FROM 
(SELECT a.`account_id`, a.`cipher_certificate_number` AS `certificate_number`, 
a.`assisted_query_certificate_number`, a.`cipher_password` AS `password`, 
a.`assisted_query_password`, a.`cipher_amount` AS `amount` FROM t_account `a`) 
o, t_account u WHERE 
o.assisted_query_certificate_number=u.assisted_query_certificate_number AND 
u.assisted_query_password=?" parameters="assisted_query_1" />
     </rewrite-assertion>
 
     <rewrite-assertion 
id="select_not_nested_subquery_in_table_segment_with_shorthand_project" 
db-types="MySQL">
         <input sql="SELECT u.amount, u.password, o.certificate_number FROM 
(SELECT * FROM t_account) o, t_account u WHERE 
o.certificate_number=u.certificate_number AND u.password=?" parameters="1" />
-        <output sql="SELECT u.cipher_amount AS amount, u.cipher_password AS 
password, o.cipher_certificate_number AS certificate_number FROM (SELECT 
t_account.`account_id`, t_account.`cipher_certificate_number`, 
t_account.`assisted_query_certificate_number`, t_account.`cipher_password`, 
t_account.`assisted_query_password`, t_account.`cipher_amount` FROM t_account) 
o, t_account u WHERE 
o.assisted_query_certificate_number=u.assisted_query_certificate_number AND 
u.assisted_query_password=?" [...]
+        <output sql="SELECT u.amount, u.password, o.certificate_number FROM 
(SELECT t_account.`account_id`, t_account.`cipher_certificate_number` AS 
`certificate_number`, t_account.`assisted_query_certificate_number`, 
t_account.`cipher_password` AS `password`, t_account.`assisted_query_password`, 
t_account.`cipher_amount` AS `amount` FROM t_account) o, t_account u WHERE 
o.assisted_query_certificate_number=u.assisted_query_certificate_number AND 
u.assisted_query_password=?" parameters="as [...]
     </rewrite-assertion>
 
     <rewrite-assertion 
id="select_not_nested_subquery_in_predicate_right_equal_condition" 
db-types="MySQL">
@@ -64,7 +64,7 @@
 
     <rewrite-assertion id="select_not_nested_subquery_in_table_with_alias" 
db-types="MySQL">
         <input sql="SELECT count(*) as cnt FROM (SELECT ab.certificate_number 
FROM t_account ab) X" />
-        <output sql="SELECT count(*) as cnt FROM (SELECT 
ab.cipher_certificate_number, ab.assisted_query_certificate_number FROM 
t_account ab) X" />
+        <output sql="SELECT count(*) as cnt FROM (SELECT 
ab.cipher_certificate_number AS certificate_number, 
ab.assisted_query_certificate_number FROM t_account ab) X" />
     </rewrite-assertion>
 
     <rewrite-assertion 
id="select_not_nested_subquery_in_predicate_left_and_right_equal_condition" 
db-types="MySQL">
@@ -89,12 +89,12 @@
 
     <rewrite-assertion 
id="select_not_nested_subquery_in_tablesegment_from_alias" db-types="MySQL">
         <input sql="SELECT b.certificate_number, b.amount FROM (SELECT 
a.certificate_number as certificate_number, a.amount FROM t_account a WHERE 
a.amount = 1373) b" />
-        <output sql="SELECT b.cipher_certificate_number AS certificate_number, 
b.cipher_amount AS amount FROM (SELECT a.cipher_certificate_number, 
a.assisted_query_certificate_number, a.cipher_amount FROM t_account a WHERE 
a.cipher_amount = 'encrypt_1373') b" />
+        <output sql="SELECT b.certificate_number, b.amount FROM (SELECT 
a.cipher_certificate_number AS certificate_number, 
a.assisted_query_certificate_number, a.cipher_amount AS amount FROM t_account a 
WHERE a.cipher_amount = 'encrypt_1373') b" />
     </rewrite-assertion>
 
     <rewrite-assertion 
id="select_not_nested_subquery_in_tablesegment_ref_shorthand" db-types="MySQL">
         <input sql="SELECT b.* FROM (SELECT a.certificate_number as 
certificate_number, a.amount FROM t_account a WHERE a.amount = 1373) b" />
-        <output sql="SELECT b.cipher_certificate_number AS certificate_number, 
b.cipher_amount AS amount FROM (SELECT a.cipher_certificate_number, 
a.assisted_query_certificate_number, a.cipher_amount FROM t_account a WHERE 
a.cipher_amount = 'encrypt_1373') b" />
+        <output sql="SELECT b.certificate_number, b.amount FROM (SELECT 
a.cipher_certificate_number AS certificate_number, 
a.assisted_query_certificate_number, a.cipher_amount AS amount FROM t_account a 
WHERE a.cipher_amount = 'encrypt_1373') b" />
     </rewrite-assertion>
 
     <rewrite-assertion id="select_with_exists_sub_query" db-types="MySQL">
@@ -104,16 +104,16 @@
 
     <rewrite-assertion id="select_sub_query_with_order_by" db-types="MySQL">
         <input sql="SELECT COUNT(1) AS cnt FROM (SELECT a.amount FROM 
t_account a ORDER BY a.amount DESC ) AS tmp" />
-        <output sql="SELECT COUNT(1) AS cnt FROM (SELECT a.cipher_amount FROM 
t_account a ORDER BY a.cipher_amount DESC ) AS tmp" />
+        <output sql="SELECT COUNT(1) AS cnt FROM (SELECT a.cipher_amount AS 
amount FROM t_account a ORDER BY a.cipher_amount DESC ) AS tmp" />
     </rewrite-assertion>
 
     <rewrite-assertion id="select_shorthand_from_sub_query_with_simple_select" 
db-types="MySQL">
         <input sql="SELECT * FROM (SELECT * FROM t_account a) AS temp" />
-        <output sql="SELECT temp.`account_id`, 
temp.`cipher_certificate_number` AS `certificate_number`, 
temp.`cipher_password` AS `password`, temp.`cipher_amount` AS `amount` FROM 
(SELECT a.`account_id`, a.`cipher_certificate_number`, 
a.`assisted_query_certificate_number`, a.`cipher_password`, 
a.`assisted_query_password`, a.`cipher_amount` FROM t_account a) AS temp" />
+        <output sql="SELECT temp.`account_id`, temp.`certificate_number`, 
temp.`password`, temp.`amount` FROM (SELECT a.`account_id`, 
a.`cipher_certificate_number` AS `certificate_number`, 
a.`assisted_query_certificate_number`, a.`cipher_password` AS `password`, 
a.`assisted_query_password`, a.`cipher_amount` AS `amount` FROM t_account a) AS 
temp" />
     </rewrite-assertion>
 
     <rewrite-assertion id="select_shorthand_from_sub_query_with_select_join" 
db-types="MySQL">
         <input sql="SELECT * FROM (SELECT a1.* FROM t_account a1 INNER JOIN 
t_account a2) AS temp" />
-        <output sql="SELECT temp.`account_id`, 
temp.`cipher_certificate_number` AS `certificate_number`, 
temp.`cipher_password` AS `password`, temp.`cipher_amount` AS `amount` FROM 
(SELECT a1.`account_id`, a1.`cipher_certificate_number`, 
a1.`assisted_query_certificate_number`, a1.`cipher_password`, 
a1.`assisted_query_password`, a1.`cipher_amount` FROM t_account a1 INNER JOIN 
t_account a2) AS temp" />
+        <output sql="SELECT temp.`account_id`, temp.`certificate_number`, 
temp.`password`, temp.`amount` FROM (SELECT a1.`account_id`, 
a1.`cipher_certificate_number` AS `certificate_number`, 
a1.`assisted_query_certificate_number`, a1.`cipher_password` AS `password`, 
a1.`assisted_query_password`, a1.`cipher_amount` AS `amount` FROM t_account a1 
INNER JOIN t_account a2) AS temp" />
     </rewrite-assertion>
 </rewrite-assertions>
diff --git 
a/test/it/rewriter/src/test/resources/scenario/mix/case/query-with-cipher/dml/select/select-subquery.xml
 
b/test/it/rewriter/src/test/resources/scenario/mix/case/query-with-cipher/dml/select/select-subquery.xml
index d36052b2238..866d943f13e 100644
--- 
a/test/it/rewriter/src/test/resources/scenario/mix/case/query-with-cipher/dml/select/select-subquery.xml
+++ 
b/test/it/rewriter/src/test/resources/scenario/mix/case/query-with-cipher/dml/select/select-subquery.xml
@@ -19,25 +19,25 @@
 <rewrite-assertions yaml-rule="scenario/mix/config/query-with-cipher.yaml">
     <rewrite-assertion id="select_not_nested_subquery_in_table_alias" 
db-types="MySQL">
         <input sql="SELECT count(*) as cnt FROM (SELECT ab.password FROM 
t_account ab) X" />
-        <output sql="SELECT count(*) as cnt FROM (SELECT ab.cipher_password, 
ab.assisted_query_password FROM t_account_0 ab) X" />
-        <output sql="SELECT count(*) as cnt FROM (SELECT ab.cipher_password, 
ab.assisted_query_password FROM t_account_1 ab) X" />
+        <output sql="SELECT count(*) as cnt FROM (SELECT ab.cipher_password AS 
password, ab.assisted_query_password FROM t_account_0 ab) X" />
+        <output sql="SELECT count(*) as cnt FROM (SELECT ab.cipher_password AS 
password, ab.assisted_query_password FROM t_account_1 ab) X" />
     </rewrite-assertion>
     
     <rewrite-assertion 
id="select_not_nested_subquery_in_table_segment_with_shorthand_project_alias" 
db-types="MySQL">
         <input sql="SELECT u.amount, u.password, o.certificate_number FROM 
(SELECT a.* FROM t_account a) o, t_account u WHERE 
o.certificate_number=u.certificate_number AND u.password=?" parameters="1" />
-        <output sql="SELECT u.cipher_amount AS amount, u.cipher_password AS 
password, o.certificate_number FROM (SELECT a.`account_id`, 
a.`cipher_password`, a.`assisted_query_password`, a.`cipher_amount` FROM 
t_account_0 a) o, t_account_0 u WHERE o.certificate_number=u.certificate_number 
AND u.assisted_query_password=?" parameters="assisted_query_1" />
-        <output sql="SELECT u.cipher_amount AS amount, u.cipher_password AS 
password, o.certificate_number FROM (SELECT a.`account_id`, 
a.`cipher_password`, a.`assisted_query_password`, a.`cipher_amount` FROM 
t_account_1 a) o, t_account_1 u WHERE o.certificate_number=u.certificate_number 
AND u.assisted_query_password=?" parameters="assisted_query_1" />
+        <output sql="SELECT u.amount, u.password, o.certificate_number FROM 
(SELECT a.`account_id`, a.`cipher_password` AS `password`, 
a.`assisted_query_password`, a.`cipher_amount` AS `amount` FROM t_account_0 a) 
o, t_account_0 u WHERE o.certificate_number=u.certificate_number AND 
u.assisted_query_password=?" parameters="assisted_query_1" />
+        <output sql="SELECT u.amount, u.password, o.certificate_number FROM 
(SELECT a.`account_id`, a.`cipher_password` AS `password`, 
a.`assisted_query_password`, a.`cipher_amount` AS `amount` FROM t_account_1 a) 
o, t_account_1 u WHERE o.certificate_number=u.certificate_number AND 
u.assisted_query_password=?" parameters="assisted_query_1" />
     </rewrite-assertion>
 
     <rewrite-assertion 
id="select_not_nested_subquery_in_table_segment_with_shorthand_project_alias_quote"
 db-types="MySQL">
         <input sql="SELECT u.amount, u.password, o.certificate_number FROM 
(SELECT `a`.* FROM t_account `a`) o, t_account u WHERE 
o.certificate_number=u.certificate_number AND u.password=?" parameters="1" />
-        <output sql="SELECT u.cipher_amount AS amount, u.cipher_password AS 
password, o.certificate_number FROM (SELECT `a`.`account_id`, 
`a`.`cipher_password`, `a`.`assisted_query_password`, `a`.`cipher_amount` FROM 
t_account_0 `a`) o, t_account_0 u WHERE 
o.certificate_number=u.certificate_number AND u.assisted_query_password=?" 
parameters="assisted_query_1" />
-        <output sql="SELECT u.cipher_amount AS amount, u.cipher_password AS 
password, o.certificate_number FROM (SELECT `a`.`account_id`, 
`a`.`cipher_password`, `a`.`assisted_query_password`, `a`.`cipher_amount` FROM 
t_account_1 `a`) o, t_account_1 u WHERE 
o.certificate_number=u.certificate_number AND u.assisted_query_password=?" 
parameters="assisted_query_1" />
+        <output sql="SELECT u.amount, u.password, o.certificate_number FROM 
(SELECT `a`.`account_id`, `a`.`cipher_password` AS `password`, 
`a`.`assisted_query_password`, `a`.`cipher_amount` AS `amount` FROM t_account_0 
`a`) o, t_account_0 u WHERE o.certificate_number=u.certificate_number AND 
u.assisted_query_password=?" parameters="assisted_query_1" />
+        <output sql="SELECT u.amount, u.password, o.certificate_number FROM 
(SELECT `a`.`account_id`, `a`.`cipher_password` AS `password`, 
`a`.`assisted_query_password`, `a`.`cipher_amount` AS `amount` FROM t_account_1 
`a`) o, t_account_1 u WHERE o.certificate_number=u.certificate_number AND 
u.assisted_query_password=?" parameters="assisted_query_1" />
     </rewrite-assertion>
     
     <rewrite-assertion id="select_not_nested_subquery_in_table_segment_alias" 
db-types="MySQL">
         <input sql="SELECT o.password FROM (SELECT a.password FROM t_account 
a) o" />
-        <output sql="SELECT o.cipher_password AS password FROM (SELECT 
a.cipher_password, a.assisted_query_password FROM t_account_0 a) o" />
-        <output sql="SELECT o.cipher_password AS password FROM (SELECT 
a.cipher_password, a.assisted_query_password FROM t_account_1 a) o" />
+        <output sql="SELECT o.password FROM (SELECT a.cipher_password AS 
password, a.assisted_query_password FROM t_account_0 a) o" />
+        <output sql="SELECT o.password FROM (SELECT a.cipher_password AS 
password, a.assisted_query_password FROM t_account_1 a) o" />
     </rewrite-assertion>
 </rewrite-assertions>

Reply via email to