You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shardingsphere.apache.org by me...@apache.org on 2020/11/11 23:18:24 UTC

[shardingsphere] branch master updated: Remove EncryptColumnMetaData (#8140)

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

menghaoran 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 ab325a0  Remove EncryptColumnMetaData (#8140)
ab325a0 is described below

commit ab325a0ff50bedc37a1bef92d2ef8c13ad2d3237
Author: Liang Zhang <te...@163.com>
AuthorDate: Thu Nov 12 07:07:11 2020 +0800

    Remove EncryptColumnMetaData (#8140)
    
    * Decouple EncryptColumnMetaData
    
    * Remove EncryptColumnMetaData
---
 .../encrypt/metadata/EncryptColumnMetaData.java    |  46 -------
 .../metadata/EncryptTableMetaDataBuilder.java      |   7 +-
 .../merge/dal/EncryptDALResultDecorator.java       |  14 +--
 .../impl/DecoratedEncryptColumnsMergedResult.java  |   6 +-
 .../merge/dal/impl/EncryptColumnsMergedResult.java |  62 +++-------
 .../dal/impl/MergedEncryptColumnsMergedResult.java |   6 +-
 .../merge/dql/EncryptDQLResultDecorator.java       |   8 +-
 .../merge/dal/EncryptDALResultDecoratorTest.java   |  24 ++--
 .../dal/MergedEncryptColumnsMergedResultTest.java  |  62 ++++------
 .../DecoratedEncryptColumnsMergedResultTest.java   |   4 +-
 .../merge/dql/EncryptDQLResultDecoratorTest.java   |  20 ++-
 .../fixture/EncryptColumnsMergedResultFixture.java |   6 +-
 .../dql/impl/EncryptColumnsMergedResultTest.java   | 137 ---------------------
 .../metadata/schema/model/ColumnMetaData.java      |   2 +-
 .../shardingsphere/infra/merge/MergeEngine.java    |   4 +-
 .../merge/engine/decorator/ResultDecorator.java    |  16 +--
 .../decorator/impl/TransparentResultDecorator.java |   9 +-
 .../engine/decorator/impl/TransparentRule.java}    |  27 +---
 .../impl/TransparentResultDecoratorTest.java       |   7 +-
 .../fixture/decorator/ResultDecoratorFixture.java  |  10 +-
 20 files changed, 114 insertions(+), 363 deletions(-)

diff --git a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-common/src/main/java/org/apache/shardingsphere/encrypt/metadata/EncryptColumnMetaData.java b/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-common/src/main/java/org/apache/shardingsphere/encrypt/metadata/EncryptColumnMetaData.java
deleted file mode 100644
index ad2fc15..0000000
--- a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-common/src/main/java/org/apache/shardingsphere/encrypt/metadata/EncryptColumnMetaData.java
+++ /dev/null
@@ -1,46 +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.encrypt.metadata;
-
-import lombok.EqualsAndHashCode;
-import lombok.Getter;
-import lombok.ToString;
-import org.apache.shardingsphere.infra.metadata.schema.model.ColumnMetaData;
-
-/**
- * Column meta data for encrypt.
- */
-@Getter
-@EqualsAndHashCode(callSuper = true)
-@ToString(callSuper = true)
-public final class EncryptColumnMetaData extends ColumnMetaData {
-    
-    private final String cipherColumnName;
-    
-    private final String plainColumnName;
-    
-    private final String assistedQueryColumnName;
-    
-    public EncryptColumnMetaData(final String name, final int dataType, final String dataTypeName, final boolean primaryKey,
-                                 final String cipherColumnName, final String plainColumnName, final String assistedQueryColumnName) {
-        super(name, dataType, dataTypeName, primaryKey, false, false);
-        this.cipherColumnName = cipherColumnName;
-        this.plainColumnName = plainColumnName;
-        this.assistedQueryColumnName = assistedQueryColumnName;
-    }
-}
diff --git a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-common/src/main/java/org/apache/shardingsphere/encrypt/metadata/EncryptTableMetaDataBuilder.java b/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-common/src/main/java/org/apache/shardingsphere/encrypt/metadata/EncryptTableMetaDataBuilder.java
index 98fc95a..0fa55d3 100644
--- a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-common/src/main/java/org/apache/shardingsphere/encrypt/metadata/EncryptTableMetaDataBuilder.java
+++ b/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-common/src/main/java/org/apache/shardingsphere/encrypt/metadata/EncryptTableMetaDataBuilder.java
@@ -67,11 +67,8 @@ public final class EncryptTableMetaDataBuilder implements RuleBasedTableMetaData
             return originalColumnMetaData;
         }
         String logicColumnName = encryptRule.getLogicColumnOfCipher(tableName, originalColumnMetaData.getName());
-        String plainColumnName = encryptRule.findPlainColumn(tableName, logicColumnName).orElse(null);
-        String assistedQueryColumnName = encryptRule.findAssistedQueryColumn(tableName, logicColumnName).orElse(null);
-        return new EncryptColumnMetaData(
-                logicColumnName, originalColumnMetaData.getDataType(), originalColumnMetaData.getDataTypeName(), originalColumnMetaData.isPrimaryKey(), originalColumnMetaData.getName(),
-                plainColumnName, assistedQueryColumnName);
+        return new ColumnMetaData(logicColumnName, originalColumnMetaData.getDataType(), 
+                originalColumnMetaData.getDataTypeName(), originalColumnMetaData.isPrimaryKey(), originalColumnMetaData.isGenerated(), originalColumnMetaData.isCaseSensitive());
     }
     
     @Override
diff --git a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-merge/src/main/java/org/apache/shardingsphere/encrypt/merge/dal/EncryptDALResultDecorator.java b/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-merge/src/main/java/org/apache/shardingsphere/encrypt/merge/dal/EncryptDALResultDecorator.java
index 780bb04..46e056f 100644
--- a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-merge/src/main/java/org/apache/shardingsphere/encrypt/merge/dal/EncryptDALResultDecorator.java
+++ b/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-merge/src/main/java/org/apache/shardingsphere/encrypt/merge/dal/EncryptDALResultDecorator.java
@@ -19,12 +19,12 @@ package org.apache.shardingsphere.encrypt.merge.dal;
 
 import org.apache.shardingsphere.encrypt.merge.dal.impl.DecoratedEncryptColumnsMergedResult;
 import org.apache.shardingsphere.encrypt.merge.dal.impl.MergedEncryptColumnsMergedResult;
+import org.apache.shardingsphere.encrypt.rule.EncryptRule;
+import org.apache.shardingsphere.infra.binder.statement.SQLStatementContext;
 import org.apache.shardingsphere.infra.executor.sql.QueryResult;
 import org.apache.shardingsphere.infra.merge.engine.decorator.ResultDecorator;
 import org.apache.shardingsphere.infra.merge.result.MergedResult;
 import org.apache.shardingsphere.infra.merge.result.impl.transparent.TransparentMergedResult;
-import org.apache.shardingsphere.infra.metadata.schema.ShardingSphereSchema;
-import org.apache.shardingsphere.infra.binder.statement.SQLStatementContext;
 import org.apache.shardingsphere.sql.parser.sql.common.statement.SQLStatement;
 import org.apache.shardingsphere.sql.parser.sql.dialect.statement.mysql.dal.MySQLDescribeStatement;
 import org.apache.shardingsphere.sql.parser.sql.dialect.statement.mysql.dal.MySQLShowColumnsStatement;
@@ -32,17 +32,17 @@ import org.apache.shardingsphere.sql.parser.sql.dialect.statement.mysql.dal.MySQ
 /**
  * DAL result decorator for encrypt.
  */
