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

panjuan 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 b8db81f  optimize encrypt subquery projection rewrite logic (#13643)
b8db81f is described below

commit b8db81f51e533773a8992c4909cc4f623279a356
Author: Zhengqiang Duan <[email protected]>
AuthorDate: Tue Nov 16 19:07:35 2021 +0800

    optimize encrypt subquery projection rewrite logic (#13643)
    
    * refactor EncryptProjectionTokenGenerator
    
    * refactor EncryptProjectionTokenGenerator
    
    * refactor EncryptProjectionTokenGenerator
    
    * delete useless enum
    
    * delete useless method
    
    * delete useless method
    
    * fix unit test error
    
    * fix integration test error
    
    * modify rewrite test case
---
 .../impl/EncryptPredicateColumnTokenGenerator.java |  15 +-
 .../impl/EncryptProjectionTokenGenerator.java      | 229 +++++++--------------
 .../route/engine/condition/ShardingConditions.java |   5 +-
 .../merge/dql/ShardingDQLResultMergerTest.java     |  10 +-
 .../RowNumberDecoratorMergedResultTest.java        |   7 +-
 .../select/subquery/SubqueryTableContext.java      |  20 +-
 .../engine/SubqueryTableContextEngine.java         |  50 +++++
 .../infra/binder/segment/table/TablesContext.java  |  41 +++-
 .../statement/dml/SelectStatementContext.java      |  40 ++--
 .../binder/statement/dml/SubqueryTableContext.java |  88 --------
 .../sql/common/util/SubqueryExtractUtil.java       |  53 +----
 .../resources/scenario/encrypt/case/insert.xml     |   4 +-
 .../encrypt/case/select_for_query_with_cipher.xml  |  42 ++--
 13 files changed, 248 insertions(+), 356 deletions(-)

diff --git 
a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/impl/EncryptPredicateColumnTokenGenerator.java
 
b/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/impl/EncryptPredicateColumnTokenGenerator.java
index c9a1af0..2f4e450 100644
--- 
a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/impl/EncryptPredicateColumnTokenGenerator.java
+++ 
b/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/impl/EncryptPredicateColumnTokenGenerator.java
@@ -25,7 +25,6 @@ import 
org.apache.shardingsphere.infra.binder.segment.select.projection.impl.Col
 import org.apache.shardingsphere.infra.binder.statement.SQLStatementContext;
 import 
org.apache.shardingsphere.infra.binder.statement.dml.InsertStatementContext;
 import 
org.apache.shardingsphere.infra.binder.statement.dml.SelectStatementContext;
-import 
org.apache.shardingsphere.infra.binder.statement.dml.SubqueryTableContext;
 import org.apache.shardingsphere.infra.binder.type.WhereAvailable;
 import org.apache.shardingsphere.infra.metadata.schema.ShardingSphereSchema;
 import 
org.apache.shardingsphere.infra.rewrite.sql.token.generator.CollectionSQLTokenGenerator;
@@ -76,28 +75,22 @@ public final class EncryptPredicateColumnTokenGenerator 
extends BaseEncryptSQLTo
             Collection<AndPredicate> andPredicates = 
ExpressionExtractUtil.getAndPredicates(each.getExpr());
             Map<String, String> columnTableNames = 
getColumnTableNames(sqlStatementContext, andPredicates);
             for (AndPredicate predicate : andPredicates) {
-                result.addAll(generateSQLTokens(sqlStatementContext, 
predicate.getPredicates(), columnTableNames));
+                result.addAll(generateSQLTokens(predicate.getPredicates(), 
columnTableNames));
             }
         }
         return result;
     }
 
