You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shardingsphere.apache.org by pa...@apache.org on 2021/11/26 02:24:39 UTC

[shardingsphere] branch master updated: fix encrypt rewrite wrong result with table level queryWithCipherColumn (#13803)

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 b72ee63  fix encrypt rewrite wrong result with table level queryWithCipherColumn (#13803)
b72ee63 is described below

commit b72ee6380199db4ce6d6957a7c5b44332fce645b
Author: Zhengqiang Duan <du...@apache.org>
AuthorDate: Fri Nov 26 10:23:45 2021 +0800

    fix encrypt rewrite wrong result with table level queryWithCipherColumn (#13803)
    
    * fix encrypt rewrite wrong result with table level queryWithCipherColumn
    
    * add rewrite test case
    
    * fix checkstyle
---
 .../merge/EncryptResultDecoratorEngine.java        |  4 +-
 .../merge/dql/EncryptAlgorithmMetaData.java        | 48 +++++++++++++++-------
 .../merge/dql/EncryptDQLResultDecorator.java       |  6 +--
 .../encrypt/merge/dql/EncryptMergedResult.java     |  4 +-
 .../context/EncryptSQLRewriteContextDecorator.java |  2 +-
 .../impl/EncryptPredicateParameterRewriter.java    |  8 ++--
 .../impl/EncryptPredicateColumnTokenGenerator.java | 16 ++++----
 .../EncryptPredicateRightValueTokenGenerator.java  |  9 ++--
 .../impl/EncryptProjectionTokenGenerator.java      | 17 ++++----
 .../shardingsphere/encrypt/rule/EncryptRule.java   | 24 +++--------
 .../shardingsphere/encrypt/rule/EncryptTable.java  | 11 ++++-
 .../merge/dql/EncryptDQLResultDecoratorTest.java   |  4 +-
 .../encrypt/merge/dql/EncryptMergedResultTest.java | 20 +++++----
 .../EncryptSQLRewriterParameterizedTest.java       |  2 +
 .../encrypt/case/select_for_query_with_cipher.xml  | 10 +++++
 .../encrypt/case/select_for_query_with_plain.xml   | 10 +++++
 .../scenario/encrypt/config/query-with-cipher.yaml | 17 ++++++++
 .../scenario/encrypt/config/query-with-plain.yaml  | 16 ++++++++
 18 files changed, 143 insertions(+), 85 deletions(-)

diff --git a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/merge/EncryptResultDecoratorEngine.java b/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/merge/EncryptResultDecoratorEngine.java
index 664c712..c01ad7c 100644
--- a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/merge/EncryptResultDecoratorEngine.java
+++ b/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/merge/EncryptResultDecoratorEngine.java
@@ -41,8 +41,8 @@ public final class EncryptResultDecoratorEngine implements ResultDecoratorEngine
     public ResultDecorator newInstance(final DatabaseType databaseType, final ShardingSphereSchema schema,
                                        final EncryptRule encryptRule, final ConfigurationProperties props, final SQLStatementContext sqlStatementContext) {
         if (sqlStatementContext instanceof SelectStatementContext) {
-            return new EncryptDQLResultDecorator(new EncryptAlgorithmMetaData(schema, 
-                    encryptRule, (SelectStatementContext) sqlStatementContext), encryptRule.isQueryWithCipherColumn(sqlStatementContext));
+            EncryptAlgorithmMetaData metaData = new EncryptAlgorithmMetaData(schema, encryptRule, (SelectStatementContext) sqlStatementContext);
+            return new EncryptDQLResultDecorator(metaData);
         } 
         if (sqlStatementContext.getSqlStatement() instanceof DALStatement) {
             return new EncryptDALResultDecorator();
diff --git a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/merge/dql/EncryptAlgorithmMetaData.java b/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/merge/dql/EncryptAlgorithmMetaData.java
index 0a4586e..c24ecc0 100644
--- a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/merge/dql/EncryptAlgorithmMetaData.java
+++ b/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/merge/dql/EncryptAlgorithmMetaData.java
@@ -49,23 +49,15 @@ public final class EncryptAlgorithmMetaData {
      * @return encryptor
      */
     public Optional<EncryptAlgorithm> findEncryptor(final int columnIndex) {
-        List<Projection> expandProjections = selectStatementContext.getProjectionsContext().getExpandProjections();
-        if (expandProjections.isEmpty()) {
+        Optional<ColumnProjection> columnProjection = findColumnProjection(columnIndex);
+        if (!columnProjection.isPresent()) {
             return Optional.empty();
         }
-        return findEncryptor(columnIndex, expandProjections);
-    }
-    
-    private Optional<EncryptAlgorithm> findEncryptor(final int columnIndex, final List<Projection> expandProjections) {
-        Projection projection = expandProjections.get(columnIndex - 1);
-        if (projection instanceof ColumnProjection) {
-            String columnName = ((ColumnProjection) projection).getName();
-            Map<String, String> columnTableNames = selectStatementContext.getTablesContext().findTableName(Collections.singletonList((ColumnProjection) projection), schema);
-            String schemaName = selectStatementContext.getSchemaName();
-            return columnTableNames.containsKey(projection.getExpression()) 
-                    ? findEncryptor(schemaName, columnTableNames.get(projection.getExpression()), columnName) : findEncryptor(schemaName, columnName);
-        }
-        return Optional.empty();
+        Map<String, String> columnTableNames = selectStatementContext.getTablesContext().findTableName(Collections.singletonList(columnProjection.get()), schema);
+        Optional<String> tableName = Optional.ofNullable(columnTableNames.get(columnProjection.get().getExpression()));
+        String schemaName = selectStatementContext.getSchemaName();
+        String columnName = columnProjection.get().getName();
+        return tableName.isPresent() ? findEncryptor(schemaName, tableName.get(), columnName) : findEncryptor(schemaName, columnName);
     }
     
     private Optional<EncryptAlgorithm> findEncryptor(final String schemaName, final String tableName, final String columnName) {
@@ -81,4 +73,30 @@ public final class EncryptAlgorithmMetaData {
         }
         return Optional.empty();
     }
+    
+    /**
+     * Judge whether table is support QueryWithCipherColumn or not.
+     *
+     * @param columnIndex column index
+     * @return whether table is support QueryWithCipherColumn or not
+     */
+    public boolean isQueryWithCipherColumn(final int columnIndex) {
+        Optional<ColumnProjection> columnProjection = findColumnProjection(columnIndex);
+        Optional<String> tableName = Optional.empty();
+        if (columnProjection.isPresent()) {
+            Map<String, String> columnTableNames = selectStatementContext.getTablesContext().findTableName(Collections.singletonList(columnProjection.get()), schema);
+            tableName = Optional.ofNullable(columnTableNames.get(columnProjection.get().getExpression()));
+        }
+        return encryptRule.isQueryWithCipherColumn(tableName.orElse(""));
+
+    }
+    
+    private Optional<ColumnProjection> findColumnProjection(final int columnIndex) {
+        List<Projection> expandProjections = selectStatementContext.getProjectionsContext().getExpandProjections();
+        if (expandProjections.size() < columnIndex) {
+            return Optional.empty();
+        }
+        Projection projection = expandProjections.get(columnIndex - 1);
+        return projection instanceof ColumnProjection ? Optional.of((ColumnProjection) projection) : Optional.empty();
+    }
 }
diff --git a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/merge/dql/EncryptDQLResultDecorator.java b/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/merge/dql/EncryptDQLResultDecorator.java
index 2ae55a6..043ffb7 100644
--- a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/merge/dql/EncryptDQLResultDecorator.java
+++ b/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/merge/dql/EncryptDQLResultDecorator.java
@@ -33,15 +33,13 @@ public final class EncryptDQLResultDecorator implements ResultDecorator<EncryptR
     
     private final EncryptAlgorithmMetaData metaData;
     
-    private final boolean queryWithCipherColumn;
-    
     @Override
     public MergedResult decorate(final QueryResult queryResult, final SQLStatementContext<?> sqlStatementContext, final EncryptRule rule) {
-        return new EncryptMergedResult(metaData, new TransparentMergedResult(queryResult), queryWithCipherColumn);
+        return new EncryptMergedResult(metaData, new TransparentMergedResult(queryResult));
     }
     
     @Override
     public MergedResult decorate(final MergedResult mergedResult, final SQLStatementContext<?> sqlStatementContext, final EncryptRule rule) {
-        return new EncryptMergedResult(metaData, mergedResult, queryWithCipherColumn);
+        return new EncryptMergedResult(metaData, mergedResult);
     }
 }
diff --git a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/merge/dql/EncryptMergedResult.java b/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/merge/dql/EncryptMergedResult.java
index f233b08..9c17b5f 100644
--- a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/merge/dql/EncryptMergedResult.java
+++ b/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/merge/dql/EncryptMergedResult.java
@@ -36,8 +36,6 @@ public final class EncryptMergedResult implements MergedResult {
     
     private final MergedResult mergedResult;
     
-    private final boolean queryWithCipherColumn;
-    
     @Override
     public boolean next() throws SQLException {
         return mergedResult.next();
@@ -46,7 +44,7 @@ public final class EncryptMergedResult implements MergedResult {
     @SuppressWarnings({"rawtypes", "unchecked"})
     @Override
     public Object getValue(final int columnIndex, final Class<?> type) throws SQLException {
-        if (!queryWithCipherColumn) {
+        if (!metaData.isQueryWithCipherColumn(columnIndex)) {
             return mergedResult.getValue(columnIndex, type);
         }
         Optional<EncryptAlgorithm> encryptAlgorithm = metaData.findEncryptor(columnIndex);
diff --git a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/context/EncryptSQLRewriteContextDecorator.java b/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/context/EncryptSQLRewriteContextDecorator.java
index eb01248..381fbad 100644
--- a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/context/EncryptSQLRewriteContextDecorator.java
+++ b/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/context/EncryptSQLRewriteContextDecorator.java
@@ -35,7 +35,7 @@ public final class EncryptSQLRewriteContextDecorator implements SQLRewriteContex
     @SuppressWarnings({"rawtypes", "unchecked"})
     @Override
     public void decorate(final EncryptRule encryptRule, final ConfigurationProperties props, final SQLRewriteContext sqlRewriteContext, final RouteContext routeContext) {
-        for (ParameterRewriter each : new EncryptParameterRewriterBuilder(encryptRule, encryptRule.isQueryWithCipherColumn(sqlRewriteContext.getSqlStatementContext()))
+        for (ParameterRewriter each : new EncryptParameterRewriterBuilder(encryptRule, encryptRule.isQueryWithCipherColumn())
                 .getParameterRewriters(sqlRewriteContext.getSchema())) {
             if (!sqlRewriteContext.getParameters().isEmpty() && each.isNeedRewrite(sqlRewriteContext.getSqlStatementContext())) {
                 each.rewrite(sqlRewriteContext.getParameterBuilder(), sqlRewriteContext.getSqlStatementContext(), sqlRewriteContext.getParameters());
diff --git a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/parameter/impl/EncryptPredicateParameterRewriter.java b/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/parameter/impl/EncryptPredicateParameterRewriter.java
index 7364649..c25115b 100644
--- a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/parameter/impl/EncryptPredicateParameterRewriter.java
+++ b/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/parameter/impl/EncryptPredicateParameterRewriter.java
@@ -18,13 +18,12 @@
 package org.apache.shardingsphere.encrypt.rewrite.parameter.impl;
 
 import lombok.Setter;
-import org.apache.shardingsphere.encrypt.rewrite.aware.QueryWithCipherColumnAware;
 import org.apache.shardingsphere.encrypt.rewrite.condition.EncryptCondition;
 import org.apache.shardingsphere.encrypt.rewrite.condition.EncryptConditionEngine;
 import org.apache.shardingsphere.encrypt.rewrite.parameter.EncryptParameterRewriter;
-import org.apache.shardingsphere.infra.metadata.schema.ShardingSphereSchema;
 import org.apache.shardingsphere.infra.binder.statement.SQLStatementContext;
 import org.apache.shardingsphere.infra.binder.statement.dml.util.DMLStatementContextHelper;
+import org.apache.shardingsphere.infra.metadata.schema.ShardingSphereSchema;
 import org.apache.shardingsphere.infra.rewrite.parameter.builder.ParameterBuilder;
 import org.apache.shardingsphere.infra.rewrite.parameter.builder.impl.StandardParameterBuilder;
 import org.apache.shardingsphere.infra.rewrite.sql.token.generator.aware.SchemaMetaDataAware;
@@ -38,12 +37,10 @@ import java.util.Map.Entry;
  * Predicate parameter rewriter for encrypt.
  */
 @Setter
-public final class EncryptPredicateParameterRewriter extends EncryptParameterRewriter<SQLStatementContext> implements SchemaMetaDataAware, QueryWithCipherColumnAware {
+public final class EncryptPredicateParameterRewriter extends EncryptParameterRewriter<SQLStatementContext> implements SchemaMetaDataAware {
     
     private ShardingSphereSchema schema;
     
-    private boolean queryWithCipherColumn;
-    
     @Override
     protected boolean isNeedRewriteForEncrypt(final SQLStatementContext sqlStatementContext) {
         return true;
@@ -57,6 +54,7 @@ public final class EncryptPredicateParameterRewriter extends EncryptParameterRew
         }
         String schemaName = DMLStatementContextHelper.getSchemaName(sqlStatementContext);
         for (EncryptCondition each : encryptConditions) {
+            boolean queryWithCipherColumn = getEncryptRule().isQueryWithCipherColumn(each.getTableName());
             if (queryWithCipherColumn) {
                 encryptParameters(parameterBuilder, each.getPositionIndexMap(), getEncryptedValues(schemaName, each, each.getValues(parameters)));
             }
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 502dfb9..d648d3e 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
@@ -18,7 +18,6 @@
 package org.apache.shardingsphere.encrypt.rewrite.token.generator.impl;
 
 import lombok.Setter;
-import org.apache.shardingsphere.encrypt.rewrite.aware.QueryWithCipherColumnAware;
 import org.apache.shardingsphere.encrypt.rewrite.token.generator.BaseEncryptSQLTokenGenerator;
 import org.apache.shardingsphere.encrypt.rule.EncryptTable;
 import org.apache.shardingsphere.infra.binder.segment.select.projection.impl.ColumnProjection;
@@ -50,12 +49,10 @@ import java.util.stream.Collectors;
  * Predicate column token generator for encrypt.
  */
 @Setter
-public final class EncryptPredicateColumnTokenGenerator extends BaseEncryptSQLTokenGenerator implements CollectionSQLTokenGenerator, SchemaMetaDataAware, QueryWithCipherColumnAware {
+public final class EncryptPredicateColumnTokenGenerator extends BaseEncryptSQLTokenGenerator implements CollectionSQLTokenGenerator, SchemaMetaDataAware {
     
     private ShardingSphereSchema schema;
     
-    private boolean queryWithCipherColumn;
-    
     @SuppressWarnings("rawtypes")
     @Override
     protected boolean isGenerateSQLTokenForEncrypt(final SQLStatementContext sqlStatementContext) {
@@ -82,14 +79,15 @@ public final class EncryptPredicateColumnTokenGenerator extends BaseEncryptSQLTo
         Collection<SubstitutableColumnNameToken> result = new LinkedList<>();
         for (ExpressionSegment each : predicates) {
             for (ColumnSegment column : ColumnExtractor.extract(each)) {
-                Optional<EncryptTable> encryptTable = findEncryptTable(columnTableNames, buildColumnProjection(column));
+                Optional<String> tableName = findTableName(columnTableNames, buildColumnProjection(column));
+                Optional<EncryptTable> encryptTable = tableName.flatMap(optional -> getEncryptRule().findEncryptTable(optional));
                 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) {
+                boolean queryWithCipherColumn = getEncryptRule().isQueryWithCipherColumn(tableName.orElse(""));
+                if (!queryWithCipherColumn) {
                     Optional<String> plainColumn = encryptTable.get().findPlainColumn(column.getIdentifier().getValue());
                     if (plainColumn.isPresent()) {
                         result.add(new SubstitutableColumnNameToken(startIndex, stopIndex, getColumnProjections(plainColumn.get())));
@@ -129,8 +127,8 @@ public final class EncryptPredicateColumnTokenGenerator extends BaseEncryptSQLTo
         return new ColumnProjection(owner, segment.getIdentifier().getValue(), null);
     }
     
-    private Optional<EncryptTable> findEncryptTable(final Map<String, String> columnTableNames, final ColumnProjection column) {
-        return Optional.ofNullable(columnTableNames.get(column.getExpression())).flatMap(tableName -> getEncryptRule().findEncryptTable(tableName));
+    private Optional<String> findTableName(final Map<String, String> columnTableNames, final ColumnProjection column) {
+        return Optional.ofNullable(columnTableNames.get(column.getExpression()));
     }
     
     private Collection<ColumnProjection> getColumnProjections(final String columnName) {
diff --git a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/impl/EncryptPredicateRightValueTokenGenerator.java b/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/impl/EncryptPredicateRightValueTokenGenerator.java
index cb88801..8c8ddd7 100644
--- a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/impl/EncryptPredicateRightValueTokenGenerator.java
+++ b/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/impl/EncryptPredicateRightValueTokenGenerator.java
@@ -18,17 +18,16 @@
 package org.apache.shardingsphere.encrypt.rewrite.token.generator.impl;
 
 import lombok.Setter;
-import org.apache.shardingsphere.encrypt.rewrite.aware.QueryWithCipherColumnAware;
 import org.apache.shardingsphere.encrypt.rewrite.condition.EncryptCondition;
 import org.apache.shardingsphere.encrypt.rewrite.condition.EncryptConditionEngine;
 import org.apache.shardingsphere.encrypt.rewrite.condition.impl.EncryptInCondition;
 import org.apache.shardingsphere.encrypt.rewrite.token.generator.BaseEncryptSQLTokenGenerator;
 import org.apache.shardingsphere.encrypt.rewrite.token.pojo.EncryptPredicateEqualRightValueToken;
 import org.apache.shardingsphere.encrypt.rewrite.token.pojo.EncryptPredicateInRightValueToken;
-import org.apache.shardingsphere.infra.metadata.schema.ShardingSphereSchema;
 import org.apache.shardingsphere.infra.binder.statement.SQLStatementContext;
 import org.apache.shardingsphere.infra.binder.statement.dml.util.DMLStatementContextHelper;
 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;
 import org.apache.shardingsphere.infra.rewrite.sql.token.generator.aware.ParametersAware;
 import org.apache.shardingsphere.infra.rewrite.sql.token.generator.aware.SchemaMetaDataAware;
@@ -46,15 +45,12 @@ import java.util.Optional;
  * Predicate right value token generator for encrypt.
  */
 @Setter
-public final class EncryptPredicateRightValueTokenGenerator extends BaseEncryptSQLTokenGenerator 
-        implements CollectionSQLTokenGenerator, SchemaMetaDataAware, ParametersAware, QueryWithCipherColumnAware {
+public final class EncryptPredicateRightValueTokenGenerator extends BaseEncryptSQLTokenGenerator implements CollectionSQLTokenGenerator, SchemaMetaDataAware, ParametersAware {
     
     private ShardingSphereSchema schema;
     
     private List<Object> parameters;
     
-    private boolean queryWithCipherColumn;
-    
     @Override
     protected boolean isGenerateSQLTokenForEncrypt(final SQLStatementContext sqlStatementContext) {
         return sqlStatementContext instanceof WhereAvailable && ((WhereAvailable) sqlStatementContext).getWhere().isPresent();
@@ -77,6 +73,7 @@ public final class EncryptPredicateRightValueTokenGenerator extends BaseEncryptS
     private SQLToken generateSQLToken(final String schemaName, final EncryptCondition encryptCondition) {
         List<Object> originalValues = encryptCondition.getValues(parameters);
         int startIndex = encryptCondition.getStartIndex();
+        boolean queryWithCipherColumn = getEncryptRule().isQueryWithCipherColumn(encryptCondition.getTableName());
         return queryWithCipherColumn ? generateSQLTokenForQueryWithCipherColumn(schemaName, encryptCondition, originalValues, startIndex)
                 : generateSQLTokenForQueryWithoutCipherColumn(encryptCondition, originalValues, startIndex);
     }
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 e54d1a4..fab3e26 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
@@ -19,9 +19,7 @@ package org.apache.shardingsphere.encrypt.rewrite.token.generator.impl;
 
 import com.google.common.base.Preconditions;
 import lombok.Setter;
-import org.apache.shardingsphere.encrypt.rewrite.aware.QueryWithCipherColumnAware;
 import org.apache.shardingsphere.encrypt.rewrite.token.generator.BaseEncryptSQLTokenGenerator;
-import org.apache.shardingsphere.encrypt.rule.EncryptTable;
 import org.apache.shardingsphere.infra.binder.segment.select.projection.Projection;
 import org.apache.shardingsphere.infra.binder.segment.select.projection.ProjectionsContext;
 import org.apache.shardingsphere.infra.binder.segment.select.projection.impl.ColumnProjection;
@@ -51,10 +49,7 @@ import java.util.Optional;
  * Projection token generator for encrypt.
  */
 @Setter
-public final class EncryptProjectionTokenGenerator extends BaseEncryptSQLTokenGenerator 
-        implements CollectionSQLTokenGenerator<SQLStatementContext>, QueryWithCipherColumnAware, PreviousSQLTokensAware, SchemaMetaDataAware {
-    
-    private boolean queryWithCipherColumn;
+public final class EncryptProjectionTokenGenerator extends BaseEncryptSQLTokenGenerator implements CollectionSQLTokenGenerator<SQLStatementContext>, PreviousSQLTokensAware, SchemaMetaDataAware {
     
     private List<SQLToken> previousSQLTokens;
     
@@ -161,8 +156,8 @@ public final class EncryptProjectionTokenGenerator extends BaseEncryptSQLTokenGe
     }
     
     private ColumnProjection generatePredicateSubqueryProjection(final String tableName, final ColumnProjection column) {
-        Boolean queryWithCipherColumn = getEncryptRule().findEncryptTable(tableName).map(EncryptTable::getQueryWithCipherColumn).orElse(null);
-        if (Boolean.FALSE.equals(queryWithCipherColumn) || !this.queryWithCipherColumn) {
+        boolean queryWithCipherColumn = getEncryptRule().isQueryWithCipherColumn(tableName);
+        if (!queryWithCipherColumn) {
             Optional<String> plainColumn = getEncryptRule().findPlainColumn(tableName, column.getName());
             if (plainColumn.isPresent()) {
                 return new ColumnProjection(column.getOwner(), plainColumn.get(), null);
@@ -194,7 +189,11 @@ public final class EncryptProjectionTokenGenerator extends BaseEncryptSQLTokenGe
     
     private String getEncryptColumnName(final String tableName, final String logicEncryptColumnName) {
         Optional<String> plainColumn = getEncryptRule().findPlainColumn(tableName, logicEncryptColumnName);
-        return plainColumn.isPresent() && !queryWithCipherColumn ? plainColumn.get() : getEncryptRule().getCipherColumn(tableName, logicEncryptColumnName);
+        boolean queryWithCipherColumn = getEncryptRule().isQueryWithCipherColumn(tableName);
+        if (!queryWithCipherColumn) {
+            return plainColumn.orElseGet(() -> getEncryptRule().getCipherColumn(tableName, logicEncryptColumnName));
+        }
+        return getEncryptRule().getCipherColumn(tableName, logicEncryptColumnName);
     }
     
     private ShorthandProjection getShorthandProjection(final ShorthandProjectionSegment segment, final ProjectionsContext projectionsContext) {
diff --git a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rule/EncryptRule.java b/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rule/EncryptRule.java
index f8ec418..979f143 100644
--- a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rule/EncryptRule.java
+++ b/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rule/EncryptRule.java
@@ -27,16 +27,12 @@ import org.apache.shardingsphere.encrypt.api.config.rule.EncryptTableRuleConfigu
 import org.apache.shardingsphere.encrypt.rewrite.util.EncryptPropertiesBuilder;
 import org.apache.shardingsphere.encrypt.spi.EncryptAlgorithm;
 import org.apache.shardingsphere.encrypt.spi.QueryAssistedEncryptAlgorithm;
-import org.apache.shardingsphere.infra.binder.statement.SQLStatementContext;
-import org.apache.shardingsphere.infra.binder.statement.dml.SelectStatementContext;
-import org.apache.shardingsphere.infra.binder.type.TableAvailable;
 import org.apache.shardingsphere.infra.config.algorithm.ShardingSphereAlgorithmFactory;
 import org.apache.shardingsphere.infra.metadata.schema.ShardingSphereSchema;
 import org.apache.shardingsphere.infra.rewrite.sql.token.generator.aware.SchemaMetaDataAware;
 import org.apache.shardingsphere.infra.rule.identifier.scope.SchemaRule;
 import org.apache.shardingsphere.infra.rule.identifier.type.TableContainedRule;
 import org.apache.shardingsphere.spi.ShardingSphereServiceLoader;
-import org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.SimpleTableSegment;
 
 import java.util.Collection;
 import java.util.Collections;
@@ -256,23 +252,13 @@ public final class EncryptRule implements SchemaRule, TableContainedRule {
     }
 
     /**
-     * Check the table is support QueryWithCipherColumn.
+     * Judge whether table is support QueryWithCipherColumn or not.
      *
-     * @param sqlStatementContext sqlStatementContext
-     * @return isQueryWithCipherColumn
+     * @param tableName table name
+     * @return whether table is support QueryWithCipherColumn or not
      */
-    public boolean isQueryWithCipherColumn(final SQLStatementContext<?> sqlStatementContext) {
-        Collection<SimpleTableSegment> simpleTables = sqlStatementContext instanceof SelectStatementContext
-                ? ((TableAvailable) sqlStatementContext).getAllTables()
-                : Collections.emptyList();
-        boolean result = queryWithCipherColumn;
-        if (!simpleTables.isEmpty()) {
-            String tableName = simpleTables.iterator().next().getTableName().getIdentifier().getValue();
-            if (tables.containsKey(tableName) && null != tables.get(tableName).getQueryWithCipherColumn()) {
-                result = tables.get(tableName).getQueryWithCipherColumn();
-            }
-        }
-        return result;
+    public boolean isQueryWithCipherColumn(final String tableName) {
+        return findEncryptTable(tableName).flatMap(EncryptTable::getQueryWithCipherColumn).orElse(queryWithCipherColumn);
     }
     
     private Optional<String> findOriginColumnName(final String logicTable, final String logicColumn) {
diff --git a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rule/EncryptTable.java b/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rule/EncryptTable.java
index b249d97..0b77f93 100644
--- a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rule/EncryptTable.java
+++ b/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rule/EncryptTable.java
@@ -18,7 +18,6 @@
 package org.apache.shardingsphere.encrypt.rule;
 
 import com.google.common.collect.Maps;
-import lombok.Getter;
 import org.apache.shardingsphere.encrypt.api.config.rule.EncryptColumnRuleConfiguration;
 import org.apache.shardingsphere.encrypt.api.config.rule.EncryptTableRuleConfiguration;
 import org.apache.shardingsphere.infra.exception.ShardingSphereException;
@@ -37,7 +36,6 @@ public final class EncryptTable {
     
     private final Map<String, EncryptColumn> columns;
     
-    @Getter
     private final Boolean queryWithCipherColumn;
     
     public EncryptTable(final EncryptTableRuleConfiguration config) {
@@ -160,4 +158,13 @@ public final class EncryptTable {
     public Map<String, String> getLogicAndCipherColumns() {
         return Maps.transformValues(columns, EncryptColumn::getCipherColumn);
     }
+    
+    /**
+     * Get query with cipher column.
+     * 
+     * @return query with cipher column
+     */
+    public Optional<Boolean> getQueryWithCipherColumn() {
+        return Optional.ofNullable(queryWithCipherColumn);
+    }
 }
diff --git a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/test/java/org/apache/shardingsphere/encrypt/merge/dql/EncryptDQLResultDecoratorTest.java b/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/test/java/org/apache/shardingsphere/encrypt/merge/dql/EncryptDQLResultDecoratorTest.java
index a26df63..da481cc 100644
--- a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/test/java/org/apache/shardingsphere/encrypt/merge/dql/EncryptDQLResultDecoratorTest.java
+++ b/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/test/java/org/apache/shardingsphere/encrypt/merge/dql/EncryptDQLResultDecoratorTest.java
@@ -35,7 +35,7 @@ public final class EncryptDQLResultDecoratorTest {
     public void assertDecorateQueryResult() throws SQLException {
         QueryResult queryResult = mock(QueryResult.class);
         when(queryResult.next()).thenReturn(true);
-        EncryptDQLResultDecorator decorator = new EncryptDQLResultDecorator(mock(EncryptAlgorithmMetaData.class), false);
+        EncryptDQLResultDecorator decorator = new EncryptDQLResultDecorator(mock(EncryptAlgorithmMetaData.class));
         MergedResult actual = decorator.decorate(queryResult, mock(SQLStatementContext.class), mock(EncryptRule.class));
         assertTrue(actual.next());
     }
@@ -44,7 +44,7 @@ public final class EncryptDQLResultDecoratorTest {
     public void assertDecorateMergedResult() throws SQLException {
         MergedResult mergedResult = mock(MergedResult.class);
         when(mergedResult.next()).thenReturn(true);
-        EncryptDQLResultDecorator decorator = new EncryptDQLResultDecorator(mock(EncryptAlgorithmMetaData.class), false);
+        EncryptDQLResultDecorator decorator = new EncryptDQLResultDecorator(mock(EncryptAlgorithmMetaData.class));
         MergedResult actual = decorator.decorate(mergedResult, mock(SQLStatementContext.class), mock(EncryptRule.class));
         assertTrue(actual.next());
     }
diff --git a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/test/java/org/apache/shardingsphere/encrypt/merge/dql/EncryptMergedResultTest.java b/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/test/java/org/apache/shardingsphere/encrypt/merge/dql/EncryptMergedResultTest.java
index 02ab8a1..3756958 100644
--- a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/test/java/org/apache/shardingsphere/encrypt/merge/dql/EncryptMergedResultTest.java
+++ b/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/test/java/org/apache/shardingsphere/encrypt/merge/dql/EncryptMergedResultTest.java
@@ -48,20 +48,22 @@ public final class EncryptMergedResultTest {
     
     @Test
     public void assertNext() throws SQLException {
-        assertFalse(new EncryptMergedResult(metaData, mergedResult, true).next());
+        assertFalse(new EncryptMergedResult(metaData, mergedResult).next());
     }
     
     @Test
     public void assertGetValueWithQueryWithPlainColumn() throws SQLException {
         when(mergedResult.getValue(1, String.class)).thenReturn("VALUE");
-        assertThat(new EncryptMergedResult(metaData, mergedResult, false).getValue(1, String.class), is("VALUE"));
+        when(metaData.isQueryWithCipherColumn(1)).thenReturn(false);
+        assertThat(new EncryptMergedResult(metaData, mergedResult).getValue(1, String.class), is("VALUE"));
     }
     
     @Test
     public void assertGetValueWithQueryWithCipherColumnAndMismatchedEncryptor() throws SQLException {
         when(mergedResult.getValue(1, String.class)).thenReturn("VALUE");
         when(metaData.findEncryptor(1)).thenReturn(Optional.empty());
-        assertThat(new EncryptMergedResult(metaData, mergedResult, true).getValue(1, String.class), is("VALUE"));
+        when(metaData.isQueryWithCipherColumn(1)).thenReturn(true);
+        assertThat(new EncryptMergedResult(metaData, mergedResult).getValue(1, String.class), is("VALUE"));
     }
     
     @Test
@@ -70,32 +72,34 @@ public final class EncryptMergedResultTest {
         EncryptAlgorithm encryptAlgorithm = mock(EncryptAlgorithm.class);
         when(encryptAlgorithm.decrypt("VALUE")).thenReturn("ORIGINAL_VALUE");
         when(metaData.findEncryptor(1)).thenReturn(Optional.of(encryptAlgorithm));
-        assertThat(new EncryptMergedResult(metaData, mergedResult, true).getValue(1, String.class), is("ORIGINAL_VALUE"));
+        when(metaData.isQueryWithCipherColumn(1)).thenReturn(true);
+        assertThat(new EncryptMergedResult(metaData, mergedResult).getValue(1, String.class), is("ORIGINAL_VALUE"));
     }
     
     @Test
     public void assertGetValueWithQueryWithCipherColumnAndMatchedEncryptorWithNullCiphertext() throws SQLException {
         EncryptAlgorithm encryptAlgorithm = mock(EncryptAlgorithm.class);
         when(metaData.findEncryptor(1)).thenReturn(Optional.of(encryptAlgorithm));
-        assertNull(new EncryptMergedResult(metaData, mergedResult, true).getValue(1, String.class));
+        when(metaData.isQueryWithCipherColumn(1)).thenReturn(true);
+        assertNull(new EncryptMergedResult(metaData, mergedResult).getValue(1, String.class));
     }
     
     @Test
     public void assertGetCalendarValue() throws SQLException {
         Calendar calendar = Calendar.getInstance();
         when(mergedResult.getCalendarValue(1, Date.class, calendar)).thenReturn(new Date(0L));
-        assertThat(new EncryptMergedResult(metaData, mergedResult, true).getCalendarValue(1, Date.class, calendar), is(new Date(0L)));
+        assertThat(new EncryptMergedResult(metaData, mergedResult).getCalendarValue(1, Date.class, calendar), is(new Date(0L)));
     }
     
     @Test
     public void assertGetInputStream() throws SQLException {
         InputStream inputStream = mock(InputStream.class);
         when(mergedResult.getInputStream(1, "asc")).thenReturn(inputStream);
-        assertThat(new EncryptMergedResult(metaData, mergedResult, true).getInputStream(1, "asc"), is(inputStream));
+        assertThat(new EncryptMergedResult(metaData, mergedResult).getInputStream(1, "asc"), is(inputStream));
     }
     
     @Test
     public void assertWasNull() throws SQLException {
-        assertFalse(new EncryptMergedResult(metaData, mergedResult, true).wasNull());
+        assertFalse(new EncryptMergedResult(metaData, mergedResult).wasNull());
     }
 }
diff --git a/shardingsphere-test/shardingsphere-rewrite-test/src/test/java/org/apache/shardingsphere/sharding/rewrite/parameterized/scenario/EncryptSQLRewriterParameterizedTest.java b/shardingsphere-test/shardingsphere-rewrite-test/src/test/java/org/apache/shardingsphere/sharding/rewrite/parameterized/scenario/EncryptSQLRewriterParameterizedTest.java
index 92bd5d9..43adbaa 100644
--- a/shardingsphere-test/shardingsphere-rewrite-test/src/test/java/org/apache/shardingsphere/sharding/rewrite/parameterized/scenario/EncryptSQLRewriterParameterizedTest.java
+++ b/shardingsphere-test/shardingsphere-rewrite-test/src/test/java/org/apache/shardingsphere/sharding/rewrite/parameterized/scenario/EncryptSQLRewriterParameterizedTest.java
@@ -64,6 +64,7 @@ public final class EncryptSQLRewriterParameterizedTest extends AbstractSQLRewrit
         ShardingSphereSchema result = mock(ShardingSphereSchema.class);
         when(result.getAllColumnNames("t_account")).thenReturn(Arrays.asList("account_id", "certificate_number", "password", "amount", "status"));
         when(result.getAllColumnNames("t_account_bak")).thenReturn(Arrays.asList("account_id", "certificate_number", "password", "amount", "status"));
+        when(result.getAllColumnNames("t_account_detail")).thenReturn(Arrays.asList("account_id", "certificate_number", "password", "amount", "status"));
         return result;
     }
     
@@ -73,6 +74,7 @@ public final class EncryptSQLRewriterParameterizedTest extends AbstractSQLRewrit
         if (singleTableRule.isPresent()) {
             singleTableRule.get().put("t_account", "encrypt_ds");
             singleTableRule.get().put("t_account_bak", "encrypt_ds");
+            singleTableRule.get().put("t_account_detail", "encrypt_ds");
         }
     }
 }
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 665929d..acfdaf3 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
@@ -128,4 +128,14 @@
         <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-assertion id="select_plain_with_table_level_query_with_cipher_column_for_parameters" db-types="MySQL">
+        <input sql="SELECT a.account_id, a.password, a.amount AS a, a.status AS s FROM t_account_detail AS a WHERE a.account_id = ? AND a.password = ? AND a.amount = ? AND a.status = ?" parameters="1, aaa, 1000, OK" />
+        <output sql="SELECT a.account_id, a.plain_password AS password, a.plain_amount AS a, a.status AS s FROM t_account_detail AS a WHERE a.account_id = ? AND a.plain_password = ? AND a.plain_amount = ? AND a.status = ?" parameters="1, aaa, 1000, OK" />
+    </rewrite-assertion>
+    
+    <rewrite-assertion id="select_plain_with_table_level_query_with_cipher_column_for_literals" db-types="MySQL">
+        <input sql="SELECT a.account_id, a.password, a.amount AS a, a.status AS s FROM t_account_detail AS a WHERE a.account_id = 1 AND a.password = 'aaa' AND a.amount = '1000' AND a.status = 'OK'" />
+        <output sql="SELECT a.account_id, a.plain_password AS password, a.plain_amount AS a, a.status AS s FROM t_account_detail AS a WHERE a.account_id = 1 AND a.plain_password = 'aaa' AND a.plain_amount = '1000' AND a.status = 'OK'" />
+    </rewrite-assertion>
 </rewrite-assertions>
diff --git a/shardingsphere-test/shardingsphere-rewrite-test/src/test/resources/scenario/encrypt/case/select_for_query_with_plain.xml b/shardingsphere-test/shardingsphere-rewrite-test/src/test/resources/scenario/encrypt/case/select_for_query_with_plain.xml
index cb95001..9fd97db 100644
--- a/shardingsphere-test/shardingsphere-rewrite-test/src/test/resources/scenario/encrypt/case/select_for_query_with_plain.xml
+++ b/shardingsphere-test/shardingsphere-rewrite-test/src/test/resources/scenario/encrypt/case/select_for_query_with_plain.xml
@@ -51,4 +51,14 @@
         <input sql="SELECT t_account.password from t_account, t_account_bak where t_account.account_id = t_account_bak.account_id"/>
         <output sql="SELECT t_account.cipher_password AS password from t_account, t_account_bak where t_account.account_id = t_account_bak.account_id"/>
     </rewrite-assertion>
+
+    <rewrite-assertion id="select_cipher_with_table_level_query_with_cipher_column_for_parameters" db-types="MySQL">
+        <input sql="SELECT a.account_id, a.password, a.amount AS a, a.status AS s FROM t_account_detail AS a WHERE a.account_id = ? AND a.password = ? AND a.amount = ? AND a.status = ?" parameters="1, aaa, 1000, OK" />
+        <output sql="SELECT a.account_id, a.cipher_password AS password, a.cipher_amount AS a, a.status AS s FROM t_account_detail AS a WHERE a.account_id = ? AND a.assisted_query_password = ? AND a.cipher_amount = ? AND a.status = ?" parameters="1, assisted_query_aaa, encrypt_1000, OK" />
+    </rewrite-assertion>
+
+    <rewrite-assertion id="select_cipher_with_table_level_query_with_cipher_column_for_literals" db-types="MySQL">
+        <input sql="SELECT a.account_id, a.password, a.amount AS a, a.status AS s FROM t_account_detail AS a WHERE a.account_id = 1 AND a.password = 'aaa' AND a.amount = 1000 AND a.status = 'OK'" />
+        <output sql="SELECT a.account_id, a.cipher_password AS password, a.cipher_amount AS a, a.status AS s FROM t_account_detail AS a WHERE a.account_id = 1 AND a.assisted_query_password = 'assisted_query_aaa' AND a.cipher_amount = 'encrypt_1000' AND a.status = 'OK'" />
+    </rewrite-assertion>
 </rewrite-assertions>
diff --git a/shardingsphere-test/shardingsphere-rewrite-test/src/test/resources/scenario/encrypt/config/query-with-cipher.yaml b/shardingsphere-test/shardingsphere-rewrite-test/src/test/resources/scenario/encrypt/config/query-with-cipher.yaml
index e7ec13b..a34daea 100644
--- a/shardingsphere-test/shardingsphere-rewrite-test/src/test/resources/scenario/encrypt/config/query-with-cipher.yaml
+++ b/shardingsphere-test/shardingsphere-rewrite-test/src/test/resources/scenario/encrypt/config/query-with-cipher.yaml
@@ -55,6 +55,23 @@ rules:
           cipherColumn: cipher_amount
           plainColumn: plain_amount
           encryptorName: normal
+    t_account_detail:
+      columns:
+        certificate_number:
+          cipherColumn: cipher_certificate_number
+          assistedQueryColumn: assisted_query_certificate_number
+          plainColumn: plain_certificate_number
+          encryptorName: assisted_query
+        password:
+          cipherColumn: cipher_password
+          assistedQueryColumn: assisted_query_password
+          plainColumn: plain_password
+          encryptorName: assisted_query
+        amount:
+          cipherColumn: cipher_amount
+          plainColumn: plain_amount
+          encryptorName: normal
+      queryWithCipherColumn: false
   encryptors:
     normal:
       type: NORMAL_ENCRYPT
diff --git a/shardingsphere-test/shardingsphere-rewrite-test/src/test/resources/scenario/encrypt/config/query-with-plain.yaml b/shardingsphere-test/shardingsphere-rewrite-test/src/test/resources/scenario/encrypt/config/query-with-plain.yaml
index aeeb109..d7e4124 100644
--- a/shardingsphere-test/shardingsphere-rewrite-test/src/test/resources/scenario/encrypt/config/query-with-plain.yaml
+++ b/shardingsphere-test/shardingsphere-rewrite-test/src/test/resources/scenario/encrypt/config/query-with-plain.yaml
@@ -54,6 +54,22 @@ rules:
           cipherColumn: cipher_amount
           plainColumn: plain_amount
           encryptorName: normal
+    t_account_detail:
+      columns:
+        certificate_number:
+          cipherColumn: cipher_certificate_number
+          assistedQueryColumn: assisted_query_certificate_number
+          encryptorName: assisted_query
+        password:
+          cipherColumn: cipher_password
+          assistedQueryColumn: assisted_query_password
+          plainColumn: plain_password
+          encryptorName: assisted_query
+        amount:
+          cipherColumn: cipher_amount
+          plainColumn: plain_amount
+          encryptorName: normal
+      queryWithCipherColumn: true
   encryptors:
     normal:
       type: NORMAL_ENCRYPT