-public final class EncryptDALResultDecorator implements ResultDecorator {
+public final class EncryptDALResultDecorator implements ResultDecorator<EncryptRule> {
     
     @Override
-    public MergedResult decorate(final QueryResult queryResult, final SQLStatementContext<?> sqlStatementContext, final ShardingSphereSchema schema) {
+    public MergedResult decorate(final QueryResult queryResult, final SQLStatementContext<?> sqlStatementContext, final EncryptRule rule) {
         return isNeedMergeEncryptColumns(sqlStatementContext.getSqlStatement())
-                ? new MergedEncryptColumnsMergedResult(queryResult, sqlStatementContext, schema) : new TransparentMergedResult(queryResult);
+                ? new MergedEncryptColumnsMergedResult(queryResult, sqlStatementContext, rule) : new TransparentMergedResult(queryResult);
     }
     
     @Override
-    public MergedResult decorate(final MergedResult mergedResult, final SQLStatementContext<?> sqlStatementContext, final ShardingSphereSchema schema) {
-        return isNeedMergeEncryptColumns(sqlStatementContext.getSqlStatement()) ? new DecoratedEncryptColumnsMergedResult(mergedResult, sqlStatementContext, schema) : mergedResult;
+    public MergedResult decorate(final MergedResult mergedResult, final SQLStatementContext<?> sqlStatementContext, final EncryptRule rule) {
+        return isNeedMergeEncryptColumns(sqlStatementContext.getSqlStatement()) ? new DecoratedEncryptColumnsMergedResult(mergedResult, sqlStatementContext, rule) : mergedResult;
     }
     
     private boolean isNeedMergeEncryptColumns(final SQLStatement sqlStatement) {
diff --git a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-merge/src/main/java/org/apache/shardingsphere/encrypt/merge/dal/impl/DecoratedEncryptColumnsMergedResult.java b/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-merge/src/main/java/org/apache/shardingsphere/encrypt/merge/dal/impl/DecoratedEncryptColumnsMergedResult.java
index 0f4b51d..feacf17 100644
--- a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-merge/src/main/java/org/apache/shardingsphere/encrypt/merge/dal/impl/DecoratedEncryptColumnsMergedResult.java
+++ b/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-merge/src/main/java/org/apache/shardingsphere/encrypt/merge/dal/impl/DecoratedEncryptColumnsMergedResult.java
@@ -17,7 +17,7 @@
 
 package org.apache.shardingsphere.encrypt.merge.dal.impl;
 
-import org.apache.shardingsphere.infra.metadata.schema.ShardingSphereSchema;
+import org.apache.shardingsphere.encrypt.rule.EncryptRule;
 import org.apache.shardingsphere.infra.binder.statement.SQLStatementContext;
 import org.apache.shardingsphere.infra.merge.result.MergedResult;
 
@@ -30,8 +30,8 @@ public final class DecoratedEncryptColumnsMergedResult extends EncryptColumnsMer
     
     private final MergedResult mergedResult;
     
-    public DecoratedEncryptColumnsMergedResult(final MergedResult mergedResult, final SQLStatementContext sqlStatementContext, final ShardingSphereSchema schema) {
-        super(sqlStatementContext, schema);
+    public DecoratedEncryptColumnsMergedResult(final MergedResult mergedResult, final SQLStatementContext sqlStatementContext, final EncryptRule encryptRule) {
+        super(sqlStatementContext, encryptRule);
         this.mergedResult = mergedResult;
     }
     
diff --git a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-merge/src/main/java/org/apache/shardingsphere/encrypt/merge/dal/impl/EncryptColumnsMergedResult.java b/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-merge/src/main/java/org/apache/shardingsphere/encrypt/merge/dal/impl/EncryptColumnsMergedResult.java
index 748348d..b7ea910 100644
--- a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-merge/src/main/java/org/apache/shardingsphere/encrypt/merge/dal/impl/EncryptColumnsMergedResult.java
+++ b/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-merge/src/main/java/org/apache/shardingsphere/encrypt/merge/dal/impl/EncryptColumnsMergedResult.java
@@ -18,9 +18,8 @@
 package org.apache.shardingsphere.encrypt.merge.dal.impl;
 
 import com.google.common.base.Preconditions;
-import org.apache.shardingsphere.encrypt.metadata.EncryptColumnMetaData;
-import org.apache.shardingsphere.infra.metadata.schema.model.ColumnMetaData;
-import org.apache.shardingsphere.infra.metadata.schema.ShardingSphereSchema;
+import org.apache.shardingsphere.encrypt.rule.EncryptRule;
+import org.apache.shardingsphere.encrypt.rule.EncryptTable;
 import org.apache.shardingsphere.infra.binder.statement.SQLStatementContext;
 import org.apache.shardingsphere.infra.binder.type.TableAvailable;
 import org.apache.shardingsphere.infra.merge.result.MergedResult;
@@ -29,38 +28,35 @@ import java.io.InputStream;
 import java.sql.SQLException;
 import java.sql.SQLFeatureNotSupportedException;
 import java.util.Calendar;
-import java.util.Collection;
-import java.util.LinkedList;
-import java.util.Map.Entry;
 import java.util.Optional;
-import java.util.stream.Collectors;
 
 /**
  * Encrypt column merged result.
  */
 public abstract class EncryptColumnsMergedResult implements MergedResult {
     
-    private final ShardingSphereSchema schema;
-    
     private final String tableName;
     
-    protected EncryptColumnsMergedResult(final SQLStatementContext sqlStatementContext, final ShardingSphereSchema schema) {
-        this.schema = schema;
+    private final EncryptRule encryptRule;
+    
+    protected EncryptColumnsMergedResult(final SQLStatementContext sqlStatementContext, final EncryptRule encryptRule) {
         Preconditions.checkState(sqlStatementContext instanceof TableAvailable && 1 == ((TableAvailable) sqlStatementContext).getAllTables().size());
         tableName = ((TableAvailable) sqlStatementContext).getAllTables().iterator().next().getTableName().getIdentifier().getValue();
+        this.encryptRule = encryptRule;
     }
     
     @Override
     public final boolean next() throws SQLException { 
         boolean hasNext = nextValue();
-        if (hasNext && getTableEncryptColumnMetaDataList().isEmpty()) {
+        Optional<EncryptTable> encryptTable = encryptRule.findEncryptTable(tableName);
+        if (hasNext && !encryptTable.isPresent()) {
             return true;
         }
         if (!hasNext) {
             return false;
         }
         String columnName = getOriginalValue(1, String.class).toString();
-        while (getAssistedQueryColumns().contains(columnName) || getPlainColumns().contains(columnName)) {
+        while (encryptTable.get().getAssistedQueryColumns().contains(columnName) || encryptTable.get().getPlainColumns().contains(columnName)) {
             hasNext = nextValue();
             if (!hasNext) {
                 return false;
@@ -70,48 +66,20 @@ public abstract class EncryptColumnsMergedResult implements MergedResult {
         return true;
     }
     
-    private Collection<String> getAssistedQueryColumns() {
-        return getTableEncryptColumnMetaDataList().stream().map(EncryptColumnMetaData::getAssistedQueryColumnName)
-                .collect(Collectors.toList());
-    }
-    
-    private Collection<String> getPlainColumns() {
-        return getTableEncryptColumnMetaDataList().stream().map(EncryptColumnMetaData::getPlainColumnName)
-                .collect(Collectors.toList());
-    }
-    
-    private Collection<EncryptColumnMetaData> getTableEncryptColumnMetaDataList() {
-        Collection<EncryptColumnMetaData> result = new LinkedList<>();
-        for (Entry<String, ColumnMetaData> entry : schema.get(tableName).getColumns().entrySet()) {
-            if (entry.getValue() instanceof EncryptColumnMetaData) {
-                result.add((EncryptColumnMetaData) entry.getValue());
-            }
-        }
-        return result;
-    }
-    
     @Override
     public final Object getValue(final int columnIndex, final Class<?> type) throws SQLException {
         if (1 == columnIndex) {
             String columnName = getOriginalValue(1, type).toString();
-            Optional<String> logicColumn = getLogicColumnOfCipher(columnName);
+            Optional<EncryptTable> encryptTable = encryptRule.findEncryptTable(tableName);
+            if (!encryptTable.isPresent()) {
+                return columnName;
+            }
+            Optional<String> logicColumn = encryptTable.get().isCipherColumn(columnName) ? Optional.of(encryptTable.get().getLogicColumn(columnName)) : Optional.empty();
             return logicColumn.orElse(columnName);
         }
         return getOriginalValue(columnIndex, type);
     }
-    
-    private Optional<String> getLogicColumnOfCipher(final String cipherColumn) {
-        for (Entry<String, ColumnMetaData> entry : schema.get(tableName).getColumns().entrySet()) {
-            if (entry.getValue() instanceof EncryptColumnMetaData) {
-                EncryptColumnMetaData encryptColumnMetaData = (EncryptColumnMetaData) entry.getValue();
-                if (encryptColumnMetaData.getCipherColumnName().equalsIgnoreCase(cipherColumn)) {
-                    return Optional.of(entry.getKey());
-                }
-            }
-        }
-        return Optional.empty();
-    }
-    
+
     @Override
     public final Object getCalendarValue(final int columnIndex, final Class<?> type, final Calendar calendar) throws SQLException {
         throw new SQLFeatureNotSupportedException("");
diff --git a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-merge/src/main/java/org/apache/shardingsphere/encrypt/merge/dal/impl/MergedEncryptColumnsMergedResult.java b/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-merge/src/main/java/org/apache/shardingsphere/encrypt/merge/dal/impl/MergedEncryptColumnsMergedResult.java
index 5d81088..2977a63 100644
--- a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-merge/src/main/java/org/apache/shardingsphere/encrypt/merge/dal/impl/MergedEncryptColumnsMergedResult.java
+++ b/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-merge/src/main/java/org/apache/shardingsphere/encrypt/merge/dal/impl/MergedEncryptColumnsMergedResult.java
@@ -17,7 +17,7 @@
 
 package org.apache.shardingsphere.encrypt.merge.dal.impl;
 
-import org.apache.shardingsphere.infra.metadata.schema.ShardingSphereSchema;
+import org.apache.shardingsphere.encrypt.rule.EncryptRule;
 import org.apache.shardingsphere.infra.binder.statement.SQLStatementContext;
 import org.apache.shardingsphere.infra.executor.sql.QueryResult;
 
@@ -30,8 +30,8 @@ public final class MergedEncryptColumnsMergedResult extends EncryptColumnsMerged
     
     private final QueryResult queryResult;
     
-    public MergedEncryptColumnsMergedResult(final QueryResult queryResult, final SQLStatementContext sqlStatementContext, final ShardingSphereSchema schema) {
-        super(sqlStatementContext, schema);
+    public MergedEncryptColumnsMergedResult(final QueryResult queryResult, final SQLStatementContext sqlStatementContext, final EncryptRule encryptRule) {
+        super(sqlStatementContext, encryptRule);
         this.queryResult = queryResult;
     }
     
diff --git a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-merge/src/main/java/org/apache/shardingsphere/encrypt/merge/dql/EncryptDQLResultDecorator.java b/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-merge/src/main/java/org/apache/shardingsphere/encrypt/merge/dql/EncryptDQLResultDecorator.java
index 4309f85..7ca5e99 100644
--- a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-merge/src/main/java/org/apache/shardingsphere/encrypt/merge/dql/EncryptDQLResultDecorator.java
+++ b/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-merge/src/main/java/org/apache/shardingsphere/encrypt/merge/dql/EncryptDQLResultDecorator.java
@@ -18,7 +18,7 @@
 package org.apache.shardingsphere.encrypt.merge.dql;
 
 import lombok.RequiredArgsConstructor;
-import org.apache.shardingsphere.infra.metadata.schema.ShardingSphereSchema;
+import org.apache.shardingsphere.encrypt.rule.EncryptRule;
 import org.apache.shardingsphere.infra.binder.statement.SQLStatementContext;
 import org.apache.shardingsphere.infra.executor.sql.QueryResult;
 import org.apache.shardingsphere.infra.merge.engine.decorator.ResultDecorator;
@@ -29,19 +29,19 @@ import org.apache.shardingsphere.infra.merge.result.impl.transparent.Transparent
  * DQL result decorator for encrypt.
  */
 @RequiredArgsConstructor
-public final class EncryptDQLResultDecorator implements ResultDecorator {
+public final class EncryptDQLResultDecorator implements ResultDecorator<EncryptRule> {
     
     private final EncryptAlgorithmMetaData metaData;
     
     private final boolean queryWithCipherColumn;
     
     @Override
-    public MergedResult decorate(final QueryResult queryResult, final SQLStatementContext<?> sqlStatementContext, final ShardingSphereSchema schema) {
+    public MergedResult decorate(final QueryResult queryResult, final SQLStatementContext<?> sqlStatementContext, final EncryptRule rule) {
         return new EncryptMergedResult(metaData, new TransparentMergedResult(queryResult), queryWithCipherColumn);
     }
     
     @Override
-    public MergedResult decorate(final MergedResult mergedResult, final SQLStatementContext<?> sqlStatementContext, final ShardingSphereSchema schema) {
+    public MergedResult decorate(final MergedResult mergedResult, final SQLStatementContext<?> sqlStatementContext, final EncryptRule rule) {
         return new EncryptMergedResult(metaData, mergedResult, queryWithCipherColumn);
     }
 }
diff --git a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-merge/src/test/java/org/apache/shardingsphere/encrypt/merge/dal/EncryptDALResultDecoratorTest.java b/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-merge/src/test/java/org/apache/shardingsphere/encrypt/merge/dal/EncryptDALResultDecoratorTest.java
index 433b5d7..6a61c7b 100644
--- a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-merge/src/test/java/org/apache/shardingsphere/encrypt/merge/dal/EncryptDALResultDecoratorTest.java
+++ b/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-merge/src/test/java/org/apache/shardingsphere/encrypt/merge/dal/EncryptDALResultDecoratorTest.java
@@ -19,18 +19,19 @@ package org.apache.shardingsphere.encrypt.merge.dal;
 
 import org.apache.shardingsphere.encrypt.merge.dal.impl.DecoratedEncryptColumnsMergedResult;
 import org.apache.shardingsphere.encrypt.merge.dal.impl.MergedEncryptColumnsMergedResult;
+import org.apache.shardingsphere.encrypt.rule.EncryptRule;
+import org.apache.shardingsphere.infra.binder.statement.SQLStatementContext;
+import org.apache.shardingsphere.infra.binder.statement.dal.DescribeStatementContext;
+import org.apache.shardingsphere.infra.binder.statement.dal.ShowColumnsStatementContext;
 import org.apache.shardingsphere.infra.executor.sql.QueryResult;
 import org.apache.shardingsphere.infra.merge.result.MergedResult;
 import org.apache.shardingsphere.infra.merge.result.impl.transparent.TransparentMergedResult;
 import org.apache.shardingsphere.infra.metadata.schema.ShardingSphereSchema;
-import org.apache.shardingsphere.infra.binder.statement.SQLStatementContext;
-import org.apache.shardingsphere.infra.binder.statement.dal.DescribeStatementContext;
-import org.apache.shardingsphere.infra.binder.statement.dal.ShowColumnsStatementContext;
 import org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.SimpleTableSegment;
 import org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.TableNameSegment;
+import org.apache.shardingsphere.sql.parser.sql.common.value.identifier.IdentifierValue;
 import org.apache.shardingsphere.sql.parser.sql.dialect.statement.mysql.dal.MySQLDescribeStatement;
 import org.apache.shardingsphere.sql.parser.sql.dialect.statement.mysql.dal.MySQLShowColumnsStatement;
-import org.apache.shardingsphere.sql.parser.sql.common.value.identifier.IdentifierValue;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
@@ -48,6 +49,9 @@ public final class EncryptDALResultDecoratorTest {
     
     @Mock
     private ShardingSphereSchema schema;
+
+    @Mock
+    private EncryptRule rule;
     
     @Mock
     private SQLStatementContext<?> sqlStatementContext;
@@ -57,8 +61,8 @@ public final class EncryptDALResultDecoratorTest {
         schema = mock(ShardingSphereSchema.class);
         sqlStatementContext = getDescribeStatementContext();
         EncryptDALResultDecorator encryptDALResultDecorator = new EncryptDALResultDecorator();
-        assertThat(encryptDALResultDecorator.decorate(mock(QueryResult.class), sqlStatementContext, schema), instanceOf(MergedEncryptColumnsMergedResult.class));
-        assertThat(encryptDALResultDecorator.decorate(mock(MergedResult.class), sqlStatementContext, schema), instanceOf(DecoratedEncryptColumnsMergedResult.class));
+        assertThat(encryptDALResultDecorator.decorate(mock(QueryResult.class), sqlStatementContext, rule), instanceOf(MergedEncryptColumnsMergedResult.class));
+        assertThat(encryptDALResultDecorator.decorate(mock(MergedResult.class), sqlStatementContext, rule), instanceOf(DecoratedEncryptColumnsMergedResult.class));
     }
     
     @Test
@@ -66,8 +70,8 @@ public final class EncryptDALResultDecoratorTest {
         schema = mock(ShardingSphereSchema.class);
         sqlStatementContext = getShowColumnsStatementContext();
         EncryptDALResultDecorator encryptDALResultDecorator = new EncryptDALResultDecorator();
-        assertThat(encryptDALResultDecorator.decorate(mock(QueryResult.class), sqlStatementContext, schema), instanceOf(MergedEncryptColumnsMergedResult.class));
-        assertThat(encryptDALResultDecorator.decorate(mock(MergedResult.class), sqlStatementContext, schema), instanceOf(DecoratedEncryptColumnsMergedResult.class));
+        assertThat(encryptDALResultDecorator.decorate(mock(QueryResult.class), sqlStatementContext, rule), instanceOf(MergedEncryptColumnsMergedResult.class));
+        assertThat(encryptDALResultDecorator.decorate(mock(MergedResult.class), sqlStatementContext, rule), instanceOf(DecoratedEncryptColumnsMergedResult.class));
     }
     
     @Test
@@ -75,8 +79,8 @@ public final class EncryptDALResultDecoratorTest {
         schema = mock(ShardingSphereSchema.class);
         sqlStatementContext = mock(SQLStatementContext.class);
         EncryptDALResultDecorator encryptDALResultDecorator = new EncryptDALResultDecorator();
-        assertThat(encryptDALResultDecorator.decorate(mock(QueryResult.class), sqlStatementContext, schema), instanceOf(TransparentMergedResult.class));
-        assertThat(encryptDALResultDecorator.decorate(mock(MergedResult.class), sqlStatementContext, schema), instanceOf(MergedResult.class));
+        assertThat(encryptDALResultDecorator.decorate(mock(QueryResult.class), sqlStatementContext, rule), instanceOf(TransparentMergedResult.class));
+        assertThat(encryptDALResultDecorator.decorate(mock(MergedResult.class), sqlStatementContext, rule), instanceOf(MergedResult.class));
     }
     
     private SQLStatementContext<?> getDescribeStatementContext() {
diff --git a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-merge/src/test/java/org/apache/shardingsphere/encrypt/merge/dal/MergedEncryptColumnsMergedResultTest.java b/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-merge/src/test/java/org/apache/shardingsphere/encrypt/merge/dal/MergedEncryptColumnsMergedResultTest.java
index e996e7a..0e278af 100644
--- a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-merge/src/test/java/org/apache/shardingsphere/encrypt/merge/dal/MergedEncryptColumnsMergedResultTest.java
+++ b/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-merge/src/test/java/org/apache/shardingsphere/encrypt/merge/dal/MergedEncryptColumnsMergedResultTest.java
@@ -18,11 +18,10 @@
 package org.apache.shardingsphere.encrypt.merge.dal;
 
 import org.apache.shardingsphere.encrypt.merge.dal.impl.MergedEncryptColumnsMergedResult;
-import org.apache.shardingsphere.encrypt.metadata.EncryptColumnMetaData;
-import org.apache.shardingsphere.infra.executor.sql.QueryResult;
-import org.apache.shardingsphere.infra.metadata.schema.ShardingSphereSchema;
-import org.apache.shardingsphere.infra.metadata.schema.model.TableMetaData;
+import org.apache.shardingsphere.encrypt.rule.EncryptRule;
+import org.apache.shardingsphere.encrypt.rule.EncryptTable;
 import org.apache.shardingsphere.infra.binder.statement.dml.SelectStatementContext;
+import org.apache.shardingsphere.infra.executor.sql.QueryResult;
 import org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.SimpleTableSegment;
 import org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.TableNameSegment;
 import org.apache.shardingsphere.sql.parser.sql.common.value.identifier.IdentifierValue;
@@ -32,10 +31,8 @@ import org.mockito.Mock;
 import org.mockito.junit.MockitoJUnitRunner;
 
 import java.sql.SQLException;
-import java.sql.Types;
 import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
+import java.util.Optional;
 
 import static org.hamcrest.CoreMatchers.is;
 import static org.junit.Assert.assertFalse;
@@ -51,71 +48,62 @@ public final class MergedEncryptColumnsMergedResultTest {
     private QueryResult queryResult;
     
     @Test
-    public void assertNextWithTableEncryptColumnMetaDataListEmpty() throws SQLException {
-        when(queryResult.next()).thenReturn(true);
-        TableMetaData tableMetaData = new TableMetaData(Collections.emptyList(), Collections.emptyList());
-        Map<String, TableMetaData> tables = new HashMap<>(1, 1);
-        tables.put("test", tableMetaData);
-        assertTrue(createMergedEncryptColumnsMergedResult(queryResult, new ShardingSphereSchema(tables)).next());
+    public void assertNextWithNotHasNext() throws SQLException {
+        assertFalse(createMergedEncryptColumnsMergedResult(queryResult, mock(EncryptRule.class)).next());
     }
     
     @Test
     public void assertNextWithHasNext() throws SQLException {
-        assertFalse(createMergedEncryptColumnsMergedResult(queryResult, mock(ShardingSphereSchema.class)).next());
+        when(queryResult.next()).thenReturn(true);
+        assertTrue(createMergedEncryptColumnsMergedResult(queryResult, mock(EncryptRule.class)).next());
     }
     
     @Test
     public void assertNextWithAssistedQuery() throws SQLException {
         when(queryResult.next()).thenReturn(true).thenReturn(false);
         when(queryResult.getValue(1, String.class)).thenReturn("assistedQuery");
-        EncryptColumnMetaData encryptColumnMetaData = new EncryptColumnMetaData("id", Types.VARCHAR, "varchar", true, "cipher", "plain", "assistedQuery");
-        TableMetaData tableMetaData = new TableMetaData(Collections.singletonList(encryptColumnMetaData), Collections.emptyList());
-        Map<String, TableMetaData> tables = new HashMap<>(1, 1);
-        tables.put("test", tableMetaData);
-        assertFalse(createMergedEncryptColumnsMergedResult(queryResult, new ShardingSphereSchema(tables)).next());
+        assertFalse(createMergedEncryptColumnsMergedResult(queryResult, mockEncryptRule()).next());
     }
     
     @Test
     public void assertGetValueWithCipherColumn() throws SQLException {
         when(queryResult.getValue(1, String.class)).thenReturn("cipher");
-        EncryptColumnMetaData encryptColumnMetaData = new EncryptColumnMetaData("id", Types.VARCHAR, "varchar", true, "cipher", "plain", "assistedQuery");
-        TableMetaData tableMetaData = new TableMetaData(Collections.singletonList(encryptColumnMetaData), Collections.emptyList());
-        Map<String, TableMetaData> tables = new HashMap<>(1);
-        tables.put("test", tableMetaData);
-        assertThat(createMergedEncryptColumnsMergedResult(queryResult, new ShardingSphereSchema(tables)).getValue(1, String.class), is("id"));
+        assertThat(createMergedEncryptColumnsMergedResult(queryResult, mockEncryptRule()).getValue(1, String.class), is("id"));
+    }
+    
+    private EncryptRule mockEncryptRule() {
+        EncryptRule encryptRule = mock(EncryptRule.class);
+        EncryptTable encryptTable = mock(EncryptTable.class);
+        when(encryptRule.findEncryptTable("test")).thenReturn(Optional.of(encryptTable));
+        when(encryptTable.getAssistedQueryColumns()).thenReturn(Collections.singleton("assistedQuery"));
+        when(encryptTable.isCipherColumn("cipher")).thenReturn(true);
+        when(encryptTable.getLogicColumn("cipher")).thenReturn("id");
+        return encryptRule;
     }
     
     @Test
     public void assertGetValueWithOtherColumn() throws SQLException {
         when(queryResult.getValue(1, String.class)).thenReturn("assistedQuery");
-        EncryptColumnMetaData encryptColumnMetaData = new EncryptColumnMetaData("id", Types.VARCHAR, "varchar", true, "cipher", "plain", "assistedQuery");
-        TableMetaData tableMetaData = new TableMetaData(Collections.singletonList(encryptColumnMetaData), Collections.emptyList());
-        Map<String, TableMetaData> tables = new HashMap<>(1, 1);
-        tables.put("test", tableMetaData);
-        assertThat(createMergedEncryptColumnsMergedResult(queryResult, new ShardingSphereSchema(tables)).getValue(1, String.class), is("assistedQuery"));
+        assertThat(createMergedEncryptColumnsMergedResult(queryResult, mock(EncryptRule.class)).getValue(1, String.class), is("assistedQuery"));
     }
     
     @Test
     public void assertGetValueWithOtherIndex() throws SQLException {
         when(queryResult.getValue(2, String.class)).thenReturn("id");
-        EncryptColumnMetaData encryptColumnMetaData = new EncryptColumnMetaData("id", Types.VARCHAR, "varchar", true, "cipher", "plain", "assistedQuery");
-        TableMetaData tableMetaData = new TableMetaData(Collections.singletonList(encryptColumnMetaData), Collections.emptyList());
-        Map<String, TableMetaData> tables = new HashMap<>(1, 1);
-        tables.put("test", tableMetaData);
-        assertThat(createMergedEncryptColumnsMergedResult(queryResult, new ShardingSphereSchema(tables)).getValue(2, String.class), is("id"));
+        assertThat(createMergedEncryptColumnsMergedResult(queryResult, mock(EncryptRule.class)).getValue(2, String.class), is("id"));
     }
     
     @Test
     public void assertWasNull() throws SQLException {
-        assertFalse(createMergedEncryptColumnsMergedResult(queryResult, mock(ShardingSphereSchema.class)).wasNull());
+        assertFalse(createMergedEncryptColumnsMergedResult(queryResult, mock(EncryptRule.class)).wasNull());
     }
     
-    private MergedEncryptColumnsMergedResult createMergedEncryptColumnsMergedResult(final QueryResult queryResult, final ShardingSphereSchema schema) {
+    private MergedEncryptColumnsMergedResult createMergedEncryptColumnsMergedResult(final QueryResult queryResult, final EncryptRule encryptRule) {
         SelectStatementContext sqlStatementContext = mock(SelectStatementContext.class);
         IdentifierValue identifierValue = new IdentifierValue("test");
         TableNameSegment tableNameSegment = new TableNameSegment(1, 4, identifierValue);
         SimpleTableSegment simpleTableSegment = new SimpleTableSegment(tableNameSegment);
         when(sqlStatementContext.getAllTables()).thenReturn(Collections.singletonList(simpleTableSegment));
-        return new MergedEncryptColumnsMergedResult(queryResult, sqlStatementContext, schema);
+        return new MergedEncryptColumnsMergedResult(queryResult, sqlStatementContext, encryptRule);
     }
 }
diff --git a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-merge/src/test/java/org/apache/shardingsphere/encrypt/merge/dal/impl/DecoratedEncryptColumnsMergedResultTest.java b/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-merge/src/test/java/org/apache/shardingsphere/encrypt/merge/dal/impl/DecoratedEncryptColumnsMergedResultTest.java
index 150cc8d..a5fa8b5 100644
--- a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-merge/src/test/java/org/apache/shardingsphere/encrypt/merge/dal/impl/DecoratedEncryptColumnsMergedResultTest.java
+++ b/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-merge/src/test/java/org/apache/shardingsphere/encrypt/merge/dal/impl/DecoratedEncryptColumnsMergedResultTest.java
@@ -18,8 +18,8 @@
 package org.apache.shardingsphere.encrypt.merge.dal.impl;
 
 import org.apache.shardingsphere.encrypt.merge.dal.impl.fixture.TestStatementContext;
+import org.apache.shardingsphere.encrypt.rule.EncryptRule;
 import org.apache.shardingsphere.infra.merge.result.MergedResult;
-import org.apache.shardingsphere.infra.metadata.schema.ShardingSphereSchema;
 import org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.SimpleTableSegment;
 import org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.TableNameSegment;
 import org.apache.shardingsphere.sql.parser.sql.common.value.identifier.IdentifierValue;
@@ -52,7 +52,7 @@ public final class DecoratedEncryptColumnsMergedResultTest {
         when(mergedResult.next()).thenReturn(true);
         when(mergedResult.wasNull()).thenReturn(false);
         when(mergedResult.getValue(eq(new Integer(1)), eq(getClass()))).thenReturn("test");
-        DecoratedEncryptColumnsMergedResult actual = new DecoratedEncryptColumnsMergedResult(mergedResult, testStatementContext, mock(ShardingSphereSchema.class));
+        DecoratedEncryptColumnsMergedResult actual = new DecoratedEncryptColumnsMergedResult(mergedResult, testStatementContext, mock(EncryptRule.class));
         assertNotNull(actual);
         assertTrue(actual.nextValue());
         assertFalse(actual.wasNull());
diff --git a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-merge/src/test/java/org/apache/shardingsphere/encrypt/merge/dql/EncryptDQLResultDecoratorTest.java b/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-merge/src/test/java/org/apache/shardingsphere/encrypt/merge/dql/EncryptDQLResultDecoratorTest.java
index 1be02d3..fdd5cca 100644
--- a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-merge/src/test/java/org/apache/shardingsphere/encrypt/merge/dql/EncryptDQLResultDecoratorTest.java
+++ b/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-merge/src/test/java/org/apache/shardingsphere/encrypt/merge/dql/EncryptDQLResultDecoratorTest.java
@@ -17,10 +17,10 @@
 
 package org.apache.shardingsphere.encrypt.merge.dql;
 
+import org.apache.shardingsphere.encrypt.rule.EncryptRule;
+import org.apache.shardingsphere.infra.binder.statement.SQLStatementContext;
 import org.apache.shardingsphere.infra.executor.sql.QueryResult;
 import org.apache.shardingsphere.infra.merge.result.MergedResult;
-import org.apache.shardingsphere.infra.metadata.schema.ShardingSphereSchema;
-import org.apache.shardingsphere.infra.binder.statement.SQLStatementContext;
 import org.junit.Test;
 
 import java.sql.SQLException;
@@ -30,26 +30,22 @@ import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
 public final class EncryptDQLResultDecoratorTest {
-
-    private EncryptAlgorithmMetaData metaData;
-
-    private boolean queryWithCipherColumn;
-
+    
     @Test
     public void assertDecorateQueryResult() throws SQLException {
         QueryResult queryResult = mock(QueryResult.class);
         when(queryResult.next()).thenReturn(true);
-        EncryptDQLResultDecorator decorator = new EncryptDQLResultDecorator(metaData, queryWithCipherColumn);
-        MergedResult actual = decorator.decorate(queryResult, mock(SQLStatementContext.class), mock(ShardingSphereSchema.class));
+        EncryptDQLResultDecorator decorator = new EncryptDQLResultDecorator(mock(EncryptAlgorithmMetaData.class), false);
+        MergedResult actual = decorator.decorate(queryResult, mock(SQLStatementContext.class), mock(EncryptRule.class));
         assertTrue(actual.next());
     }
-
+    
     @Test
     public void assertDecorateMergedResult() throws SQLException {
         MergedResult mergedResult = mock(MergedResult.class);
         when(mergedResult.next()).thenReturn(true);
-        EncryptDQLResultDecorator decorator = new EncryptDQLResultDecorator(metaData, queryWithCipherColumn);
-        MergedResult actual = decorator.decorate(mergedResult, mock(SQLStatementContext.class), mock(ShardingSphereSchema.class));
+        EncryptDQLResultDecorator decorator = new EncryptDQLResultDecorator(mock(EncryptAlgorithmMetaData.class), false);
+        MergedResult actual = decorator.decorate(mergedResult, mock(SQLStatementContext.class), mock(EncryptRule.class));
         assertTrue(actual.next());
     }
 }
diff --git a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-merge/src/test/java/org/apache/shardingsphere/encrypt/merge/dql/fixture/EncryptColumnsMergedResultFixture.java b/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-merge/src/test/java/org/apache/shardingsphere/encrypt/merge/dql/fixture/EncryptColumnsMergedResultFixture.java
index feb4ff7..152e6c9 100644
--- a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-merge/src/test/java/org/apache/shardingsphere/encrypt/merge/dql/fixture/EncryptColumnsMergedResultFixture.java
+++ b/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-merge/src/test/java/org/apache/shardingsphere/encrypt/merge/dql/fixture/EncryptColumnsMergedResultFixture.java
@@ -18,13 +18,13 @@
 package org.apache.shardingsphere.encrypt.merge.dql.fixture;
 
 import org.apache.shardingsphere.encrypt.merge.dal.impl.EncryptColumnsMergedResult;
-import org.apache.shardingsphere.infra.metadata.schema.ShardingSphereSchema;
+import org.apache.shardingsphere.encrypt.rule.EncryptRule;
 import org.apache.shardingsphere.infra.binder.statement.SQLStatementContext;
 
 public final class EncryptColumnsMergedResultFixture extends EncryptColumnsMergedResult {
     
-    public EncryptColumnsMergedResultFixture(final SQLStatementContext sqlStatementContext, final ShardingSphereSchema schema) {
-        super(sqlStatementContext, schema);
+    public EncryptColumnsMergedResultFixture(final SQLStatementContext sqlStatementContext, final EncryptRule encryptRule) {
+        super(sqlStatementContext, encryptRule);
     }
     
     @Override
diff --git a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-merge/src/test/java/org/apache/shardingsphere/encrypt/merge/dql/impl/EncryptColumnsMergedResultTest.java b/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-merge/src/test/java/org/apache/shardingsphere/encrypt/merge/dql/impl/EncryptColumnsMergedResultTest.java
deleted file mode 100644
index 66fe8be..0000000
--- a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-merge/src/test/java/org/apache/shardingsphere/encrypt/merge/dql/impl/EncryptColumnsMergedResultTest.java
+++ /dev/null
@@ -1,137 +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.encrypt.merge.dql.impl;
-
-import com.google.common.collect.Lists;
-import org.apache.shardingsphere.encrypt.merge.dql.fixture.EncryptColumnsMergedResultFixture;
-import org.apache.shardingsphere.encrypt.merge.dql.fixture.TableAvailableAndSqlStatementContextFixture;
-import org.apache.shardingsphere.encrypt.metadata.EncryptColumnMetaData;
-import org.apache.shardingsphere.infra.metadata.schema.model.ColumnMetaData;
-import org.apache.shardingsphere.infra.metadata.schema.ShardingSphereSchema;
-import org.apache.shardingsphere.infra.metadata.schema.model.TableMetaData;
-import org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.SimpleTableSegment;
-import org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.TableNameSegment;
-import org.apache.shardingsphere.sql.parser.sql.common.value.identifier.IdentifierValue;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnitRunner;
-
-import java.sql.SQLException;
-import java.sql.SQLFeatureNotSupportedException;
-import java.util.Calendar;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-
-import static org.hamcrest.CoreMatchers.is;
-import static org.junit.Assert.assertThat;
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.when;
-
-@RunWith(MockitoJUnitRunner.class)
-public final class EncryptColumnsMergedResultTest {
-    
-    @Mock
-    private TableAvailableAndSqlStatementContextFixture tableAvailableAndSqlStatementContextFixture;
-    
-    @Mock
-    private ShardingSphereSchema schema;
-    
-    @Mock
-    private TableMetaData tableMetaData;
-    
-    private EncryptColumnsMergedResultFixture encryptColumnsMergedResultFixture;
-    
-    @Before
-    public void setUp() { 
-        Map<String, ColumnMetaData> columns = new HashMap<>(1, 1);
-        EncryptColumnMetaData encryptColumnMetaData = new EncryptColumnMetaData("order", 1, "Integer", false, "status", "status", "status");
-        columns.put("", encryptColumnMetaData);
-        SimpleTableSegment simpleTableSegment = mock(SimpleTableSegment.class);
-        TableNameSegment tableNameSegment = mock(TableNameSegment.class);
-        IdentifierValue identifierValue = mock(IdentifierValue.class);
-        when(tableAvailableAndSqlStatementContextFixture.getAllTables()).thenReturn(Lists.newArrayList(simpleTableSegment));
-        when(simpleTableSegment.getTableName()).thenReturn(tableNameSegment);
-        when(tableNameSegment.getIdentifier()).thenReturn(identifierValue);
-        String tableName = "t_order";
-        when(identifierValue.getValue()).thenReturn(tableName);
-        when(schema.get(anyString())).thenReturn(tableMetaData);
-        when(tableMetaData.getColumns()).thenReturn(columns);
-        encryptColumnsMergedResultFixture = spy(new EncryptColumnsMergedResultFixture(tableAvailableAndSqlStatementContextFixture, schema));
-    }
-    
-    @Test
-    public void assertHasNextWithEmptyColumnMetaData() throws SQLException {
-        when(schema.get(anyString())).thenReturn(tableMetaData);
-        when(tableMetaData.getColumns()).thenReturn(Collections.emptyMap());
-        EncryptColumnsMergedResultFixture encryptColumnsMergedResultFixture = spy(new EncryptColumnsMergedResultFixture(tableAvailableAndSqlStatementContextFixture, schema));
-        when(encryptColumnsMergedResultFixture.nextValue()).thenReturn(true).thenReturn(false);
-        assertThat(encryptColumnsMergedResultFixture.next(), is(true));
-    }
-    
-    @Test
-    public void assertWithoutHasNext() throws SQLException {
-        EncryptColumnsMergedResultFixture encryptColumnsMergedResultFixture = spy(new EncryptColumnsMergedResultFixture(tableAvailableAndSqlStatementContextFixture, schema));
-        when(encryptColumnsMergedResultFixture.nextValue()).thenReturn(false);
-        assertThat(encryptColumnsMergedResultFixture.next(), is(false));
-    }
-    
-    @Test
-    public void assertContainerColumnName() throws SQLException {
-        Map<String, ColumnMetaData> columns = new HashMap<>(1, 1);
-        EncryptColumnMetaData encryptColumnMetaData = new EncryptColumnMetaData("order", 1, "Integer", false, "status", "status", "status");
-        columns.put("", encryptColumnMetaData);
-        when(schema.get(anyString())).thenReturn(tableMetaData);
-        when(tableMetaData.getColumns()).thenReturn(columns);
-        EncryptColumnsMergedResultFixture encryptColumnsMergedResultFixture = spy(new EncryptColumnsMergedResultFixture(tableAvailableAndSqlStatementContextFixture, schema));
-        when(encryptColumnsMergedResultFixture.nextValue()).thenReturn(true).thenReturn(true);
-        when(encryptColumnsMergedResultFixture.getOriginalValue(1, String.class)).thenReturn("status").thenReturn("noInThatCollection");
-        assertThat(encryptColumnsMergedResultFixture.next(), is(true));
-    }
-    
-    @Test
-    public void assertGetValueWithColumnIndex() throws SQLException {
-        Map<String, ColumnMetaData> columns = new HashMap<>(1, 1);
-        EncryptColumnMetaData encryptColumnMetaData = new EncryptColumnMetaData("order", 1, "Integer", false, "status", "status", "status");
-        columns.put("key", encryptColumnMetaData);
-        when(schema.get(anyString())).thenReturn(tableMetaData);
-        when(tableMetaData.getColumns()).thenReturn(columns);
-        when(encryptColumnsMergedResultFixture.getOriginalValue(1, String.class)).thenReturn("status");
-        assertThat(encryptColumnsMergedResultFixture.getValue(1, String.class), is("key"));
-    }
-    
-    @Test
-    public void assertGetValueWithOutColumnIndex() throws SQLException {
-        when(encryptColumnsMergedResultFixture.getOriginalValue(2, String.class)).thenReturn("status");
-        assertThat(encryptColumnsMergedResultFixture.getValue(2, String.class), is("status"));
-    }
-    
-    @Test(expected = SQLFeatureNotSupportedException.class)
-    public void assertGetCalendarValue() throws SQLException {
-        encryptColumnsMergedResultFixture.getCalendarValue(1, String.class, Calendar.getInstance());
-    }
-    
-    @Test(expected = SQLFeatureNotSupportedException.class)
-    public void assertGetInputStream() throws SQLException {
-        encryptColumnsMergedResultFixture.getInputStream(1, "whateverString");
-    }
-}
diff --git a/shardingsphere-infra/shardingsphere-infra-common/src/main/java/org/apache/shardingsphere/infra/metadata/schema/model/ColumnMetaData.java b/shardingsphere-infra/shardingsphere-infra-common/src/main/java/org/apache/shardingsphere/infra/metadata/schema/model/ColumnMetaData.java
index 1883f49..37f7236 100644
--- a/shardingsphere-infra/shardingsphere-infra-common/src/main/java/org/apache/shardingsphere/infra/metadata/schema/model/ColumnMetaData.java
+++ b/shardingsphere-infra/shardingsphere-infra-common/src/main/java/org/apache/shardingsphere/infra/metadata/schema/model/ColumnMetaData.java
@@ -29,7 +29,7 @@ import lombok.ToString;
 @Getter
 @EqualsAndHashCode
 @ToString
-public class ColumnMetaData {
+public final class ColumnMetaData {
     
     private final String name;
     
diff --git a/shardingsphere-infra/shardingsphere-infra-merge/src/main/java/org/apache/shardingsphere/infra/merge/MergeEngine.java b/shardingsphere-infra/shardingsphere-infra-merge/src/main/java/org/apache/shardingsphere/infra/merge/MergeEngine.java
index e179529..eb4bf4d 100644
--- a/shardingsphere-infra/shardingsphere-infra-merge/src/main/java/org/apache/shardingsphere/infra/merge/MergeEngine.java
+++ b/shardingsphere-infra/shardingsphere-infra-merge/src/main/java/org/apache/shardingsphere/infra/merge/MergeEngine.java
@@ -96,7 +96,7 @@ public final class MergeEngine {
         for (Entry<ShardingSphereRule, ResultProcessEngine> entry : engines.entrySet()) {
             if (entry.getValue() instanceof ResultDecoratorEngine) {
                 ResultDecorator resultDecorator = ((ResultDecoratorEngine) entry.getValue()).newInstance(databaseType, schema, entry.getKey(), props, sqlStatementContext);
-                result = null == result ? resultDecorator.decorate(mergedResult, sqlStatementContext, schema) : resultDecorator.decorate(result, sqlStatementContext, schema);
+                result = null == result ? resultDecorator.decorate(mergedResult, sqlStatementContext, entry.getKey()) : resultDecorator.decorate(result, sqlStatementContext, entry.getKey());
             }
         }
         return null == result ? mergedResult : result;
@@ -108,7 +108,7 @@ public final class MergeEngine {
         for (Entry<ShardingSphereRule, ResultProcessEngine> entry : engines.entrySet()) {
             if (entry.getValue() instanceof ResultDecoratorEngine) {
                 ResultDecorator resultDecorator = ((ResultDecoratorEngine) entry.getValue()).newInstance(databaseType, schema, entry.getKey(), props, sqlStatementContext);
-                result = null == result ? resultDecorator.decorate(queryResult, sqlStatementContext, schema) : resultDecorator.decorate(result, sqlStatementContext, schema);
+                result = null == result ? resultDecorator.decorate(queryResult, sqlStatementContext, entry.getKey()) : resultDecorator.decorate(result, sqlStatementContext, entry.getKey());
             }
         }
         return Optional.ofNullable(result);
diff --git a/shardingsphere-infra/shardingsphere-infra-merge/src/main/java/org/apache/shardingsphere/infra/merge/engine/decorator/ResultDecorator.java b/shardingsphere-infra/shardingsphere-infra-merge/src/main/java/org/apache/shardingsphere/infra/merge/engine/decorator/ResultDecorator.java
index 9107266..a76f59b 100644
--- a/shardingsphere-infra/shardingsphere-infra-merge/src/main/java/org/apache/shardingsphere/infra/merge/engine/decorator/ResultDecorator.java
+++ b/shardingsphere-infra/shardingsphere-infra-merge/src/main/java/org/apache/shardingsphere/infra/merge/engine/decorator/ResultDecorator.java
@@ -17,37 +17,39 @@
 
 package org.apache.shardingsphere.infra.merge.engine.decorator;
 
+import org.apache.shardingsphere.infra.binder.statement.SQLStatementContext;
 import org.apache.shardingsphere.infra.executor.sql.QueryResult;
 import org.apache.shardingsphere.infra.merge.result.MergedResult;
-import org.apache.shardingsphere.infra.metadata.schema.ShardingSphereSchema;
-import org.apache.shardingsphere.infra.binder.statement.SQLStatementContext;
+import org.apache.shardingsphere.infra.rule.ShardingSphereRule;
 
 import java.sql.SQLException;
 
 /**
  * Result decorator.
+ * 
+ * @param <T> type of ShardingSphere rule
  */
-public interface ResultDecorator {
+public interface ResultDecorator<T extends ShardingSphereRule> {
     
     /**
      * Decorate query result.
      *
      * @param queryResult query result
      * @param sqlStatementContext SQL statement context
-     * @param schema ShardingSphere schema
+     * @param rule ShardingSphere rule
      * @return merged result
      * @throws SQLException SQL exception
      */
-    MergedResult decorate(QueryResult queryResult, SQLStatementContext<?> sqlStatementContext, ShardingSphereSchema schema) throws SQLException;
+    MergedResult decorate(QueryResult queryResult, SQLStatementContext<?> sqlStatementContext, T rule) throws SQLException;
     
     /**
      * Decorate merged result.
      * 
      * @param mergedResult merged result
      * @param sqlStatementContext SQL statement context
-     * @param schema ShardingSphere schema
+     * @param rule ShardingSphere rule
      * @return merged result
      * @throws SQLException SQL exception
      */
-    MergedResult decorate(MergedResult mergedResult, SQLStatementContext<?> sqlStatementContext, ShardingSphereSchema schema) throws SQLException;
+    MergedResult decorate(MergedResult mergedResult, SQLStatementContext<?> sqlStatementContext, T rule) throws SQLException;
 }
diff --git a/shardingsphere-infra/shardingsphere-infra-merge/src/main/java/org/apache/shardingsphere/infra/merge/engine/decorator/impl/TransparentResultDecorator.java b/shardingsphere-infra/shardingsphere-infra-merge/src/main/java/org/apache/shardingsphere/infra/merge/engine/decorator/impl/TransparentResultDecorator.java
index 843751f..5f86d91 100644
--- a/shardingsphere-infra/shardingsphere-infra-merge/src/main/java/org/apache/shardingsphere/infra/merge/engine/decorator/impl/TransparentResultDecorator.java
+++ b/shardingsphere-infra/shardingsphere-infra-merge/src/main/java/org/apache/shardingsphere/infra/merge/engine/decorator/impl/TransparentResultDecorator.java
@@ -17,25 +17,24 @@
 
 package org.apache.shardingsphere.infra.merge.engine.decorator.impl;
 
+import org.apache.shardingsphere.infra.binder.statement.SQLStatementContext;
 import org.apache.shardingsphere.infra.executor.sql.QueryResult;
 import org.apache.shardingsphere.infra.merge.engine.decorator.ResultDecorator;
 import org.apache.shardingsphere.infra.merge.result.MergedResult;
 import org.apache.shardingsphere.infra.merge.result.impl.transparent.TransparentMergedResult;
-import org.apache.shardingsphere.infra.metadata.schema.ShardingSphereSchema;
-import org.apache.shardingsphere.infra.binder.statement.SQLStatementContext;
 
 /**
  * Transparent result decorator.
  */
-public final class TransparentResultDecorator implements ResultDecorator {
+public final class TransparentResultDecorator implements ResultDecorator<TransparentRule> {
     
     @Override
-    public MergedResult decorate(final QueryResult queryResult, final SQLStatementContext<?> sqlStatementContext, final ShardingSphereSchema schema) {
+    public MergedResult decorate(final QueryResult queryResult, final SQLStatementContext<?> sqlStatementContext, final TransparentRule rule) {
         return new TransparentMergedResult(queryResult);
     }
     
     @Override
-    public MergedResult decorate(final MergedResult mergedResult, final SQLStatementContext<?> sqlStatementContext, final ShardingSphereSchema schema) {
+    public MergedResult decorate(final MergedResult mergedResult, final SQLStatementContext<?> sqlStatementContext, final TransparentRule rule) {
         return mergedResult;
     }
 }
diff --git a/shardingsphere-infra/shardingsphere-infra-common/src/main/java/org/apache/shardingsphere/infra/metadata/schema/model/ColumnMetaData.java b/shardingsphere-infra/shardingsphere-infra-merge/src/main/java/org/apache/shardingsphere/infra/merge/engine/decorator/impl/TransparentRule.java
similarity index 60%
copy from shardingsphere-infra/shardingsphere-infra-common/src/main/java/org/apache/shardingsphere/infra/metadata/schema/model/ColumnMetaData.java
copy to shardingsphere-infra/shardingsphere-infra-merge/src/main/java/org/apache/shardingsphere/infra/merge/engine/decorator/impl/TransparentRule.java
index 1883f49..faf45d8 100644
--- a/shardingsphere-infra/shardingsphere-infra-common/src/main/java/org/apache/shardingsphere/infra/metadata/schema/model/ColumnMetaData.java
+++ b/shardingsphere-infra/shardingsphere-infra-merge/src/main/java/org/apache/shardingsphere/infra/merge/engine/decorator/impl/TransparentRule.java
@@ -15,31 +15,12 @@
  * limitations under the License.
  */
 
-package org.apache.shardingsphere.infra.metadata.schema.model;
+package org.apache.shardingsphere.infra.merge.engine.decorator.impl;
 
-import lombok.EqualsAndHashCode;
-import lombok.Getter;
-import lombok.RequiredArgsConstructor;
-import lombok.ToString;
+import org.apache.shardingsphere.infra.rule.ShardingSphereRule;
 
 /**
- * Column meta data.
+ * Transparent rule.
  */
-@RequiredArgsConstructor
-@Getter
-@EqualsAndHashCode
-@ToString
-public class ColumnMetaData {
-    
-    private final String name;
-    
-    private final int dataType;
-    
-    private final String dataTypeName;
-    
-    private final boolean primaryKey;
-    
-    private final boolean generated;
-    
-    private final boolean caseSensitive;
+public final class TransparentRule implements ShardingSphereRule {
 }
diff --git a/shardingsphere-infra/shardingsphere-infra-merge/src/test/java/org/apache/shardingsphere/infra/merge/engine/decorator/impl/TransparentResultDecoratorTest.java b/shardingsphere-infra/shardingsphere-infra-merge/src/test/java/org/apache/shardingsphere/infra/merge/engine/decorator/impl/TransparentResultDecoratorTest.java
index aa9a957..fbf0f72 100644
--- a/shardingsphere-infra/shardingsphere-infra-merge/src/test/java/org/apache/shardingsphere/infra/merge/engine/decorator/impl/TransparentResultDecoratorTest.java
+++ b/shardingsphere-infra/shardingsphere-infra-merge/src/test/java/org/apache/shardingsphere/infra/merge/engine/decorator/impl/TransparentResultDecoratorTest.java
@@ -17,10 +17,9 @@
 
 package org.apache.shardingsphere.infra.merge.engine.decorator.impl;
 
+import org.apache.shardingsphere.infra.binder.statement.SQLStatementContext;
 import org.apache.shardingsphere.infra.executor.sql.QueryResult;
 import org.apache.shardingsphere.infra.merge.result.MergedResult;
-import org.apache.shardingsphere.infra.metadata.schema.ShardingSphereSchema;
-import org.apache.shardingsphere.infra.binder.statement.SQLStatementContext;
 import org.junit.Test;
 
 import java.sql.SQLException;
@@ -36,7 +35,7 @@ public final class TransparentResultDecoratorTest {
         QueryResult queryResult = mock(QueryResult.class);
         when(queryResult.next()).thenReturn(true);
         TransparentResultDecorator decorator = new TransparentResultDecorator();
-        MergedResult actual = decorator.decorate(queryResult, mock(SQLStatementContext.class), mock(ShardingSphereSchema.class));
+        MergedResult actual = decorator.decorate(queryResult, mock(SQLStatementContext.class), new TransparentRule());
         assertTrue(actual.next());
     }
     
@@ -45,7 +44,7 @@ public final class TransparentResultDecoratorTest {
         MergedResult mergedResult = mock(MergedResult.class);
         when(mergedResult.next()).thenReturn(true);
         TransparentResultDecorator decorator = new TransparentResultDecorator();
-        MergedResult actual = decorator.decorate(mergedResult, mock(SQLStatementContext.class), mock(ShardingSphereSchema.class));
+        MergedResult actual = decorator.decorate(mergedResult, mock(SQLStatementContext.class), new TransparentRule());
         assertTrue(actual.next());
     }
 }
diff --git a/shardingsphere-infra/shardingsphere-infra-merge/src/test/java/org/apache/shardingsphere/infra/merge/fixture/decorator/ResultDecoratorFixture.java b/shardingsphere-infra/shardingsphere-infra-merge/src/test/java/org/apache/shardingsphere/infra/merge/fixture/decorator/ResultDecoratorFixture.java
index ac84ac1..0a2540e 100644
--- a/shardingsphere-infra/shardingsphere-infra-merge/src/test/java/org/apache/shardingsphere/infra/merge/fixture/decorator/ResultDecoratorFixture.java
+++ b/shardingsphere-infra/shardingsphere-infra-merge/src/test/java/org/apache/shardingsphere/infra/merge/fixture/decorator/ResultDecoratorFixture.java
@@ -17,13 +17,13 @@
 
 package org.apache.shardingsphere.infra.merge.fixture.decorator;
 
+import org.apache.shardingsphere.infra.binder.statement.SQLStatementContext;
 import org.apache.shardingsphere.infra.executor.sql.QueryResult;
 import org.apache.shardingsphere.infra.executor.sql.resourced.jdbc.queryresult.StreamQueryResult;
 import org.apache.shardingsphere.infra.merge.engine.decorator.ResultDecorator;
+import org.apache.shardingsphere.infra.merge.fixture.rule.DecoratorRuleFixture;
 import org.apache.shardingsphere.infra.merge.result.MergedResult;
 import org.apache.shardingsphere.infra.merge.result.impl.transparent.TransparentMergedResult;
-import org.apache.shardingsphere.infra.metadata.schema.ShardingSphereSchema;
-import org.apache.shardingsphere.infra.binder.statement.SQLStatementContext;
 
 import java.sql.ResultSet;
 import java.sql.SQLException;
@@ -31,17 +31,17 @@ import java.sql.SQLException;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
-public final class ResultDecoratorFixture implements ResultDecorator {
+public final class ResultDecoratorFixture implements ResultDecorator<DecoratorRuleFixture> {
     
     @Override
-    public MergedResult decorate(final QueryResult queryResult, final SQLStatementContext<?> sqlStatementContext, final ShardingSphereSchema schema) throws SQLException {
+    public MergedResult decorate(final QueryResult queryResult, final SQLStatementContext<?> sqlStatementContext, final DecoratorRuleFixture rule) throws SQLException {
         ResultSet resultSet = mock(ResultSet.class);
         when(resultSet.getString(1)).thenReturn("decorated_value");
         return new TransparentMergedResult(new StreamQueryResult(resultSet));
     }
     
     @Override
-    public MergedResult decorate(final MergedResult mergedResult, final SQLStatementContext<?> sqlStatementContext, final ShardingSphereSchema schema) throws SQLException {
+    public MergedResult decorate(final MergedResult mergedResult, final SQLStatementContext<?> sqlStatementContext, final DecoratorRuleFixture rule) throws SQLException {
         ResultSet resultSet = mock(ResultSet.class);
         when(resultSet.getString(1)).thenReturn("decorated_merged_value");
         return new TransparentMergedResult(new StreamQueryResult(resultSet));