-    private Collection<SubstitutableColumnNameToken> generateSQLTokens(final 
SQLStatementContext sqlStatementContext, final Collection<ExpressionSegment> 
predicates,
-                                                                       final 
Map<String, String> columnTableNames) {
+    private Collection<SubstitutableColumnNameToken> generateSQLTokens(final 
Collection<ExpressionSegment> predicates, final Map<String, String> 
columnTableNames) {
         Collection<SubstitutableColumnNameToken> result = new LinkedList<>();
-        SubqueryTableContext subqueryTableContext = new SubqueryTableContext();
-        if (sqlStatementContext instanceof SelectStatementContext) {
-            subqueryTableContext = ((SelectStatementContext) 
sqlStatementContext).getSubqueryTableContext();
-        }
         for (ExpressionSegment each : predicates) {
             for (ColumnSegment column : ColumnExtractor.extract(each)) {
-                int startIndex = column.getOwner().isPresent() ? 
column.getOwner().get().getStopIndex() + 2 : column.getStartIndex();
-                int stopIndex = column.getStopIndex();
-                
subqueryTableContext.getAssistedQueryColumn(column).ifPresent(item -> 
result.add(new SubstitutableColumnNameToken(startIndex, stopIndex, 
getColumnProjections(item))));
                 Optional<EncryptTable> encryptTable = 
findEncryptTable(columnTableNames, column);
                 if (!encryptTable.isPresent() || 
!encryptTable.get().findEncryptorName(column.getIdentifier().getValue()).isPresent())
 {
                     continue;
                 }
+                int startIndex = column.getOwner().isPresent() ? 
column.getOwner().get().getStopIndex() + 2 : column.getStartIndex();
+                int stopIndex = column.getStopIndex();
                 EncryptTable table = encryptTable.get();
                 if (Boolean.FALSE.equals(table.getQueryWithCipherColumn()) || 
!queryWithCipherColumn) {
                     Optional<String> plainColumn = 
encryptTable.get().findPlainColumn(column.getIdentifier().getValue());
diff --git 
a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/impl/EncryptProjectionTokenGenerator.java
 
b/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/impl/EncryptProjectionTokenGenerator.java
index df3ac6f..71e195b 100644
--- 
a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/impl/EncryptProjectionTokenGenerator.java
+++ 
b/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/impl/EncryptProjectionTokenGenerator.java
@@ -26,24 +26,20 @@ import 
org.apache.shardingsphere.infra.binder.segment.select.projection.Projecti
 import 
org.apache.shardingsphere.infra.binder.segment.select.projection.ProjectionsContext;
 import 
org.apache.shardingsphere.infra.binder.segment.select.projection.impl.ColumnProjection;
 import 
org.apache.shardingsphere.infra.binder.segment.select.projection.impl.ShorthandProjection;
+import org.apache.shardingsphere.infra.binder.segment.table.TablesContext;
 import org.apache.shardingsphere.infra.binder.statement.SQLStatementContext;
 import 
org.apache.shardingsphere.infra.binder.statement.dml.InsertStatementContext;
 import 
org.apache.shardingsphere.infra.binder.statement.dml.SelectStatementContext;
-import 
org.apache.shardingsphere.infra.binder.statement.dml.SubqueryTableContext;
 import org.apache.shardingsphere.infra.database.type.DatabaseType;
 import 
org.apache.shardingsphere.infra.rewrite.sql.token.generator.CollectionSQLTokenGenerator;
 import 
org.apache.shardingsphere.infra.rewrite.sql.token.generator.aware.PreviousSQLTokensAware;
 import org.apache.shardingsphere.infra.rewrite.sql.token.pojo.SQLToken;
 import 
org.apache.shardingsphere.infra.rewrite.sql.token.pojo.generic.SubstitutableColumnNameToken;
 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;
-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.OwnerSegment;
-import 
org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.SubqueryTableSegment;
-import 
org.apache.shardingsphere.sql.parser.sql.common.util.SubqueryExtractUtil;
 
 import java.util.Collection;
 import java.util.Collections;
@@ -51,11 +47,11 @@ import java.util.LinkedHashSet;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Optional;
-import java.util.stream.Collectors;
 
 /**
  * Projection token generator for encrypt.
  */
+@SuppressWarnings("rawtypes")
 @Setter
 public final class EncryptProjectionTokenGenerator extends 
BaseEncryptSQLTokenGenerator 
         implements CollectionSQLTokenGenerator<SQLStatementContext>, 
QueryWithCipherColumnAware, PreviousSQLTokensAware {
@@ -75,90 +71,106 @@ public final class EncryptProjectionTokenGenerator extends 
BaseEncryptSQLTokenGe
     @Override
     public Collection<SubstitutableColumnNameToken> generateSQLTokens(final 
SQLStatementContext sqlStatementContext) {
         Collection<SubstitutableColumnNameToken> result = new 
LinkedHashSet<>();
-        SubqueryTableContext subqueryTableContext = new SubqueryTableContext();
         if (sqlStatementContext instanceof InsertStatementContext) {
-            result.addAll(generateSQLTokens(((InsertStatementContext) 
sqlStatementContext).getInsertSelectContext().getSelectStatementContext(), 
Optional.empty(), SubqueryEnum.INSERT_SELECT,
-                    subqueryTableContext));
+            SelectStatementContext selectStatementContext = 
((InsertStatementContext) 
sqlStatementContext).getInsertSelectContext().getSelectStatementContext();
+            result.addAll(generateSQLTokens(selectStatementContext));
         }
         if (sqlStatementContext instanceof SelectStatementContext) {
             SelectStatementContext selectStatementContext = 
(SelectStatementContext) sqlStatementContext;
-            result.addAll(generateSQLTokens(selectStatementContext, 
subqueryTableContext));
-            result.addAll(generateSQLTokens(selectStatementContext, 
Optional.empty(), SubqueryEnum.NONE, subqueryTableContext));
-        }
-        return result;
-    }
-    
-    private Collection<SubstitutableColumnNameToken> generateSQLTokens(final 
SelectStatementContext selectStatementContext, final SubqueryTableContext 
subqueryTableContext) {
-        if (!selectStatementContext.isContainsSubquery()) {
-            return Collections.emptyList();
+            result.addAll(generateProjectionSQLTokens(selectStatementContext));
+            for (SelectStatementContext each : 
selectStatementContext.getSubqueryContexts().values()) {
+                result.addAll(generateProjectionSQLTokens(each));
+            }
         }
-        Collection<SubstitutableColumnNameToken> result = new LinkedList<>();
-        
result.addAll(SubqueryExtractUtil.getSubqueryTableSegmentsFromTableSegment(selectStatementContext.getSqlStatement().getFrom()).stream().map(
-            each -> generateSQLTokens(selectStatementContext, each, 
subqueryTableContext)).flatMap(Collection::stream).collect(Collectors.toList()));
-        
result.addAll(SubqueryExtractUtil.getSubquerySegmentsFromProjections(selectStatementContext.getSqlStatement().getProjections()).stream().map(
-            each -> generateSQLTokens(selectStatementContext, each, 
SubqueryEnum.PROJECTION, 
subqueryTableContext)).flatMap(Collection::stream).collect(Collectors.toList()));
-        selectStatementContext.getWhere().ifPresent(where -> 
result.addAll(SubqueryExtractUtil.getSubquerySegmentsFromExpression(where.getExpr()).stream().map(
-            each -> generateSQLTokens(selectStatementContext, each, 
SubqueryEnum.EXPRESSION, 
subqueryTableContext)).flatMap(Collection::stream).collect(Collectors.toList())));
         return result;
     }
     
-    private Collection<SubstitutableColumnNameToken> generateSQLTokens(final 
SelectStatementContext selectStatementContext, final SubquerySegment 
subquerySegment, 
-                                                                       final 
SubqueryEnum subqueryEnum, final SubqueryTableContext subqueryTableContext) {
-        return generateSQLTokens(new 
SelectStatementContext(selectStatementContext.getMetaDataMap(), 
selectStatementContext.getParameters(), subquerySegment.getSelect(),
-                   selectStatementContext.getSchemaName()), Optional.empty(), 
subqueryEnum, subqueryTableContext);
-    }
-    
-    private Collection<SubstitutableColumnNameToken> generateSQLTokens(final 
SelectStatementContext selectStatementContext, final SubqueryTableSegment 
subqueryTableSegment, 
-                                                                       final 
SubqueryTableContext subqueryTableContext) {
-        return generateSQLTokens(new 
SelectStatementContext(selectStatementContext.getMetaDataMap(), 
selectStatementContext.getParameters(), 
subqueryTableSegment.getSubquery().getSelect(),
-                   selectStatementContext.getSchemaName()), 
subqueryTableSegment.getAlias(), SubqueryEnum.NESTED_PROJECTION_TABLE_SEGMENT, 
subqueryTableContext);
-    }
-
-    private Collection<SubstitutableColumnNameToken> generateSQLTokens(final 
SelectStatementContext selectStatementContext, final Optional<String> alias,
-                                                                       final 
SubqueryEnum subqueryEnum, final SubqueryTableContext subqueryTableContext) {
+    private Collection<SubstitutableColumnNameToken> 
generateProjectionSQLTokens(final SelectStatementContext 
selectStatementContext) {
         Collection<SubstitutableColumnNameToken> result = new 
LinkedHashSet<>();
-        ProjectionsSegment projectionsSegment = 
selectStatementContext.getSqlStatement().getProjections();
         for (String each : 
selectStatementContext.getTablesContext().getTableNames()) {
-            getEncryptRule().findEncryptTable(each).map(optional -> 
generateSQLTokens(projectionsSegment, each, selectStatementContext, optional, 
alias, subqueryEnum,
-                    subqueryTableContext)).ifPresent(result::addAll);
+            Optional<EncryptTable> encryptTable = 
getEncryptRule().findEncryptTable(each);
+            if (!encryptTable.isPresent()) {
+                continue;
+            }
+            result.addAll(generateProjectionSQLTokens(selectStatementContext, 
encryptTable.get(), each));
         }
-        selectStatementContext.setSubqueryTableContext(subqueryTableContext);
         return result;
     }
     
-    private Collection<SubstitutableColumnNameToken> generateSQLTokens(final 
ProjectionsSegment segment, final String tableName, final 
SelectStatementContext selectStatementContext,
-            final EncryptTable encryptTable, final Optional<String> alias, 
final SubqueryEnum subqueryEnum, final SubqueryTableContext 
subqueryTableContext) {
+    private Collection<SubstitutableColumnNameToken> 
generateProjectionSQLTokens(final SelectStatementContext 
selectStatementContext, 
+                                                                               
  final EncryptTable encryptTable, final String tableName) {
         Collection<SubstitutableColumnNameToken> result = new LinkedList<>();
-        for (ProjectionSegment each : segment.getProjections()) {
+        boolean subqueryTable = selectStatementContext.isSubqueryTable();
+        for (ProjectionSegment each : 
selectStatementContext.getSqlStatement().getProjections().getProjections()) {
             if (each instanceof ColumnProjectionSegment) {
-                if (!subqueryTableContext.isEmpty() && 
((ColumnProjectionSegment) each).getColumn().getOwner().isPresent()) {
-                    result.addAll(generateSQLTokens(each, 
subqueryTableContext));
+                String columnName = ((ColumnProjectionSegment) 
each).getColumn().getIdentifier().getValue();
+                Optional<String> owner = ((ColumnProjectionSegment) 
each).getColumn().getOwner().map(optional -> 
optional.getIdentifier().getValue());
+                if 
(selectStatementContext.getTablesContext().findTableNameFromSubquery(columnName,
 owner.orElse(null)).isPresent()) {
+                    
result.addAll(generateProjectionSQLTokens((ColumnProjectionSegment) each, 
selectStatementContext.getTablesContext()));
                 }
-                if 
(encryptTable.getLogicColumns().contains(((ColumnProjectionSegment) 
each).getColumn().getIdentifier().getValue())
+                if (encryptTable.getLogicColumns().contains(columnName)
                         && 
columnMatchTableAndCheckAmbiguous(selectStatementContext, 
(ColumnProjectionSegment) each, tableName)) {
-                    result.add(generateSQLToken((ColumnProjectionSegment) 
each, tableName, alias, subqueryEnum, subqueryTableContext));
+                    
result.add(generateProjectionSQLTokens((ColumnProjectionSegment) each, 
tableName, subqueryTable));
                 }
             }
             if (isToGeneratedSQLToken(each, selectStatementContext, 
tableName)) {
                 ShorthandProjection shorthandProjection = 
getShorthandProjection((ShorthandProjectionSegment) each, 
selectStatementContext.getProjectionsContext());
                 if (!shorthandProjection.getActualColumns().isEmpty()) {
-                    result.add(generateSQLToken((ShorthandProjectionSegment) 
each, shorthandProjection, tableName, encryptTable, 
selectStatementContext.getDatabaseType(), subqueryEnum));
+                    
result.add(generateProjectionSQLTokens((ShorthandProjectionSegment) each, 
shorthandProjection, 
+                            tableName, encryptTable, 
selectStatementContext.getDatabaseType(), subqueryTable));
                 }
             }
         }
         return result;
     }
 
-    private Collection<SubstitutableColumnNameToken> generateSQLTokens(final 
ProjectionSegment each, final SubqueryTableContext subqueryTableContext) {
-        Collection<SubstitutableColumnNameToken> result = new LinkedList<>();
-        ColumnSegment column = ((ColumnProjectionSegment) each).getColumn();
-        int startIndex = column.getOwner().isPresent() ? 
column.getOwner().get().getStopIndex() + 2 : column.getStartIndex();
-        int stopIndex = column.getStopIndex();
-        subqueryTableContext.getCipherColumn(column).ifPresent(item -> 
-            result.add(new SubstitutableColumnNameToken(startIndex, stopIndex, 
getColumnProjections(item, column.getIdentifier().getValue()))));
-        return result;
+    private Collection<SubstitutableColumnNameToken> 
generateProjectionSQLTokens(final ColumnProjectionSegment segment, final 
TablesContext tablesContext) {
+        ColumnSegment column = segment.getColumn();
+        String columnName = column.getIdentifier().getValue();
+        String owner = column.getOwner().map(optional -> 
optional.getIdentifier().getValue()).orElse(null);
+        Optional<String> tableName = 
tablesContext.findTableNameFromSubquery(columnName, owner);
+        if (tableName.isPresent()) {
+            String cipherColumn = 
getEncryptRule().getCipherColumn(tableName.get(), columnName);
+            int startIndex = column.getOwner().isPresent() ? 
column.getOwner().get().getStopIndex() + 2 : column.getStartIndex();
+            int stopIndex = column.getStopIndex();
+            return Collections.singletonList(new 
SubstitutableColumnNameToken(startIndex, stopIndex, 
Collections.singletonList(new ColumnProjection(null, cipherColumn, 
columnName))));
+        }
+        return Collections.emptyList();
     }
 
+    private SubstitutableColumnNameToken generateProjectionSQLTokens(final 
ColumnProjectionSegment segment, final String tableName, final boolean 
subqueryTable) {
+        Collection<ColumnProjection> projections = new LinkedList<>();
+        String encryptColumnName = getEncryptColumnName(tableName, 
segment.getColumn().getIdentifier().getValue());
+        String alias = 
segment.getAlias().orElse(segment.getColumn().getIdentifier().getValue());
+        projections.add(new ColumnProjection(null, encryptColumnName, alias));
+        Optional<String> assistedQueryColumn = 
findAssistedQueryColumn(tableName, 
segment.getColumn().getIdentifier().getValue());
+        if (subqueryTable && assistedQueryColumn.isPresent()) {
+            projections.add(new ColumnProjection(null, 
assistedQueryColumn.get(), null));
+        }
+        return segment.getColumn().getOwner().isPresent()
+                ? new 
SubstitutableColumnNameToken(segment.getColumn().getOwner().get().getStopIndex()
 + 2, segment.getStopIndex(), projections)
+                : new SubstitutableColumnNameToken(segment.getStartIndex(), 
segment.getStopIndex(), projections);
+    }
+    
+    private SubstitutableColumnNameToken generateProjectionSQLTokens(final 
ShorthandProjectionSegment segment, final ShorthandProjection 
shorthandProjection, 
+                                                                     final 
String tableName, final EncryptTable encryptTable, final DatabaseType 
databaseType, final boolean subqueryTable) {
+        List<ColumnProjection> projections = new LinkedList<>();
+        for (ColumnProjection each : 
shorthandProjection.getActualColumns().values()) {
+            if (encryptTable.getLogicColumns().contains(each.getName())) {
+                String owner = null == each.getOwner() ? null : 
each.getOwner();
+                projections.add(new ColumnProjection(owner, 
getEncryptColumnName(tableName, each.getName()), each.getName()));
+                Optional<String> assistedQueryColumn = 
findAssistedQueryColumn(tableName, each.getName());
+                if (subqueryTable && assistedQueryColumn.isPresent()) {
+                    projections.add(new ColumnProjection(owner, 
assistedQueryColumn.get(), null));
+                }
+            } else {
+                projections.add(new ColumnProjection(each.getOwner(), 
each.getName(), each.getAlias().orElse(null)));
+            }
+        }
+        previousSQLTokens.removeIf(each -> each.getStartIndex() == 
segment.getStartIndex());
+        return new SubstitutableColumnNameToken(segment.getStartIndex(), 
segment.getStopIndex(), projections, databaseType.getQuoteCharacter());
+    }
+    
     private boolean columnMatchTableAndCheckAmbiguous(final 
SelectStatementContext selectStatementContext, final ColumnProjectionSegment 
columnProjectionSegment, final String tableName) {
         return isOwnerExistsMatchTableAlias(selectStatementContext, 
columnProjectionSegment, tableName) 
                 || isOwnerExistsMatchTableName(selectStatementContext, 
columnProjectionSegment, tableName) 
@@ -204,106 +216,7 @@ public final class EncryptProjectionTokenGenerator 
extends BaseEncryptSQLTokenGe
         Optional<OwnerSegment> ownerSegment = ((ShorthandProjectionSegment) 
projectionSegment).getOwner();
         return ownerSegment.map(segment -> 
selectStatementContext.getTablesContext().findTableNameFromSQL(segment.getIdentifier().getValue()).orElse("").equalsIgnoreCase(tableName)).orElse(true);
     }
-
-    private SubstitutableColumnNameToken generateSQLToken(final 
ColumnProjectionSegment segment, final String tableName, final Optional<String> 
alias, final SubqueryEnum subqueryEnum,
-                                                          final 
SubqueryTableContext subqueryTableContext) {
-        String encryptColumnName = getEncryptColumnName(tableName, 
segment.getColumn().getIdentifier().getValue());
-        Collection<ColumnProjection> projections = 
getColumnProjections(segment, tableName, alias, encryptColumnName, subqueryEnum,
-                subqueryTableContext);
-        return segment.getColumn().getOwner().isPresent()
-                ? new 
SubstitutableColumnNameToken(segment.getColumn().getOwner().get().getStopIndex()
 + 2, segment.getStopIndex(), projections)
-                : new SubstitutableColumnNameToken(segment.getStartIndex(), 
segment.getStopIndex(), projections);
-    }
     
-    private SubstitutableColumnNameToken generateSQLToken(final 
ShorthandProjectionSegment segment, final ShorthandProjection 
shorthandProjection, final String tableName,
-                                                          final EncryptTable 
encryptTable, final DatabaseType databaseType, final SubqueryEnum subqueryEnum) 
{
-        List<ColumnProjection> projections = new LinkedList<>();
-        for (ColumnProjection each : 
shorthandProjection.getActualColumns().values()) {
-            if (encryptTable.getLogicColumns().contains(each.getName())) {
-                projections.addAll(getShorthandProjectionForSubquery(each, 
tableName, subqueryEnum));
-            } else {
-                projections.add(columnProjection(each, each.getName(), null));
-            }
-        }
-        previousSQLTokens.removeIf(each -> each.getStartIndex() == 
segment.getStartIndex());
-        return new SubstitutableColumnNameToken(segment.getStartIndex(), 
segment.getStopIndex(), projections, databaseType.getQuoteCharacter());
-    }
-
-    private Collection<ColumnProjection> getColumnProjections(final 
ColumnProjectionSegment segment, final String tableName, final Optional<String> 
alias, final String encryptColumnName,
-                                                              final 
SubqueryEnum subqueryEnum, final SubqueryTableContext subqueryTableContext) {
-        Collection<ColumnProjection> result = new LinkedList<>();
-        if (SubqueryEnum.INSERT_SELECT.equals(subqueryEnum)) {
-            result.addAll(getColumnProjectionsForInsertSelect(segment, 
tableName, encryptColumnName));
-        }
-        if (SubqueryEnum.PROJECTION.equals(subqueryEnum)) {
-            result.add(columnProjection(null, encryptColumnName, null));
-        }
-        if (SubqueryEnum.NESTED_PROJECTION_TABLE_SEGMENT.equals(subqueryEnum)) 
{
-            result.add(columnProjection(null, encryptColumnName, null));
-            
result.addAll(getColumnProjectionsForSubqueryProjectionOrTabSegment(segment, 
tableName, alias, subqueryTableContext));
-        }
-        if (SubqueryEnum.EXPRESSION.equals(subqueryEnum)) {
-            result.addAll(getColumnProjectionsForInExpression(segment, 
tableName));
-        }
-        if (SubqueryEnum.NONE.equals(subqueryEnum)) {
-            result.add(columnProjection(null, encryptColumnName, 
segment.getAlias().orElse(segment.getColumn().getIdentifier().getValue())));
-        }
-        return result;
-    }
-
-    private Collection<ColumnProjection> getColumnProjections(final String 
columnName, final String alias) {
-        return Collections.singletonList(new ColumnProjection(null, 
columnName, alias));
-    }
-
-    private Collection<ColumnProjection> 
getColumnProjectionsForInsertSelect(final ColumnProjectionSegment segment, 
final String tableName, final String encryptColumnName) {
-        Collection<ColumnProjection> result = new LinkedList<>();
-        result.add(columnProjection(null, encryptColumnName, null));
-        assistedQueryColumnProjection(segment, 
tableName).ifPresent(result::add);
-        plainColumnProjection(segment, tableName).ifPresent(result::add);
-        return result;
-    }
-
-    private Collection<ColumnProjection> 
getColumnProjectionsForInExpression(final ColumnProjectionSegment segment, 
final String tableName) {
-        Collection<ColumnProjection> result = new LinkedList<>();
-        assistedQueryColumnProjection(segment, 
tableName).ifPresent(result::add);
-        return result;
-    }
-
-    private Collection<ColumnProjection> 
getColumnProjectionsForSubqueryProjectionOrTabSegment(final 
ColumnProjectionSegment segment, final String tableName, final Optional<String> 
alias, 
-                                                                               
                final SubqueryTableContext subqueryTableContext) {
-        Collection<ColumnProjection> result = new LinkedList<>();
-        String plainColumn = segment.getColumn().getIdentifier().getValue();
-        Optional<String> assistedQueryColumn = 
findAssistedQueryColumn(tableName, plainColumn);
-        assistedQueryColumn.ifPresent(each -> result.add(new 
ColumnProjection(null, assistedQueryColumn.get(), null)));
-        subqueryTableContext.put(alias, plainColumn, 
getEncryptColumnName(tableName, plainColumn), assistedQueryColumn);
-        return result;
-    }
-
-    private Collection<ColumnProjection> 
getShorthandProjectionForSubquery(final ColumnProjection each, final String 
tableName, final SubqueryEnum subqueryKind) {
-        Collection<ColumnProjection> result = new LinkedList<>();
-        if (SubqueryEnum.PROJECTION.equals(subqueryKind)) {
-            result.add(columnProjection(each, getEncryptColumnName(tableName, 
each.getName()), null));
-            result.add(columnProjection(each, 
findAssistedQueryColumn(tableName, each.getName()).get(), null));
-        } else {
-            result.add(columnProjection(each, getEncryptColumnName(tableName, 
each.getName()), each.getName()));
-        }
-        return result;
-    }
-
-    private Optional<ColumnProjection> assistedQueryColumnProjection(final 
ColumnProjectionSegment segment, final String tableName) {
-        Optional<String> assistedQueryColumn = 
findAssistedQueryColumn(tableName, 
segment.getColumn().getIdentifier().getValue());
-        return assistedQueryColumn.isPresent() ? Optional.of(new 
ColumnProjection(null, assistedQueryColumn.get(), null)) : Optional.empty();
-    }
-
-    private Optional<ColumnProjection> plainColumnProjection(final 
ColumnProjectionSegment segment, final String tableName) {
-        Optional<String> plainColumn = 
getEncryptRule().findPlainColumn(tableName, 
segment.getColumn().getIdentifier().getValue());
-        return plainColumn.isPresent() ? Optional.of(new 
ColumnProjection(null, plainColumn.get(), null)) : Optional.empty();
-    }
-
-    private ColumnProjection columnProjection(final ColumnProjection each, 
final String columnName, final String alias) {
-        return new ColumnProjection((each == null || null == each.getOwner()) 
? null : each.getOwner(), columnName, alias);
-    }
-
     private Optional<String> findAssistedQueryColumn(final String tableName, 
final String logicEncryptColumnName) {
         Optional<String> plainColumn = 
getEncryptRule().findPlainColumn(tableName, logicEncryptColumnName);
         return plainColumn.isPresent() && !queryWithCipherColumn ? plainColumn 
: getEncryptRule().findAssistedQueryColumn(tableName, logicEncryptColumnName);
diff --git 
a/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-core/src/main/java/org/apache/shardingsphere/sharding/route/engine/condition/ShardingConditions.java
 
b/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-core/src/main/java/org/apache/shardingsphere/sharding/route/engine/condition/ShardingConditions.java
index b1a413e..58c91ce 100644
--- 
a/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-core/src/main/java/org/apache/shardingsphere/sharding/route/engine/condition/ShardingConditions.java
+++ 
b/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-core/src/main/java/org/apache/shardingsphere/sharding/route/engine/condition/ShardingConditions.java
@@ -30,7 +30,6 @@ import 
org.apache.shardingsphere.sharding.route.engine.condition.value.ShardingC
 import org.apache.shardingsphere.sharding.rule.BindingTableRule;
 import org.apache.shardingsphere.sharding.rule.ShardingRule;
 import org.apache.shardingsphere.sharding.rule.TableRule;
-import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.subquery.SubquerySegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.SubqueryTableSegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.statement.dml.SelectStatement;
 import 
org.apache.shardingsphere.sql.parser.sql.common.util.SafeNumberOperationUtil;
@@ -137,12 +136,12 @@ public final class ShardingConditions {
         Collection<SelectStatement> result = new LinkedList<>();
         if (sqlStatementContext instanceof SelectStatementContext) {
             result.add(((SelectStatementContext) 
sqlStatementContext).getSqlStatement());
-            result.addAll(((SelectStatementContext) 
sqlStatementContext).getSubquerySegments().stream().map(SubquerySegment::getSelect).collect(Collectors.toList()));
+            result.addAll(((SelectStatementContext) 
sqlStatementContext).getSubqueryContexts().values().stream().map(SelectStatementContext::getSqlStatement).collect(Collectors.toList()));
         }
         if (sqlStatementContext instanceof InsertStatementContext && null != 
((InsertStatementContext) sqlStatementContext).getInsertSelectContext()) {
             SelectStatementContext selectStatementContext = 
((InsertStatementContext) 
sqlStatementContext).getInsertSelectContext().getSelectStatementContext();
             result.add(selectStatementContext.getSqlStatement());
-            
result.addAll(selectStatementContext.getSubquerySegments().stream().map(SubquerySegment::getSelect).collect(Collectors.toList()));
+            
result.addAll(selectStatementContext.getSubqueryContexts().values().stream().map(SelectStatementContext::getSqlStatement).collect(Collectors.toList()));
         }
         return result;
     }
diff --git 
a/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-core/src/test/java/org/apache/shardingsphere/sharding/merge/dql/ShardingDQLResultMergerTest.java
 
b/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-core/src/test/java/org/apache/shardingsphere/sharding/merge/dql/ShardingDQLResultMergerTest.java
index 1b41e46..418e876 100644
--- 
a/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-core/src/test/java/org/apache/shardingsphere/sharding/merge/dql/ShardingDQLResultMergerTest.java
+++ 
b/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-core/src/test/java/org/apache/shardingsphere/sharding/merge/dql/ShardingDQLResultMergerTest.java
@@ -129,7 +129,7 @@ public final class ShardingDQLResultMergerTest {
         when(whereSegment.getExpr()).thenReturn(binaryOperationExpression);
         SubqueryTableSegment subqueryTableSegment = 
mock(SubqueryTableSegment.class);
         SubquerySegment subquerySegment = mock(SubquerySegment.class);
-        SelectStatement subSelectStatement = mock(SelectStatement.class);
+        SelectStatement subSelectStatement = mock(MySQLSelectStatement.class);
         ProjectionsSegment subProjectionsSegment = 
mock(ProjectionsSegment.class);
         TopProjectionSegment topProjectionSegment = 
mock(TopProjectionSegment.class);
         when(topProjectionSegment.getAlias()).thenReturn("row_id");
@@ -202,7 +202,7 @@ public final class ShardingDQLResultMergerTest {
         when(whereSegment.getExpr()).thenReturn(binaryOperationExpression);
         SubqueryTableSegment subqueryTableSegment = 
mock(SubqueryTableSegment.class);
         SubquerySegment subquerySegment = mock(SubquerySegment.class);
-        SelectStatement subSelectStatement = mock(SelectStatement.class);
+        SelectStatement subSelectStatement = mock(MySQLSelectStatement.class);
         ProjectionsSegment subProjectionsSegment = 
mock(ProjectionsSegment.class);
         TopProjectionSegment topProjectionSegment = 
mock(TopProjectionSegment.class);
         when(topProjectionSegment.getAlias()).thenReturn("row_id");
@@ -281,7 +281,7 @@ public final class ShardingDQLResultMergerTest {
         when(whereSegment.getExpr()).thenReturn(binaryOperationExpression);
         SubqueryTableSegment subqueryTableSegment = 
mock(SubqueryTableSegment.class);
         SubquerySegment subquerySegment = mock(SubquerySegment.class);
-        SelectStatement subSelectStatement = mock(SelectStatement.class);
+        SelectStatement subSelectStatement = mock(MySQLSelectStatement.class);
         ProjectionsSegment subProjectionsSegment = 
mock(ProjectionsSegment.class);
         TopProjectionSegment topProjectionSegment = 
mock(TopProjectionSegment.class);
         when(topProjectionSegment.getAlias()).thenReturn("row_id");
@@ -360,7 +360,7 @@ public final class ShardingDQLResultMergerTest {
         when(whereSegment.getExpr()).thenReturn(binaryOperationExpression);
         SubqueryTableSegment subqueryTableSegment = 
mock(SubqueryTableSegment.class);
         SubquerySegment subquerySegment = mock(SubquerySegment.class);
-        SelectStatement subSelectStatement = mock(SelectStatement.class);
+        SelectStatement subSelectStatement = mock(MySQLSelectStatement.class);
         ProjectionsSegment subProjectionsSegment = 
mock(ProjectionsSegment.class);
         TopProjectionSegment topProjectionSegment = 
mock(TopProjectionSegment.class);
         when(topProjectionSegment.getAlias()).thenReturn("row_id");
@@ -443,7 +443,7 @@ public final class ShardingDQLResultMergerTest {
         when(whereSegment.getExpr()).thenReturn(binaryOperationExpression);
         SubqueryTableSegment subqueryTableSegment = 
mock(SubqueryTableSegment.class);
         SubquerySegment subquerySegment = mock(SubquerySegment.class);
-        SelectStatement subSelectStatement = mock(SelectStatement.class);
+        SelectStatement subSelectStatement = mock(MySQLSelectStatement.class);
         ProjectionsSegment subProjectionsSegment = 
mock(ProjectionsSegment.class);
         TopProjectionSegment topProjectionSegment = 
mock(TopProjectionSegment.class);
         when(topProjectionSegment.getAlias()).thenReturn("row_id");
diff --git 
a/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-core/src/test/java/org/apache/shardingsphere/sharding/merge/dql/pagination/RowNumberDecoratorMergedResultTest.java
 
b/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-core/src/test/java/org/apache/shardingsphere/sharding/merge/dql/pagination/RowNumberDecoratorMergedResultTest.java
index ebef116..3277799 100644
--- 
a/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-core/src/test/java/org/apache/shardingsphere/sharding/merge/dql/pagination/RowNumberDecoratorMergedResultTest.java
+++ 
b/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-core/src/test/java/org/apache/shardingsphere/sharding/merge/dql/pagination/RowNumberDecoratorMergedResultTest.java
@@ -35,6 +35,7 @@ import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.predicate.Whe
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.SubqueryTableSegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.statement.dml.SelectStatement;
 import 
org.apache.shardingsphere.sql.parser.sql.common.value.identifier.IdentifierValue;
+import 
org.apache.shardingsphere.sql.parser.sql.dialect.statement.mysql.dml.MySQLSelectStatement;
 import 
org.apache.shardingsphere.sql.parser.sql.dialect.statement.oracle.dml.OracleSelectStatement;
 import org.junit.Test;
 
@@ -62,7 +63,7 @@ public final class RowNumberDecoratorMergedResultTest {
         when(whereSegment.getExpr()).thenReturn(binaryOperationExpression);
         SubqueryTableSegment subqueryTableSegment = 
mock(SubqueryTableSegment.class);
         SubquerySegment subquerySegment = mock(SubquerySegment.class);
-        SelectStatement subSelectStatement = mock(SelectStatement.class);
+        SelectStatement subSelectStatement = mock(MySQLSelectStatement.class);
         ProjectionsSegment subProjectionsSegment = 
mock(ProjectionsSegment.class);
         TopProjectionSegment topProjectionSegment = 
mock(TopProjectionSegment.class);
         when(topProjectionSegment.getAlias()).thenReturn("row_id");
@@ -105,7 +106,7 @@ public final class RowNumberDecoratorMergedResultTest {
         when(whereSegment.getExpr()).thenReturn(binaryOperationExpression);
         SubqueryTableSegment subqueryTableSegment = 
mock(SubqueryTableSegment.class);
         SubquerySegment subquerySegment = mock(SubquerySegment.class);
-        SelectStatement subSelectStatement = mock(SelectStatement.class);
+        SelectStatement subSelectStatement = mock(MySQLSelectStatement.class);
         ProjectionsSegment subProjectionsSegment = 
mock(ProjectionsSegment.class);
         TopProjectionSegment topProjectionSegment = 
mock(TopProjectionSegment.class);
         when(topProjectionSegment.getAlias()).thenReturn("row_id");
@@ -137,7 +138,7 @@ public final class RowNumberDecoratorMergedResultTest {
         when(whereSegment.getExpr()).thenReturn(binaryOperationExpression);
         SubqueryTableSegment subqueryTableSegment = 
mock(SubqueryTableSegment.class);
         SubquerySegment subquerySegment = mock(SubquerySegment.class);
-        SelectStatement subSelectStatement = mock(SelectStatement.class);
+        SelectStatement subSelectStatement = mock(MySQLSelectStatement.class);
         ProjectionsSegment subProjectionsSegment = 
mock(ProjectionsSegment.class);
         TopProjectionSegment topProjectionSegment = 
mock(TopProjectionSegment.class);
         when(topProjectionSegment.getAlias()).thenReturn("row_id");
diff --git 
a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/impl/SubqueryEnum.java
 
b/shardingsphere-infra/shardingsphere-infra-binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/subquery/SubqueryTableContext.java
similarity index 67%
rename from 
shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/impl/SubqueryEnum.java
rename to 
shardingsphere-infra/shardingsphere-infra-binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/subquery/SubqueryTableContext.java
index e5891f8..8179349 100644
--- 
a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/impl/SubqueryEnum.java
+++ 
b/shardingsphere-infra/shardingsphere-infra-binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/subquery/SubqueryTableContext.java
@@ -15,11 +15,23 @@
  * limitations under the License.
  */
 
-package org.apache.shardingsphere.encrypt.rewrite.token.generator.impl;
+package org.apache.shardingsphere.infra.binder.segment.select.subquery;
+
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+
+import java.util.Collection;
 
 /**
- * Subquery enum.
+ * Subquery table context.
  */
-public enum SubqueryEnum {
-    NONE, INSERT_SELECT, PROJECTION, NESTED_PROJECTION_TABLE_SEGMENT, 
EXPRESSION
+@RequiredArgsConstructor
+@Getter
+public final class SubqueryTableContext {
+    
+    private final String tableName;
+    
+    private final String alias;
+    
+    private final Collection<String> columnNames;
 }
diff --git 
a/shardingsphere-infra/shardingsphere-infra-binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/subquery/engine/SubqueryTableContextEngine.java
 
b/shardingsphere-infra/shardingsphere-infra-binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/subquery/engine/SubqueryTableContextEngine.java
new file mode 100644
index 0000000..1a3f243
--- /dev/null
+++ 
b/shardingsphere-infra/shardingsphere-infra-binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/subquery/engine/SubqueryTableContextEngine.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.infra.binder.segment.select.subquery.engine;
+
+import 
org.apache.shardingsphere.infra.binder.segment.select.projection.impl.ColumnProjection;
+import 
org.apache.shardingsphere.infra.binder.segment.select.subquery.SubqueryTableContext;
+import 
org.apache.shardingsphere.infra.binder.statement.dml.SelectStatementContext;
+
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * Subquery table context engine.
+ */
+public final class SubqueryTableContextEngine {
+    
+    /**
+     * Create subquery table contexts.
+     *
+     * @param subqueryContext subquery context
+     * @param alias subquery alias
+     * @return subquery table context collection
+     */
+    public Collection<SubqueryTableContext> createSubqueryTableContexts(final 
SelectStatementContext subqueryContext, final String alias) {
+        Collection<SubqueryTableContext> result = new LinkedList<>();
+        List<String> columnNames = 
subqueryContext.getProjectionsContext().getExpandProjections().stream()
+                .filter(each -> each instanceof ColumnProjection).map(each -> 
((ColumnProjection) each).getName()).collect(Collectors.toList());
+        for (String each : subqueryContext.getTablesContext().getTableNames()) 
{
+            result.add(new SubqueryTableContext(each, alias, columnNames));
+        }
+        return result;
+    }
+}
diff --git 
a/shardingsphere-infra/shardingsphere-infra-binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/table/TablesContext.java
 
b/shardingsphere-infra/shardingsphere-infra-binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/table/TablesContext.java
index 7c9e088..e69bc8f 100644
--- 
a/shardingsphere-infra/shardingsphere-infra-binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/table/TablesContext.java
+++ 
b/shardingsphere-infra/shardingsphere-infra-binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/table/TablesContext.java
@@ -21,9 +21,14 @@ import com.google.common.base.Preconditions;
 import lombok.Getter;
 import lombok.ToString;
 import 
org.apache.shardingsphere.infra.binder.segment.select.projection.impl.ColumnProjection;
+import 
org.apache.shardingsphere.infra.binder.segment.select.subquery.SubqueryTableContext;
+import 
org.apache.shardingsphere.infra.binder.segment.select.subquery.engine.SubqueryTableContextEngine;
+import 
org.apache.shardingsphere.infra.binder.statement.dml.SelectStatementContext;
 import org.apache.shardingsphere.infra.metadata.schema.ShardingSphereSchema;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.column.ColumnSegment;
 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.TableSegment;
 
 import java.util.Collection;
 import java.util.Collections;
@@ -47,21 +52,37 @@ public final class TablesContext {
     
     private final Map<String, SimpleTableSegment> uniqueTables = new 
HashMap<>();
     
+    private final Map<String, Collection<SubqueryTableContext>> subqueryTables 
= new HashMap<>();
+    
     private final Collection<String> schemaNames = new HashSet<>();
     
     public TablesContext(final SimpleTableSegment tableSegment) {
-        this(null == tableSegment ? Collections.emptyList() : 
Collections.singletonList(tableSegment));
+        this(Collections.singletonList(tableSegment));
     }
     
     public TablesContext(final Collection<SimpleTableSegment> tableSegments) {
+        this(tableSegments, Collections.emptyMap());
+    }
+    
+    public TablesContext(final Collection<? extends TableSegment> 
tableSegments, final Map<Integer, SelectStatementContext> subqueryContexts) {
         if (tableSegments.isEmpty()) {
             return;
         }
-        for (SimpleTableSegment each : tableSegments) {
+        Collection<SimpleTableSegment> simpleTableSegments = 
tableSegments.stream().filter(each 
+            -> each instanceof SimpleTableSegment).map(each -> 
(SimpleTableSegment) each).collect(Collectors.toList());
+        for (SimpleTableSegment each : simpleTableSegments) {
             originalTables.add(each);
             
uniqueTables.putIfAbsent(each.getTableName().getIdentifier().getValue(), each);
             each.getOwner().ifPresent(optional -> 
schemaNames.add(optional.getIdentifier().getValue()));
         }
+        Collection<SubqueryTableSegment> subqueryTableSegments = 
tableSegments.stream().filter(each
+            -> each instanceof SubqueryTableSegment).map(each -> 
(SubqueryTableSegment) each).collect(Collectors.toList());
+        for (SubqueryTableSegment each : subqueryTableSegments) {
+            SelectStatementContext subqueryContext = 
subqueryContexts.get(each.getSubquery().getStartIndex());
+            subqueryContext.setSubqueryTable(true);
+            Collection<SubqueryTableContext> subqueryTableContexts = new 
SubqueryTableContextEngine().createSubqueryTableContexts(subqueryContext, 
each.getAlias().orElse(null));
+            
subqueryTables.putAll(subqueryTableContexts.stream().collect(Collectors.groupingBy(SubqueryTableContext::getAlias)));
+        }
     }
     
     /**
@@ -122,6 +143,7 @@ public final class TablesContext {
     
     /**
      * Find table name from SQL.
+     * 
      * @param tableNameOrAlias table name or alias
      * @return table name
      */
@@ -179,6 +201,21 @@ public final class TablesContext {
     }
     
     /**
+     * Find table name from subquery.
+     * 
+     * @param columnName column name
+     * @param owner column owner
+     * @return table name
+     */
+    public Optional<String> findTableNameFromSubquery(final String columnName, 
final String owner) {
+        Collection<SubqueryTableContext> subqueryTableContexts = 
subqueryTables.get(owner);
+        if (null != subqueryTableContexts) {
+            return subqueryTableContexts.stream().filter(each -> 
each.getColumnNames().contains(columnName)).map(SubqueryTableContext::getTableName).findFirst();
+        }
+        return Optional.empty();
+    }
+    
+    /**
      * Get schema name.
      *
      * @return schema name
diff --git 
a/shardingsphere-infra/shardingsphere-infra-binder/src/main/java/org/apache/shardingsphere/infra/binder/statement/dml/SelectStatementContext.java
 
b/shardingsphere-infra/shardingsphere-infra-binder/src/main/java/org/apache/shardingsphere/infra/binder/statement/dml/SelectStatementContext.java
index 251ad8b..44126cf 100644
--- 
a/shardingsphere-infra/shardingsphere-infra-binder/src/main/java/org/apache/shardingsphere/infra/binder/statement/dml/SelectStatementContext.java
+++ 
b/shardingsphere-infra/shardingsphere-infra-binder/src/main/java/org/apache/shardingsphere/infra/binder/statement/dml/SelectStatementContext.java
@@ -51,11 +51,15 @@ import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.order.item.Te
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.predicate.WhereSegment;
 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.TableSegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.statement.dml.SelectStatement;
 import org.apache.shardingsphere.sql.parser.sql.common.util.SQLUtil;
 import 
org.apache.shardingsphere.sql.parser.sql.common.util.SubqueryExtractUtil;
 
 import java.util.Collection;
+import java.util.HashMap;
+import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 import java.util.Optional;
@@ -77,32 +81,35 @@ public final class SelectStatementContext extends 
CommonSQLStatementContext<Sele
     
     private final PaginationContext paginationContext;
     
-    private final Collection<SubquerySegment> subquerySegments;
+    private final Map<Integer, SelectStatementContext> subqueryContexts;
     
     private final String schemaName;
-
-    private final Map<String, ShardingSphereMetaData> metaDataMap;
-
-    private final List<Object> parameters;
-
+    
     @Setter
-    private SubqueryTableContext subqueryTableContext;
-
+    private boolean subqueryTable;
+    
     public SelectStatementContext(final Map<String, ShardingSphereMetaData> 
metaDataMap, final List<Object> parameters, final SelectStatement sqlStatement, 
final String defaultSchemaName) {
         super(sqlStatement);
-        this.metaDataMap = metaDataMap;
-        this.parameters = parameters;
-        tablesContext = new TablesContext(getAllSimpleTableSegments());
+        subqueryContexts = createSubqueryContexts(metaDataMap, parameters, 
defaultSchemaName);
+        tablesContext = new TablesContext(getAllTableSegments(), 
subqueryContexts);
         ShardingSphereSchema schema = getSchema(metaDataMap, 
defaultSchemaName);
         groupByContext = new 
GroupByContextEngine().createGroupByContext(sqlStatement);
         orderByContext = new 
OrderByContextEngine().createOrderBy(sqlStatement, groupByContext);
         projectionsContext = new ProjectionsContextEngine(schema, 
getDatabaseType())
                 .createProjectionsContext(getSqlStatement().getFrom(), 
getSqlStatement().getProjections(), groupByContext, orderByContext);
         paginationContext = new 
PaginationContextEngine().createPaginationContext(sqlStatement, 
projectionsContext, parameters);
-        subquerySegments = 
SubqueryExtractUtil.getSubquerySegments(getSqlStatement());
         schemaName = defaultSchemaName;
     }
     
+    private Map<Integer, SelectStatementContext> createSubqueryContexts(final 
Map<String, ShardingSphereMetaData> metaDataMap, final List<Object> parameters, 
final String defaultSchemaName) {
+        Collection<SubquerySegment> subquerySegments = 
SubqueryExtractUtil.getSubquerySegments(getSqlStatement());
+        Map<Integer, SelectStatementContext> result = new 
HashMap<>(subquerySegments.size(), 1);
+        for (SubquerySegment each : subquerySegments) {
+            result.put(each.getStartIndex(), new 
SelectStatementContext(metaDataMap, parameters, each.getSelect(), 
defaultSchemaName));
+        }
+        return result;
+    }
+    
     private ShardingSphereSchema getSchema(final Map<String, 
ShardingSphereMetaData> metaDataMap, final String defaultSchemaName) {
         String schemaName = 
tablesContext.getSchemaName().orElse(defaultSchemaName);
         ShardingSphereMetaData metaData = metaDataMap.get(schemaName);
@@ -127,7 +134,7 @@ public final class SelectStatementContext extends 
CommonSQLStatementContext<Sele
      * @return whether contains subquery or not
      */
     public boolean isContainsSubquery() {
-        return !subquerySegments.isEmpty();
+        return !subqueryContexts.isEmpty();
     }
     
     /**
@@ -242,9 +249,12 @@ public final class SelectStatementContext extends 
CommonSQLStatementContext<Sele
         return getSqlStatement().getWhere();
     }
     
-    private Collection<SimpleTableSegment> getAllSimpleTableSegments() {
+    private Collection<TableSegment> getAllTableSegments() {
+        Collection<TableSegment> result = new LinkedList<>();
         TableExtractor tableExtractor = new TableExtractor();
         tableExtractor.extractTablesFromSelect(getSqlStatement());
-        return tableExtractor.getRewriteTables();
+        result.addAll(tableExtractor.getRewriteTables());
+        result.addAll(tableExtractor.getTableContext().stream().filter(each -> 
each instanceof SubqueryTableSegment).collect(Collectors.toList()));
+        return result;
     }
 }
diff --git 
a/shardingsphere-infra/shardingsphere-infra-binder/src/main/java/org/apache/shardingsphere/infra/binder/statement/dml/SubqueryTableContext.java
 
b/shardingsphere-infra/shardingsphere-infra-binder/src/main/java/org/apache/shardingsphere/infra/binder/statement/dml/SubqueryTableContext.java
deleted file mode 100644
index f6ccea5..0000000
--- 
a/shardingsphere-infra/shardingsphere-infra-binder/src/main/java/org/apache/shardingsphere/infra/binder/statement/dml/SubqueryTableContext.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.shardingsphere.infra.binder.statement.dml;
-
-import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.column.ColumnSegment;
-
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.LinkedHashMap;
-import java.util.Map;
-import java.util.Optional;
-
-/**
- * Subquery table context.
- */
-public final class SubqueryTableContext {
-    
-    private final Map<String, Map<String, Map<String, String>>> 
rewriteMetaDataMap;
-    
-    public SubqueryTableContext() {
-        this.rewriteMetaDataMap = new LinkedHashMap<>();
-    }
-    
-    /**
-     * Put rewrite meta data map.
-     * @param alias alias
-     * @param plainColumn plainColumn
-     * @param cipherColumn cipherColumn
-     * @param assistedQueryColumn assistedQueryColumn
-     */
-    public void put(final Optional<String> alias, final String plainColumn, 
final String cipherColumn, final Optional<String> assistedQueryColumn) {
-        Map<String, String> rewriteColumnMap = new HashMap<>();
-        rewriteColumnMap.put("cipherColumn", cipherColumn);
-        assistedQueryColumn.ifPresent(each -> 
rewriteColumnMap.put("assistedQueryColumn", each));
-        alias.ifPresent(each -> rewriteMetaDataMap.put(each, 
Collections.singletonMap(plainColumn, rewriteColumnMap)));
-    }
-    
-    /**
-     * Get cipherColumn.
-     * @param column ColumnSegment
-     * @return cipherColumn
-     */
-    public Optional<String> getCipherColumn(final ColumnSegment column) {
-        return getColumn(column, "cipherColumn");
-    }
-    
-    /**
-     * Get assistedQueryColumn.
-     * @param column ColumnSegment
-     * @return assistedQueryColumn
-     */
-    public Optional<String> getAssistedQueryColumn(final ColumnSegment column) 
{
-        return getColumn(column, "assistedQueryColumn");
-    }
-    
-    private Optional<String> getColumn(final ColumnSegment column, final 
String columnName) {
-        String alias = column.getOwner().isPresent() ? 
column.getOwner().get().getIdentifier().getValue() : "";
-        String plainColumn = column.getIdentifier().getValue();
-        Map<String, Map<String, String>> rewriteColumnMap = 
rewriteMetaDataMap.get(alias);
-        if (null != rewriteColumnMap && 
rewriteColumnMap.containsKey(plainColumn)) {
-            return 
Optional.ofNullable(rewriteColumnMap.get(plainColumn).get(columnName));
-        }
-        return Optional.empty();
-    }
-    
-    /**
-     * Get rewriteMetaDataMap is empty or not.
-     * @return rewriteMetaDataMap is empty or not
-     */
-    public boolean isEmpty() {
-        return rewriteMetaDataMap.isEmpty();
-    }
-}
diff --git 
a/shardingsphere-sql-parser/shardingsphere-sql-parser-statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/util/SubqueryExtractUtil.java
 
b/shardingsphere-sql-parser/shardingsphere-sql-parser-statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/util/SubqueryExtractUtil.java
index 6e07cd0..4ad3609 100644
--- 
a/shardingsphere-sql-parser/shardingsphere-sql-parser-statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/util/SubqueryExtractUtil.java
+++ 
b/shardingsphere-sql-parser/shardingsphere-sql-parser-statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/util/SubqueryExtractUtil.java
@@ -59,14 +59,8 @@ public final class SubqueryExtractUtil {
         }
         return result;
     }
-
-    /**
-     * Get subquery segment from projections.
-     *
-     * @param projections ProjectionsSegment
-     * @return subquery segment collection
-     */
-    public static Collection<SubquerySegment> 
getSubquerySegmentsFromProjections(final ProjectionsSegment projections) {
+    
+    private static Collection<SubquerySegment> 
getSubquerySegmentsFromProjections(final ProjectionsSegment projections) {
         if (null == projections || projections.getProjections().isEmpty()) {
             return Collections.emptyList();
         }
@@ -81,37 +75,8 @@ public final class SubqueryExtractUtil {
         }
         return result;
     }
-
-    /**
-     * Get subquery table segment from tableSegment.
-     *
-     * @param tableSegment TableSegment
-     * @return subquery table segment collection
-     */
-    public static Collection<SubqueryTableSegment> 
getSubqueryTableSegmentsFromTableSegment(final TableSegment tableSegment) {
-        if (null == tableSegment) {
-            return Collections.emptyList();
-        }
-        Collection<SubqueryTableSegment> result = new LinkedList<>();
-        if (tableSegment instanceof SubqueryTableSegment) {
-            SubqueryTableSegment subqueryTableSegment = (SubqueryTableSegment) 
tableSegment;
-            result.add(subqueryTableSegment);
-            
result.addAll(getSubqueryTableSegmentsFromTableSegment(subqueryTableSegment.getSubquery().getSelect().getFrom()));
-        }
-        if (tableSegment instanceof JoinTableSegment) {
-            
result.addAll(getSubqueryTableSegmentsFromTableSegment(((JoinTableSegment) 
tableSegment).getLeft()));
-            
result.addAll(getSubqueryTableSegmentsFromTableSegment(((JoinTableSegment) 
tableSegment).getRight()));
-        }
-        return result;
-    }
-
-    /**
-     * Get subquery segment from tableSegment.
-     *
-     * @param tableSegment TableSegment
-     * @return subquery segment collection
-     */
-    public static Collection<SubquerySegment> 
getSubquerySegmentsFromTableSegment(final TableSegment tableSegment) {
+    
+    private static Collection<SubquerySegment> 
getSubquerySegmentsFromTableSegment(final TableSegment tableSegment) {
         if (null == tableSegment) {
             return Collections.emptyList();
         }
@@ -127,14 +92,8 @@ public final class SubqueryExtractUtil {
         }
         return result;
     }
-
-    /**
-     * Get subquery segment from expression.
-     *
-     * @param expressionSegment ExpressionSegment
-     * @return subquery table segment collection
-     */
-    public static Collection<SubquerySegment> 
getSubquerySegmentsFromExpression(final ExpressionSegment expressionSegment) {
+    
+    private static Collection<SubquerySegment> 
getSubquerySegmentsFromExpression(final ExpressionSegment expressionSegment) {
         Collection<SubquerySegment> result = new LinkedList<>();
         if (expressionSegment instanceof SubqueryExpressionSegment) {
             SubquerySegment subquerySegment = ((SubqueryExpressionSegment) 
expressionSegment).getSubquery();
diff --git 
a/shardingsphere-test/shardingsphere-rewrite-test/src/test/resources/scenario/encrypt/case/insert.xml
 
b/shardingsphere-test/shardingsphere-rewrite-test/src/test/resources/scenario/encrypt/case/insert.xml
index 0e98b70..5c27454 100644
--- 
a/shardingsphere-test/shardingsphere-rewrite-test/src/test/resources/scenario/encrypt/case/insert.xml
+++ 
b/shardingsphere-test/shardingsphere-rewrite-test/src/test/resources/scenario/encrypt/case/insert.xml
@@ -68,8 +68,8 @@
     </rewrite-assertion>
     
     <rewrite-assertion id="insert_select_encrypt_rewrite" db-types="MySQL">
-        <input sql="INSERT INTO t_account(account_id, certificate_number, 
password, amount) SELECT account_id, certificate_number, password, amount from 
t_account_bak where certificate_number = ?" parameters="111X"/>
-        <output sql="INSERT INTO t_account(account_id, 
cipher_certificate_number, assisted_query_certificate_number, cipher_password, 
assisted_query_password, cipher_amount) SELECT account_id, 
cipher_certificate_number, assisted_query_certificate_number, 
plain_certificate_number, cipher_password, assisted_query_password, 
plain_password, cipher_amount, plain_amount from t_account_bak where 
assisted_query_certificate_number = ?" parameters="assisted_query_111X" />
+        <input sql="INSERT INTO t_account(account_id, certificate_number, 
password, amount) SELECT account_id, certificate_number, password, amount FROM 
t_account_bak WHERE certificate_number = ?" parameters="111X"/>
+        <output sql="INSERT INTO t_account(account_id, 
cipher_certificate_number, assisted_query_certificate_number, cipher_password, 
assisted_query_password, cipher_amount) SELECT account_id, 
cipher_certificate_number AS certificate_number, cipher_password AS password, 
cipher_amount AS amount FROM t_account_bak WHERE 
assisted_query_certificate_number = ?" parameters="assisted_query_111X" />
     </rewrite-assertion>
     
     <rewrite-assertion id="insert_values_without_columns_for_literals" 
db-types="MySQL">
diff --git 
a/shardingsphere-test/shardingsphere-rewrite-test/src/test/resources/scenario/encrypt/case/select_for_query_with_cipher.xml
 
b/shardingsphere-test/shardingsphere-rewrite-test/src/test/resources/scenario/encrypt/case/select_for_query_with_cipher.xml
index dc0092b..4ed2c3a 100644
--- 
a/shardingsphere-test/shardingsphere-rewrite-test/src/test/resources/scenario/encrypt/case/select_for_query_with_cipher.xml
+++ 
b/shardingsphere-test/shardingsphere-rewrite-test/src/test/resources/scenario/encrypt/case/select_for_query_with_cipher.xml
@@ -89,33 +89,39 @@
         <output sql="SELECT a.account_id, a.cipher_password AS password, 
a.cipher_amount AS a, a.status AS s FROM t_account_bak AS a WHERE 
a.cipher_amount in (?, ?)" parameters="encrypt_1000, encrypt_2000" />
     </rewrite-assertion>
 
-    <rewrite-assertion id="select_with_projection_not_nested_subquery" 
db-types="MySQL">
-        <input sql="SELECT u.certificate_number, u.password, (select o.amount 
from t_account_bak o where o.certificate_number=u.certificate_number) amount 
FROM t_account u, t_account_bak c where u.certificate_number = 
c.certificate_number and u.password=?" parameters="1" />-->
-        <output sql="SELECT u.cipher_certificate_number AS certificate_number, 
u.cipher_password AS password, (select o.cipher_amount from t_account_bak o 
where o.certificate_number=u.assisted_query_certificate_number) amount FROM 
t_account u, t_account_bak c where u.assisted_query_certificate_number = 
c.assisted_query_certificate_number and u.assisted_query_password=?" 
parameters="assisted_query_1" />
+    <rewrite-assertion id="select_not_nested_subquery_in_projection" 
db-types="MySQL">
+        <input sql="SELECT u.certificate_number, u.password, (SELECT o.amount 
FROM t_account_bak o WHERE o.certificate_number=u.certificate_number) amount 
FROM t_account u, t_account_bak c WHERE u.certificate_number = 
c.certificate_number and u.password=?" parameters="1" />
+        <output sql="SELECT u.cipher_certificate_number AS certificate_number, 
u.cipher_password AS password, (SELECT o.cipher_amount AS amount FROM 
t_account_bak o WHERE o.certificate_number=u.assisted_query_certificate_number) 
amount FROM t_account u, t_account_bak c WHERE 
u.assisted_query_certificate_number = c.assisted_query_certificate_number and 
u.assisted_query_password=?" parameters="assisted_query_1" />
     </rewrite-assertion>
 
-    <rewrite-assertion id="select_with_tabsegment_not_nested_subquery" 
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" />
+    <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 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_with_expression_not_nested_subquery1" 
db-types="MySQL">
-        <input sql="SELECT u.amount, u.password, u.certificate_number FROM 
t_account_bak u, t_account c where u.certificate_number=(select 
certificate_number from t_account where password=?) and u.password=?" 
parameters="1, 2" />-->
-        <output sql="SELECT u.cipher_amount AS amount, u.cipher_password AS 
password, u.cipher_certificate_number AS certificate_number FROM t_account_bak 
u, t_account c where u.assisted_query_certificate_number=(select 
assisted_query_certificate_number from t_account where 
assisted_query_password=?) and u.assisted_query_password=?" 
parameters="assisted_query_1, assisted_query_2" />
+    <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` 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, 
`t_account`.`status` FROM t_account) o, t_account u WHERE 
o.assisted_query_certifica [...]
+    </rewrite-assertion>
+    <!-- TODO support subuqery rewrite in predicate
+    <rewrite-assertion 
id="select_not_nested_subquery_in_predicate_right_equal_condition" 
db-types="MySQL">
+        <input sql="SELECT u.amount, u.password, u.certificate_number FROM 
t_account_bak u, t_account c WHERE u.certificate_number=(SELECT 
certificate_number FROM t_account WHERE password=?) AND u.password=?" 
parameters="1, 2" />
+        <output sql="SELECT u.cipher_amount AS amount, u.cipher_password AS 
password, u.cipher_certificate_number AS certificate_number FROM t_account_bak 
u, t_account c WHERE u.assisted_query_certificate_number=(SELECT 
assisted_query_certificate_number FROM t_account WHERE 
assisted_query_password=?) and u.assisted_query_password=?" 
parameters="assisted_query_1, assisted_query_2" />
     </rewrite-assertion>
 
-    <rewrite-assertion id="select_with_expression_not_nested_subquery2" 
db-types="MySQL">
-        <input sql="SELECT u.amount, u.password, u.certificate_number FROM 
t_account_bak u, t_account c where (select certificate_number from t_account 
where password=?)=u.certificate_number and u.password=?" parameters="1, 2" />-->
-        <output sql="SELECT u.cipher_amount AS amount, u.cipher_password AS 
password, u.cipher_certificate_number AS certificate_number FROM t_account_bak 
u, t_account c where (select assisted_query_certificate_number from t_account 
where assisted_query_password=?)=u.assisted_query_certificate_number and 
u.assisted_query_password=?" parameters="assisted_query_1, assisted_query_2" />
+    <rewrite-assertion 
id="select_not_nested_subquery_in_predicate_left_equal_condition" 
db-types="MySQL">
+        <input sql="SELECT u.amount, u.password, u.certificate_number FROM 
t_account_bak u, t_account c WHERE (SELECT certificate_number FROM t_account 
WHERE password=?)=u.certificate_number AND u.password=?" parameters="1, 2" />
+        <output sql="SELECT u.cipher_amount AS amount, u.cipher_password AS 
password, u.cipher_certificate_number AS certificate_number FROM t_account_bak 
u, t_account c WHERE (SELECT assisted_query_certificate_number FROM t_account 
WHERE assisted_query_password=?)=u.assisted_query_certificate_number AND 
u.assisted_query_password=?" parameters="assisted_query_1, assisted_query_2" />
     </rewrite-assertion>
 
-    <rewrite-assertion id="select_with_expression_not_nested_subquery3" 
db-types="MySQL">
-        <input sql="SELECT u.amount, u.password, u.certificate_number FROM 
t_account_bak u, t_account c where (select certificate_number from t_account 
where password=?)=(select certificate_number from t_account_bak where 
password=?) and u.password=?" parameters="1, 2, 3" />-->
-        <output sql="SELECT u.cipher_amount AS amount, u.cipher_password AS 
password, u.cipher_certificate_number AS certificate_number FROM t_account_bak 
u, t_account c where (select assisted_query_certificate_number from t_account 
where assisted_query_password=?)=(select assisted_query_certificate_number from 
t_account_bak where assisted_query_password=?) and u.assisted_query_password=?" 
parameters="assisted_query_1, assisted_query_2, assisted_query_3" />
+    <rewrite-assertion 
id="select_not_nested_subquery_in_predicate_left_and_right_equal_condition" 
db-types="MySQL">
+        <input sql="SELECT u.amount, u.password, u.certificate_number FROM 
t_account_bak u, t_account c WHERE (SELECT certificate_number FROM t_account 
WHERE password=?)=(SELECT certificate_number FROM t_account_bak WHERE 
password=?) AND u.password=?" parameters="1, 2, 3" />
+        <output sql="SELECT u.cipher_amount AS amount, u.cipher_password AS 
password, u.cipher_certificate_number AS certificate_number FROM t_account_bak 
u, t_account c WHERE (SELECT assisted_query_certificate_number FROM t_account 
WHERE assisted_query_password=?)=(SELECT assisted_query_certificate_number FROM 
t_account_bak WHERE assisted_query_password=?) AND u.assisted_query_password=?" 
parameters="assisted_query_1, assisted_query_2, assisted_query_3" />
     </rewrite-assertion>
 
-    <rewrite-assertion id="select_with_expression_not_nested_subquery4" 
db-types="MySQL">
-        <input sql="SELECT u.amount, u.password, u.certificate_number FROM 
t_account_bak u, t_account c where u.certificate_number in (select 
certificate_number from t_account where password=?) and u.password=?" 
parameters="1, 2" />-->
-        <output sql="SELECT u.cipher_amount AS amount, u.cipher_password AS 
password, u.cipher_certificate_number AS certificate_number FROM t_account_bak 
u, t_account c where u.assisted_query_certificate_number in (select 
assisted_query_certificate_number from t_account where 
assisted_query_password=?) and u.assisted_query_password=?" 
parameters="assisted_query_1, assisted_query_2" />
+    <rewrite-assertion 
id="select_not_nested_subquery_in_predicate_in_condition" db-types="MySQL">
+        <input sql="SELECT u.amount, u.password, u.certificate_number FROM 
t_account_bak u, t_account c WHERE u.certificate_number IN (SELECT 
certificate_number FROM t_account WHERE password=?) AND u.password=?" 
parameters="1, 2" />
+        <output sql="SELECT u.cipher_amount AS amount, u.cipher_password AS 
password, u.cipher_certificate_number AS certificate_number FROM t_account_bak 
u, t_account c WHERE u.assisted_query_certificate_number IN (SELECT 
assisted_query_certificate_number FROM t_account WHERE 
assisted_query_password=?) AND u.assisted_query_password=?" 
parameters="assisted_query_1, assisted_query_2" />
     </rewrite-assertion>
+    -->
 </rewrite-assertions>

Reply via email to