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

chengzhang 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 b49b323a02e Fix show create table wrong result with encrypt when data 
type contains float (#31024)
b49b323a02e is described below

commit b49b323a02ee10e8268c2bc5ffd8f88289af4400
Author: Zhengqiang Duan <[email protected]>
AuthorDate: Fri Apr 26 17:30:27 2024 +0800

    Fix show create table wrong result with encrypt when data type contains 
float (#31024)
---
 features/encrypt/core/pom.xml                      | 41 +++++++++++++++++++++
 .../merge/EncryptResultDecoratorEngine.java        |  5 ++-
 .../merge/dal/EncryptDALResultDecorator.java       |  9 ++++-
 ...ecoratedEncryptShowCreateTableMergedResult.java |  6 ++-
 .../show/EncryptShowCreateTableMergedResult.java   | 43 +++++++++++++---------
 .../MergedEncryptShowCreateTableMergedResult.java  |  6 ++-
 .../merge/EncryptResultDecoratorEngineTest.java    |  8 ++--
 .../merge/dal/EncryptDALResultDecoratorTest.java   | 12 ++++--
 ...atedEncryptShowCreateTableMergedResultTest.java | 22 ++++++++++-
 ...rgedEncryptShowCreateTableMergedResultTest.java | 22 ++++++++++-
 .../mask/merge/MaskResultDecoratorEngine.java      |  3 +-
 .../mask/merge/MaskResultDecoratorEngineTest.java  |  6 ++-
 .../shardingsphere/infra/merge/MergeEngine.java    |  9 ++++-
 .../engine/decorator/ResultDecoratorEngine.java    |  6 ++-
 .../infra/merge/MergeEngineTest.java               | 21 +++++++----
 .../decorator/ResultDecoratorEngineFixture.java    |  3 +-
 .../statement/ShardingSpherePreparedStatement.java |  2 +-
 .../core/statement/ShardingSphereStatement.java    |  4 +-
 .../enumerable/EnumerableScanExecutor.java         |  8 ++--
 .../proxy/backend/connector/DatabaseConnector.java |  4 +-
 20 files changed, 181 insertions(+), 59 deletions(-)

diff --git a/features/encrypt/core/pom.xml b/features/encrypt/core/pom.xml
index f9229753b57..b3575792347 100644
--- a/features/encrypt/core/pom.xml
+++ b/features/encrypt/core/pom.xml
@@ -52,6 +52,11 @@
             
<artifactId>shardingsphere-infra-algorithm-message-digest-md5</artifactId>
             <version>${project.version}</version>
         </dependency>
+        <dependency>
+            <groupId>org.apache.shardingsphere</groupId>
+            <artifactId>shardingsphere-sql-parser-core</artifactId>
+            <version>${project.version}</version>
+        </dependency>
         
         <dependency>
             <groupId>org.apache.shardingsphere</groupId>
@@ -77,6 +82,42 @@
             <version>${project.version}</version>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>org.apache.shardingsphere</groupId>
+            <artifactId>shardingsphere-parser-sql-sql92</artifactId>
+            <version>${project.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.shardingsphere</groupId>
+            <artifactId>shardingsphere-parser-sql-mysql</artifactId>
+            <version>${project.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.shardingsphere</groupId>
+            <artifactId>shardingsphere-parser-sql-postgresql</artifactId>
+            <version>${project.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.shardingsphere</groupId>
+            <artifactId>shardingsphere-parser-sql-opengauss</artifactId>
+            <version>${project.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.shardingsphere</groupId>
+            <artifactId>shardingsphere-parser-sql-oracle</artifactId>
+            <version>${project.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.shardingsphere</groupId>
+            <artifactId>shardingsphere-parser-sql-sqlserver</artifactId>
+            <version>${project.version}</version>
+            <scope>test</scope>
+        </dependency>
         
         <dependency>
             <groupId>commons-codec</groupId>
diff --git 
a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/merge/EncryptResultDecoratorEngine.java
 
b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/merge/EncryptResultDecoratorEngine.java
index 545e410d01f..becf7a42d32 100644
--- 
a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/merge/EncryptResultDecoratorEngine.java
+++ 
b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/merge/EncryptResultDecoratorEngine.java
@@ -27,6 +27,7 @@ import 
org.apache.shardingsphere.infra.config.props.ConfigurationProperties;
 import org.apache.shardingsphere.infra.merge.engine.decorator.ResultDecorator;
 import 
org.apache.shardingsphere.infra.merge.engine.decorator.ResultDecoratorEngine;
 import 
org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
+import org.apache.shardingsphere.infra.metadata.database.rule.RuleMetaData;
 import 
org.apache.shardingsphere.sql.parser.sql.common.statement.dal.DALStatement;
 
 import java.util.Optional;
@@ -37,13 +38,13 @@ import java.util.Optional;
 public final class EncryptResultDecoratorEngine implements 
ResultDecoratorEngine<EncryptRule> {
     
     @Override
-    public Optional<ResultDecorator<EncryptRule>> newInstance(final 
ShardingSphereDatabase database,
+    public Optional<ResultDecorator<EncryptRule>> newInstance(final 
RuleMetaData globalRuleMetaData, final ShardingSphereDatabase database,
                                                               final 
EncryptRule encryptRule, final ConfigurationProperties props, final 
SQLStatementContext sqlStatementContext) {
         if (sqlStatementContext instanceof SelectStatementContext) {
             return Optional.of(new EncryptDQLResultDecorator(database, 
encryptRule, (SelectStatementContext) sqlStatementContext));
         }
         if (sqlStatementContext.getSqlStatement() instanceof DALStatement) {
-            return Optional.of(new EncryptDALResultDecorator());
+            return Optional.of(new 
EncryptDALResultDecorator(globalRuleMetaData));
         }
         return Optional.empty();
     }
diff --git 
a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/merge/dal/EncryptDALResultDecorator.java
 
b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/merge/dal/EncryptDALResultDecorator.java
index 26a941fb086..40056628d43 100644
--- 
a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/merge/dal/EncryptDALResultDecorator.java
+++ 
b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/merge/dal/EncryptDALResultDecorator.java
@@ -17,6 +17,7 @@
 
 package org.apache.shardingsphere.encrypt.merge.dal;
 
+import lombok.RequiredArgsConstructor;
 import 
org.apache.shardingsphere.encrypt.merge.dal.show.DecoratedEncryptShowColumnsMergedResult;
 import 
org.apache.shardingsphere.encrypt.merge.dal.show.DecoratedEncryptShowCreateTableMergedResult;
 import 
org.apache.shardingsphere.encrypt.merge.dal.show.MergedEncryptShowColumnsMergedResult;
@@ -27,6 +28,7 @@ import 
org.apache.shardingsphere.infra.executor.sql.execute.result.query.QueryRe
 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.database.rule.RuleMetaData;
 import org.apache.shardingsphere.sql.parser.sql.common.statement.SQLStatement;
 import 
org.apache.shardingsphere.sql.parser.sql.dialect.statement.mysql.dal.MySQLExplainStatement;
 import 
org.apache.shardingsphere.sql.parser.sql.dialect.statement.mysql.dal.MySQLShowColumnsStatement;
@@ -35,8 +37,11 @@ import 
org.apache.shardingsphere.sql.parser.sql.dialect.statement.mysql.dal.MySQ
 /**
  * DAL result decorator for encrypt.
  */
+@RequiredArgsConstructor
 public final class EncryptDALResultDecorator implements 
ResultDecorator<EncryptRule> {
     
+    private final RuleMetaData globalRuleMetaData;
+    
     @Override
     public MergedResult decorate(final QueryResult queryResult, final 
SQLStatementContext sqlStatementContext, final EncryptRule rule) {
         SQLStatement sqlStatement = sqlStatementContext.getSqlStatement();
@@ -44,7 +49,7 @@ public final class EncryptDALResultDecorator implements 
ResultDecorator<EncryptR
             return new MergedEncryptShowColumnsMergedResult(queryResult, 
sqlStatementContext, rule);
         }
         if (sqlStatement instanceof MySQLShowCreateTableStatement) {
-            return new MergedEncryptShowCreateTableMergedResult(queryResult, 
sqlStatementContext, rule);
+            return new 
MergedEncryptShowCreateTableMergedResult(globalRuleMetaData, queryResult, 
sqlStatementContext, rule);
         }
         return new TransparentMergedResult(queryResult);
     }
@@ -56,7 +61,7 @@ public final class EncryptDALResultDecorator implements 
ResultDecorator<EncryptR
             return new DecoratedEncryptShowColumnsMergedResult(mergedResult, 
sqlStatementContext, rule);
         }
         if (sqlStatement instanceof MySQLShowCreateTableStatement) {
-            return new 
DecoratedEncryptShowCreateTableMergedResult(mergedResult, sqlStatementContext, 
rule);
+            return new 
DecoratedEncryptShowCreateTableMergedResult(globalRuleMetaData, mergedResult, 
sqlStatementContext, rule);
         }
         return mergedResult;
     }
diff --git 
a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/merge/dal/show/DecoratedEncryptShowCreateTableMergedResult.java
 
b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/merge/dal/show/DecoratedEncryptShowCreateTableMergedResult.java
index 6e86e6bd0d7..2c8b6624cba 100644
--- 
a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/merge/dal/show/DecoratedEncryptShowCreateTableMergedResult.java
+++ 
b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/merge/dal/show/DecoratedEncryptShowCreateTableMergedResult.java
@@ -20,6 +20,7 @@ package org.apache.shardingsphere.encrypt.merge.dal.show;
 import org.apache.shardingsphere.encrypt.rule.EncryptRule;
 import 
org.apache.shardingsphere.infra.binder.context.statement.SQLStatementContext;
 import org.apache.shardingsphere.infra.merge.result.MergedResult;
+import org.apache.shardingsphere.infra.metadata.database.rule.RuleMetaData;
 
 import java.sql.SQLException;
 
@@ -30,8 +31,9 @@ public final class 
DecoratedEncryptShowCreateTableMergedResult extends EncryptSh
     
     private final MergedResult mergedResult;
     
-    public DecoratedEncryptShowCreateTableMergedResult(final MergedResult 
mergedResult, final SQLStatementContext sqlStatementContext, final EncryptRule 
encryptRule) {
-        super(sqlStatementContext, encryptRule);
+    public DecoratedEncryptShowCreateTableMergedResult(final RuleMetaData 
globalRuleMetaData, final MergedResult mergedResult, final SQLStatementContext 
sqlStatementContext,
+                                                       final EncryptRule 
encryptRule) {
+        super(globalRuleMetaData, sqlStatementContext, encryptRule);
         this.mergedResult = mergedResult;
     }
     
diff --git 
a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/merge/dal/show/EncryptShowCreateTableMergedResult.java
 
b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/merge/dal/show/EncryptShowCreateTableMergedResult.java
index 77f5256c323..01ff9de1456 100644
--- 
a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/merge/dal/show/EncryptShowCreateTableMergedResult.java
+++ 
b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/merge/dal/show/EncryptShowCreateTableMergedResult.java
@@ -17,21 +17,25 @@
 
 package org.apache.shardingsphere.encrypt.merge.dal.show;
 
-import com.google.common.base.Splitter;
 import 
org.apache.shardingsphere.encrypt.exception.syntax.UnsupportedEncryptSQLException;
 import org.apache.shardingsphere.encrypt.rule.EncryptRule;
 import org.apache.shardingsphere.encrypt.rule.EncryptTable;
 import 
org.apache.shardingsphere.infra.binder.context.statement.SQLStatementContext;
 import org.apache.shardingsphere.infra.binder.context.type.TableAvailable;
-import 
org.apache.shardingsphere.infra.database.core.metadata.database.DialectDatabaseMetaData;
-import org.apache.shardingsphere.infra.database.core.type.DatabaseTypeRegistry;
 import 
org.apache.shardingsphere.infra.exception.core.ShardingSpherePreconditions;
 import org.apache.shardingsphere.infra.merge.result.MergedResult;
+import org.apache.shardingsphere.infra.metadata.database.rule.RuleMetaData;
+import org.apache.shardingsphere.infra.parser.SQLParserEngine;
+import org.apache.shardingsphere.parser.rule.SQLParserRule;
+import 
org.apache.shardingsphere.sql.parser.sql.common.segment.ddl.column.ColumnDefinitionSegment;
+import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.column.ColumnSegment;
+import 
org.apache.shardingsphere.sql.parser.sql.common.statement.ddl.CreateTableStatement;
 
 import java.io.InputStream;
 import java.io.Reader;
 import java.sql.SQLException;
 import java.sql.SQLFeatureNotSupportedException;
+import java.util.ArrayList;
 import java.util.Calendar;
 import java.util.List;
 import java.util.Optional;
@@ -41,22 +45,22 @@ import java.util.Optional;
  */
 public abstract class EncryptShowCreateTableMergedResult implements 
MergedResult {
     
-    private static final String COMMA = ",";
+    private static final String COMMA = ", ";
     
     private static final int CREATE_TABLE_DEFINITION_INDEX = 2;
     
-    private final DialectDatabaseMetaData dialectDatabaseMetaData;
-    
     private final String tableName;
     
     private final EncryptRule encryptRule;
     
-    protected EncryptShowCreateTableMergedResult(final SQLStatementContext 
sqlStatementContext, final EncryptRule encryptRule) {
+    private final SQLParserEngine sqlParserEngine;
+    
+    protected EncryptShowCreateTableMergedResult(final RuleMetaData 
globalRuleMetaData, final SQLStatementContext sqlStatementContext, final 
EncryptRule encryptRule) {
         ShardingSpherePreconditions.checkState(sqlStatementContext instanceof 
TableAvailable && 1 == ((TableAvailable) 
sqlStatementContext).getAllTables().size(),
                 () -> new UnsupportedEncryptSQLException("SHOW CREATE TABLE 
FOR MULTI TABLE"));
-        dialectDatabaseMetaData = new 
DatabaseTypeRegistry(sqlStatementContext.getDatabaseType()).getDialectDatabaseMetaData();
         tableName = ((TableAvailable) 
sqlStatementContext).getAllTables().iterator().next().getTableName().getIdentifier().getValue();
         this.encryptRule = encryptRule;
+        sqlParserEngine = 
globalRuleMetaData.getSingleRule(SQLParserRule.class).getSQLParserEngine(sqlStatementContext.getDatabaseType());
     }
     
     @Override
@@ -72,26 +76,31 @@ public abstract class EncryptShowCreateTableMergedResult 
implements MergedResult
             if (!encryptTable.isPresent() || !result.contains("(")) {
                 return result;
             }
-            StringBuilder builder = new StringBuilder(result.substring(0, 
result.indexOf('(') + 1));
-            List<String> columnDefinitions = 
Splitter.on(COMMA).splitToList(result.substring(result.indexOf('(') + 1, 
result.lastIndexOf(')')));
-            for (String each : columnDefinitions) {
-                findLogicColumnDefinition(each, 
encryptTable.get()).ifPresent(optional -> 
builder.append(optional).append(COMMA));
+            CreateTableStatement createTableStatement = (CreateTableStatement) 
sqlParserEngine.parse(result, false);
+            List<ColumnDefinitionSegment> columnDefinitions = new 
ArrayList<>(createTableStatement.getColumnDefinitions());
+            StringBuilder builder = new StringBuilder(result.substring(0, 
columnDefinitions.get(0).getStartIndex()));
+            for (ColumnDefinitionSegment each : columnDefinitions) {
+                findLogicColumnDefinition(each, encryptTable.get(), 
result).ifPresent(optional -> builder.append(optional).append(COMMA));
             }
-            builder.deleteCharAt(builder.length() - 
1).append(result.substring(result.lastIndexOf(')')));
+            // TODO decorate encrypt column index when we support index rewrite
+            builder.delete(builder.length() - COMMA.length(), 
builder.length()).append(result.substring(columnDefinitions.get(columnDefinitions.size()
 - 1).getStopIndex() + 1));
             return builder.toString();
         }
         return getOriginalValue(columnIndex, type);
     }
     
-    private Optional<String> findLogicColumnDefinition(final String 
columnDefinition, final EncryptTable encryptTable) {
-        String columnName = 
dialectDatabaseMetaData.getQuoteCharacter().unwrap(columnDefinition.trim().split("\\s+")[0]);
+    private Optional<String> findLogicColumnDefinition(final 
ColumnDefinitionSegment columnDefinition, final EncryptTable encryptTable, 
final String sql) {
+        ColumnSegment columnSegment = columnDefinition.getColumnName();
+        String columnName = columnSegment.getIdentifier().getValue();
         if (encryptTable.isCipherColumn(columnName)) {
-            return Optional.of(columnDefinition.replace(columnName, 
encryptTable.getLogicColumnByCipherColumn(columnName)));
+            String logicColumn = 
encryptTable.getLogicColumnByCipherColumn(columnName);
+            return Optional.of(sql.substring(columnDefinition.getStartIndex(), 
columnSegment.getStartIndex())
+                    + 
columnSegment.getIdentifier().getQuoteCharacter().wrap(logicColumn) + 
sql.substring(columnSegment.getStopIndex() + 1, columnDefinition.getStopIndex() 
+ 1));
         }
         if (isDerivedColumn(encryptTable, columnName)) {
             return Optional.empty();
         }
-        return Optional.of(columnDefinition);
+        return Optional.of(sql.substring(columnDefinition.getStartIndex(), 
columnDefinition.getStopIndex() + 1));
     }
     
     private boolean isDerivedColumn(final EncryptTable encryptTable, final 
String columnName) {
diff --git 
a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/merge/dal/show/MergedEncryptShowCreateTableMergedResult.java
 
b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/merge/dal/show/MergedEncryptShowCreateTableMergedResult.java
index c906f0a06cf..db7485ea2ec 100644
--- 
a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/merge/dal/show/MergedEncryptShowCreateTableMergedResult.java
+++ 
b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/merge/dal/show/MergedEncryptShowCreateTableMergedResult.java
@@ -20,6 +20,7 @@ package org.apache.shardingsphere.encrypt.merge.dal.show;
 import org.apache.shardingsphere.encrypt.rule.EncryptRule;
 import 
org.apache.shardingsphere.infra.binder.context.statement.SQLStatementContext;
 import 
org.apache.shardingsphere.infra.executor.sql.execute.result.query.QueryResult;
+import org.apache.shardingsphere.infra.metadata.database.rule.RuleMetaData;
 
 import java.sql.SQLException;
 
@@ -30,8 +31,9 @@ public final class MergedEncryptShowCreateTableMergedResult 
extends EncryptShowC
     
     private final QueryResult queryResult;
     
-    public MergedEncryptShowCreateTableMergedResult(final QueryResult 
queryResult, final SQLStatementContext sqlStatementContext, final EncryptRule 
encryptRule) {
-        super(sqlStatementContext, encryptRule);
+    public MergedEncryptShowCreateTableMergedResult(final RuleMetaData 
globalRuleMetaData, final QueryResult queryResult, final SQLStatementContext 
sqlStatementContext,
+                                                    final EncryptRule 
encryptRule) {
+        super(globalRuleMetaData, sqlStatementContext, encryptRule);
         this.queryResult = queryResult;
     }
     
diff --git 
a/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/merge/EncryptResultDecoratorEngineTest.java
 
b/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/merge/EncryptResultDecoratorEngineTest.java
index ec44ff8b05c..d29ea872841 100644
--- 
a/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/merge/EncryptResultDecoratorEngineTest.java
+++ 
b/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/merge/EncryptResultDecoratorEngineTest.java
@@ -28,6 +28,7 @@ import 
org.apache.shardingsphere.infra.config.props.ConfigurationProperties;
 import org.apache.shardingsphere.infra.merge.engine.ResultProcessEngine;
 import org.apache.shardingsphere.infra.merge.engine.decorator.ResultDecorator;
 import 
org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
+import org.apache.shardingsphere.infra.metadata.database.rule.RuleMetaData;
 import org.apache.shardingsphere.infra.spi.type.ordered.OrderedSPILoader;
 import 
org.apache.shardingsphere.sql.parser.sql.dialect.statement.mysql.dal.MySQLExplainStatement;
 import org.junit.jupiter.api.Test;
@@ -58,7 +59,8 @@ class EncryptResultDecoratorEngineTest {
     @Test
     void assertNewInstanceWithSelectStatement() {
         EncryptResultDecoratorEngine engine = (EncryptResultDecoratorEngine) 
OrderedSPILoader.getServices(ResultProcessEngine.class, 
Collections.singleton(rule)).get(rule);
-        Optional<ResultDecorator<EncryptRule>> actual = 
engine.newInstance(database, rule, mock(ConfigurationProperties.class), 
mock(SelectStatementContext.class, RETURNS_DEEP_STUBS));
+        Optional<ResultDecorator<EncryptRule>> actual =
+                engine.newInstance(mock(RuleMetaData.class), database, rule, 
mock(ConfigurationProperties.class), mock(SelectStatementContext.class, 
RETURNS_DEEP_STUBS));
         assertTrue(actual.isPresent());
         assertThat(actual.get(), instanceOf(EncryptDQLResultDecorator.class));
     }
@@ -68,7 +70,7 @@ class EncryptResultDecoratorEngineTest {
         SQLStatementContext sqlStatementContext = 
mock(ExplainStatementContext.class);
         
when(sqlStatementContext.getSqlStatement()).thenReturn(mock(MySQLExplainStatement.class));
         EncryptResultDecoratorEngine engine = (EncryptResultDecoratorEngine) 
OrderedSPILoader.getServices(ResultProcessEngine.class, 
Collections.singleton(rule)).get(rule);
-        Optional<ResultDecorator<EncryptRule>> actual = 
engine.newInstance(database, rule, mock(ConfigurationProperties.class), 
sqlStatementContext);
+        Optional<ResultDecorator<EncryptRule>> actual = 
engine.newInstance(mock(RuleMetaData.class), database, rule, 
mock(ConfigurationProperties.class), sqlStatementContext);
         assertTrue(actual.isPresent());
         assertThat(actual.get(), instanceOf(EncryptDALResultDecorator.class));
     }
@@ -76,6 +78,6 @@ class EncryptResultDecoratorEngineTest {
     @Test
     void assertNewInstanceWithOtherStatement() {
         EncryptResultDecoratorEngine engine = (EncryptResultDecoratorEngine) 
OrderedSPILoader.getServices(ResultProcessEngine.class, 
Collections.singleton(rule)).get(rule);
-        assertFalse(engine.newInstance(database, rule, 
mock(ConfigurationProperties.class), 
mock(InsertStatementContext.class)).isPresent());
+        assertFalse(engine.newInstance(mock(RuleMetaData.class), database, 
rule, mock(ConfigurationProperties.class), 
mock(InsertStatementContext.class)).isPresent());
     }
 }
diff --git 
a/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/merge/dal/EncryptDALResultDecoratorTest.java
 
b/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/merge/dal/EncryptDALResultDecoratorTest.java
index c8393c17784..76565afbb98 100644
--- 
a/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/merge/dal/EncryptDALResultDecoratorTest.java
+++ 
b/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/merge/dal/EncryptDALResultDecoratorTest.java
@@ -30,7 +30,9 @@ import 
org.apache.shardingsphere.infra.database.core.type.DatabaseType;
 import 
org.apache.shardingsphere.infra.executor.sql.execute.result.query.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.database.rule.RuleMetaData;
 import org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader;
+import org.apache.shardingsphere.parser.rule.SQLParserRule;
 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;
@@ -63,7 +65,7 @@ class EncryptDALResultDecoratorTest {
     @Test
     void assertMergedResultWithDescribeStatement() {
         sqlStatementContext = getDescribeStatementContext();
-        EncryptDALResultDecorator encryptDALResultDecorator = new 
EncryptDALResultDecorator();
+        EncryptDALResultDecorator encryptDALResultDecorator = new 
EncryptDALResultDecorator(mock(RuleMetaData.class));
         assertThat(encryptDALResultDecorator.decorate(mock(QueryResult.class), 
sqlStatementContext, rule), 
instanceOf(MergedEncryptShowColumnsMergedResult.class));
         
assertThat(encryptDALResultDecorator.decorate(mock(MergedResult.class), 
sqlStatementContext, rule), 
instanceOf(DecoratedEncryptShowColumnsMergedResult.class));
     }
@@ -71,7 +73,7 @@ class EncryptDALResultDecoratorTest {
     @Test
     void assertMergedResultWithShowColumnsStatement() {
         sqlStatementContext = getShowColumnsStatementContext();
-        EncryptDALResultDecorator encryptDALResultDecorator = new 
EncryptDALResultDecorator();
+        EncryptDALResultDecorator encryptDALResultDecorator = new 
EncryptDALResultDecorator(mock(RuleMetaData.class));
         assertThat(encryptDALResultDecorator.decorate(mock(QueryResult.class), 
sqlStatementContext, rule), 
instanceOf(MergedEncryptShowColumnsMergedResult.class));
         
assertThat(encryptDALResultDecorator.decorate(mock(MergedResult.class), 
sqlStatementContext, rule), 
instanceOf(DecoratedEncryptShowColumnsMergedResult.class));
     }
@@ -79,7 +81,9 @@ class EncryptDALResultDecoratorTest {
     @Test
     void assertMergedResultWithShowCreateTableStatement() {
         sqlStatementContext = getShowCreateTableStatementContext();
-        EncryptDALResultDecorator encryptDALResultDecorator = new 
EncryptDALResultDecorator();
+        RuleMetaData ruleMetaData = mock(RuleMetaData.class);
+        
when(ruleMetaData.getSingleRule(SQLParserRule.class)).thenReturn(mock(SQLParserRule.class));
+        EncryptDALResultDecorator encryptDALResultDecorator = new 
EncryptDALResultDecorator(ruleMetaData);
         assertThat(encryptDALResultDecorator.decorate(mock(QueryResult.class), 
sqlStatementContext, rule), 
instanceOf(MergedEncryptShowCreateTableMergedResult.class));
         
assertThat(encryptDALResultDecorator.decorate(mock(MergedResult.class), 
sqlStatementContext, rule), 
instanceOf(DecoratedEncryptShowCreateTableMergedResult.class));
     }
@@ -87,7 +91,7 @@ class EncryptDALResultDecoratorTest {
     @Test
     void assertMergedResultWithOtherStatement() {
         sqlStatementContext = mock(SQLStatementContext.class);
-        EncryptDALResultDecorator encryptDALResultDecorator = new 
EncryptDALResultDecorator();
+        EncryptDALResultDecorator encryptDALResultDecorator = new 
EncryptDALResultDecorator(mock(RuleMetaData.class));
         assertThat(encryptDALResultDecorator.decorate(mock(QueryResult.class), 
sqlStatementContext, rule), instanceOf(TransparentMergedResult.class));
         
assertThat(encryptDALResultDecorator.decorate(mock(MergedResult.class), 
sqlStatementContext, rule), instanceOf(MergedResult.class));
     }
diff --git 
a/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/merge/dal/show/DecoratedEncryptShowCreateTableMergedResultTest.java
 
b/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/merge/dal/show/DecoratedEncryptShowCreateTableMergedResultTest.java
index 3eaa8e52b2f..4ee123b2507 100644
--- 
a/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/merge/dal/show/DecoratedEncryptShowCreateTableMergedResultTest.java
+++ 
b/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/merge/dal/show/DecoratedEncryptShowCreateTableMergedResultTest.java
@@ -25,7 +25,11 @@ import org.apache.shardingsphere.encrypt.rule.EncryptTable;
 import 
org.apache.shardingsphere.infra.binder.context.statement.dal.ShowCreateTableStatementContext;
 import org.apache.shardingsphere.infra.database.core.type.DatabaseType;
 import org.apache.shardingsphere.infra.merge.result.MergedResult;
+import org.apache.shardingsphere.infra.metadata.database.rule.RuleMetaData;
 import org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader;
+import org.apache.shardingsphere.parser.config.SQLParserRuleConfiguration;
+import org.apache.shardingsphere.parser.rule.SQLParserRule;
+import org.apache.shardingsphere.sql.parser.api.CacheOption;
 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;
@@ -64,6 +68,20 @@ class DecoratedEncryptShowCreateTableMergedResultTest {
         
assertTrue(createDecoratedEncryptShowCreateTableMergedResult(mergedResult, 
mock(EncryptRule.class)).next());
     }
     
+    @Test
+    void assertGetValueWhenConfigFloatDataTypeAndComment() throws SQLException 
{
+        when(mergedResult.next()).thenReturn(true).thenReturn(false);
+        when(mergedResult.getValue(2, String.class)).thenReturn(
+                "CREATE TABLE `t_encrypt` (`id` INT NOT NULL, `user_id_cipher` 
FLOAT(10, 2) NOT NULL "
+                        + "COMMENT ',123\\&/\\`\"abc', `order_id` VARCHAR(30) 
NOT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;");
+        EncryptColumnRuleConfiguration columnRuleConfig = new 
EncryptColumnRuleConfiguration("user_id", new 
EncryptColumnItemRuleConfiguration("user_id_cipher", "foo_encryptor"));
+        DecoratedEncryptShowCreateTableMergedResult actual = 
createDecoratedEncryptShowCreateTableMergedResult(mergedResult, 
mockEncryptRule(Collections.singleton(columnRuleConfig)));
+        assertTrue(actual.next());
+        assertThat(actual.getValue(2, String.class),
+                is("CREATE TABLE `t_encrypt` (`id` INT NOT NULL, `user_id` 
FLOAT(10, 2) NOT NULL "
+                        + "COMMENT ',123\\&/\\`\"abc', `order_id` VARCHAR(30) 
NOT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;"));
+    }
+    
     @Test
     void assertGetValueWhenConfigAssistedQueryColumn() throws SQLException {
         when(mergedResult.next()).thenReturn(true).thenReturn(false);
@@ -131,6 +149,8 @@ class DecoratedEncryptShowCreateTableMergedResultTest {
         SimpleTableSegment simpleTableSegment = new 
SimpleTableSegment(tableNameSegment);
         
when(sqlStatementContext.getAllTables()).thenReturn(Collections.singleton(simpleTableSegment));
         
when(sqlStatementContext.getDatabaseType()).thenReturn(TypedSPILoader.getService(DatabaseType.class,
 "MySQL"));
-        return new DecoratedEncryptShowCreateTableMergedResult(mergedResult, 
sqlStatementContext, encryptRule);
+        RuleMetaData ruleMetaData = mock(RuleMetaData.class);
+        when(ruleMetaData.getSingleRule(SQLParserRule.class)).thenReturn(new 
SQLParserRule(new SQLParserRuleConfiguration(new CacheOption(128, 1024), new 
CacheOption(2000, 65535))));
+        return new DecoratedEncryptShowCreateTableMergedResult(ruleMetaData, 
mergedResult, sqlStatementContext, encryptRule);
     }
 }
diff --git 
a/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/merge/dal/show/MergedEncryptShowCreateTableMergedResultTest.java
 
b/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/merge/dal/show/MergedEncryptShowCreateTableMergedResultTest.java
index d151f935e51..fcf54f229cf 100644
--- 
a/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/merge/dal/show/MergedEncryptShowCreateTableMergedResultTest.java
+++ 
b/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/merge/dal/show/MergedEncryptShowCreateTableMergedResultTest.java
@@ -25,7 +25,11 @@ import org.apache.shardingsphere.encrypt.rule.EncryptTable;
 import 
org.apache.shardingsphere.infra.binder.context.statement.dal.ShowCreateTableStatementContext;
 import org.apache.shardingsphere.infra.database.core.type.DatabaseType;
 import 
org.apache.shardingsphere.infra.executor.sql.execute.result.query.QueryResult;
+import org.apache.shardingsphere.infra.metadata.database.rule.RuleMetaData;
 import org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader;
+import org.apache.shardingsphere.parser.config.SQLParserRuleConfiguration;
+import org.apache.shardingsphere.parser.rule.SQLParserRule;
+import org.apache.shardingsphere.sql.parser.api.CacheOption;
 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;
@@ -63,6 +67,20 @@ class MergedEncryptShowCreateTableMergedResultTest {
         assertTrue(createMergedEncryptShowCreateTableMergedResult(queryResult, 
mock(EncryptRule.class)).next());
     }
     
+    @Test
+    void assertGetValueWhenConfigFloatDataTypeAndComment() throws SQLException 
{
+        when(queryResult.next()).thenReturn(true).thenReturn(false);
+        when(queryResult.getValue(2, String.class)).thenReturn(
+                "CREATE TABLE `t_encrypt` (`id` INT NOT NULL, `user_id_cipher` 
FLOAT(10, 2) NOT NULL "
+                        + "COMMENT ',123\\&/\\`\"abc', `order_id` VARCHAR(30) 
NOT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;");
+        EncryptColumnRuleConfiguration columnRuleConfig = new 
EncryptColumnRuleConfiguration("user_id", new 
EncryptColumnItemRuleConfiguration("user_id_cipher", "foo_encryptor"));
+        MergedEncryptShowCreateTableMergedResult actual = 
createMergedEncryptShowCreateTableMergedResult(queryResult, 
mockEncryptRule(Collections.singleton(columnRuleConfig)));
+        assertTrue(actual.next());
+        assertThat(actual.getValue(2, String.class),
+                is("CREATE TABLE `t_encrypt` (`id` INT NOT NULL, `user_id` 
FLOAT(10, 2) NOT NULL "
+                        + "COMMENT ',123\\&/\\`\"abc', `order_id` VARCHAR(30) 
NOT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;"));
+    }
+    
     @Test
     void assertGetValueWhenConfigAssistedQueryColumn() throws SQLException {
         when(queryResult.next()).thenReturn(true).thenReturn(false);
@@ -110,6 +128,8 @@ class MergedEncryptShowCreateTableMergedResultTest {
         SimpleTableSegment simpleTableSegment = new 
SimpleTableSegment(tableNameSegment);
         
when(sqlStatementContext.getAllTables()).thenReturn(Collections.singleton(simpleTableSegment));
         
when(sqlStatementContext.getDatabaseType()).thenReturn(TypedSPILoader.getService(DatabaseType.class,
 "MySQL"));
-        return new MergedEncryptShowCreateTableMergedResult(queryResult, 
sqlStatementContext, encryptRule);
+        RuleMetaData ruleMetaData = mock(RuleMetaData.class);
+        when(ruleMetaData.getSingleRule(SQLParserRule.class)).thenReturn(new 
SQLParserRule(new SQLParserRuleConfiguration(new CacheOption(128, 1024), new 
CacheOption(2000, 65535))));
+        return new MergedEncryptShowCreateTableMergedResult(ruleMetaData, 
queryResult, sqlStatementContext, encryptRule);
     }
 }
diff --git 
a/features/mask/core/src/main/java/org/apache/shardingsphere/mask/merge/MaskResultDecoratorEngine.java
 
b/features/mask/core/src/main/java/org/apache/shardingsphere/mask/merge/MaskResultDecoratorEngine.java
index ff182069649..01d8e896e20 100644
--- 
a/features/mask/core/src/main/java/org/apache/shardingsphere/mask/merge/MaskResultDecoratorEngine.java
+++ 
b/features/mask/core/src/main/java/org/apache/shardingsphere/mask/merge/MaskResultDecoratorEngine.java
@@ -23,6 +23,7 @@ import 
org.apache.shardingsphere.infra.config.props.ConfigurationProperties;
 import org.apache.shardingsphere.infra.merge.engine.decorator.ResultDecorator;
 import 
org.apache.shardingsphere.infra.merge.engine.decorator.ResultDecoratorEngine;
 import 
org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
+import org.apache.shardingsphere.infra.metadata.database.rule.RuleMetaData;
 import org.apache.shardingsphere.mask.constant.MaskOrder;
 import org.apache.shardingsphere.mask.merge.dql.MaskDQLResultDecorator;
 import org.apache.shardingsphere.mask.rule.MaskRule;
@@ -35,7 +36,7 @@ import java.util.Optional;
 public final class MaskResultDecoratorEngine implements 
ResultDecoratorEngine<MaskRule> {
     
     @Override
-    public Optional<ResultDecorator<MaskRule>> newInstance(final 
ShardingSphereDatabase database,
+    public Optional<ResultDecorator<MaskRule>> newInstance(final RuleMetaData 
globalRuleMetaData, final ShardingSphereDatabase database,
                                                            final MaskRule 
maskRule, final ConfigurationProperties props, final SQLStatementContext 
sqlStatementContext) {
         return sqlStatementContext instanceof SelectStatementContext ? 
Optional.of(new MaskDQLResultDecorator(maskRule, (SelectStatementContext) 
sqlStatementContext)) : Optional.empty();
     }
diff --git 
a/features/mask/core/src/test/java/org/apache/shardingsphere/mask/merge/MaskResultDecoratorEngineTest.java
 
b/features/mask/core/src/test/java/org/apache/shardingsphere/mask/merge/MaskResultDecoratorEngineTest.java
index f1b6a65083b..c7db8e81096 100644
--- 
a/features/mask/core/src/test/java/org/apache/shardingsphere/mask/merge/MaskResultDecoratorEngineTest.java
+++ 
b/features/mask/core/src/test/java/org/apache/shardingsphere/mask/merge/MaskResultDecoratorEngineTest.java
@@ -23,6 +23,7 @@ import 
org.apache.shardingsphere.infra.config.props.ConfigurationProperties;
 import org.apache.shardingsphere.infra.merge.engine.ResultProcessEngine;
 import org.apache.shardingsphere.infra.merge.engine.decorator.ResultDecorator;
 import 
org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
+import org.apache.shardingsphere.infra.metadata.database.rule.RuleMetaData;
 import org.apache.shardingsphere.infra.spi.type.ordered.OrderedSPILoader;
 import org.apache.shardingsphere.mask.merge.dql.MaskDQLResultDecorator;
 import org.apache.shardingsphere.mask.rule.MaskRule;
@@ -53,7 +54,8 @@ class MaskResultDecoratorEngineTest {
     @Test
     void assertNewInstanceWithSelectStatement() {
         MaskResultDecoratorEngine engine = (MaskResultDecoratorEngine) 
OrderedSPILoader.getServices(ResultProcessEngine.class, 
Collections.singleton(rule)).get(rule);
-        Optional<ResultDecorator<MaskRule>> actual = 
engine.newInstance(database, rule, mock(ConfigurationProperties.class), 
mock(SelectStatementContext.class, RETURNS_DEEP_STUBS));
+        Optional<ResultDecorator<MaskRule>> actual =
+                engine.newInstance(mock(RuleMetaData.class), database, rule, 
mock(ConfigurationProperties.class), mock(SelectStatementContext.class, 
RETURNS_DEEP_STUBS));
         assertTrue(actual.isPresent());
         assertThat(actual.get(), instanceOf(MaskDQLResultDecorator.class));
     }
@@ -61,6 +63,6 @@ class MaskResultDecoratorEngineTest {
     @Test
     void assertNewInstanceWithOtherStatement() {
         MaskResultDecoratorEngine engine = (MaskResultDecoratorEngine) 
OrderedSPILoader.getServices(ResultProcessEngine.class, 
Collections.singleton(rule)).get(rule);
-        assertFalse(engine.newInstance(database, rule, 
mock(ConfigurationProperties.class), 
mock(InsertStatementContext.class)).isPresent());
+        assertFalse(engine.newInstance(mock(RuleMetaData.class), database, 
rule, mock(ConfigurationProperties.class), 
mock(InsertStatementContext.class)).isPresent());
     }
 }
diff --git 
a/infra/merge/src/main/java/org/apache/shardingsphere/infra/merge/MergeEngine.java
 
b/infra/merge/src/main/java/org/apache/shardingsphere/infra/merge/MergeEngine.java
index 2f3155966fa..cd931787c1d 100644
--- 
a/infra/merge/src/main/java/org/apache/shardingsphere/infra/merge/MergeEngine.java
+++ 
b/infra/merge/src/main/java/org/apache/shardingsphere/infra/merge/MergeEngine.java
@@ -30,6 +30,7 @@ import 
org.apache.shardingsphere.infra.merge.engine.merger.ResultMergerEngine;
 import org.apache.shardingsphere.infra.merge.result.MergedResult;
 import 
org.apache.shardingsphere.infra.merge.result.impl.transparent.TransparentMergedResult;
 import 
org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
+import org.apache.shardingsphere.infra.metadata.database.rule.RuleMetaData;
 import org.apache.shardingsphere.infra.rule.ShardingSphereRule;
 import org.apache.shardingsphere.infra.session.connection.ConnectionContext;
 import org.apache.shardingsphere.infra.spi.type.ordered.OrderedSPILoader;
@@ -46,6 +47,8 @@ import java.util.Optional;
 @HighFrequencyInvocation
 public final class MergeEngine {
     
+    private final RuleMetaData globalRuleMetaData;
+    
     private final ShardingSphereDatabase database;
     
     private final ConfigurationProperties props;
@@ -55,7 +58,8 @@ public final class MergeEngine {
     
     private final ConnectionContext connectionContext;
     
-    public MergeEngine(final ShardingSphereDatabase database, final 
ConfigurationProperties props, final ConnectionContext connectionContext) {
+    public MergeEngine(final RuleMetaData globalRuleMetaData, final 
ShardingSphereDatabase database, final ConfigurationProperties props, final 
ConnectionContext connectionContext) {
+        this.globalRuleMetaData = globalRuleMetaData;
         this.database = database;
         this.props = props;
         engines = OrderedSPILoader.getServices(ResultProcessEngine.class, 
database.getRuleMetaData().getRules());
@@ -113,6 +117,7 @@ public final class MergeEngine {
     
     @SuppressWarnings({"unchecked", "rawtypes"})
     private ResultDecorator getResultDecorator(final SQLStatementContext 
sqlStatementContext, final Entry<ShardingSphereRule, ResultProcessEngine> 
entry) {
-        return (ResultDecorator) ((ResultDecoratorEngine) 
entry.getValue()).newInstance(database, entry.getKey(), props, 
sqlStatementContext).orElseGet(TransparentResultDecorator::new);
+        return (ResultDecorator) ((ResultDecoratorEngine) 
entry.getValue()).newInstance(globalRuleMetaData, database, entry.getKey(), 
props, sqlStatementContext)
+                .orElseGet(TransparentResultDecorator::new);
     }
 }
diff --git 
a/infra/merge/src/main/java/org/apache/shardingsphere/infra/merge/engine/decorator/ResultDecoratorEngine.java
 
b/infra/merge/src/main/java/org/apache/shardingsphere/infra/merge/engine/decorator/ResultDecoratorEngine.java
index c41ec08dcc5..83baab91121 100644
--- 
a/infra/merge/src/main/java/org/apache/shardingsphere/infra/merge/engine/decorator/ResultDecoratorEngine.java
+++ 
b/infra/merge/src/main/java/org/apache/shardingsphere/infra/merge/engine/decorator/ResultDecoratorEngine.java
@@ -21,6 +21,7 @@ import 
org.apache.shardingsphere.infra.binder.context.statement.SQLStatementCont
 import org.apache.shardingsphere.infra.config.props.ConfigurationProperties;
 import org.apache.shardingsphere.infra.merge.engine.ResultProcessEngine;
 import 
org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
+import org.apache.shardingsphere.infra.metadata.database.rule.RuleMetaData;
 import org.apache.shardingsphere.infra.rule.ShardingSphereRule;
 
 import java.util.Optional;
@@ -34,12 +35,13 @@ public interface ResultDecoratorEngine<T extends 
ShardingSphereRule> extends Res
     
     /**
      * Create new instance of result decorator.
-     * 
+     *
+     * @param globalRuleMetaData global rule meta data
      * @param database database
      * @param rule rule
      * @param props configuration properties
      * @param sqlStatementContext SQL statement context
      * @return created instance
      */
-    Optional<ResultDecorator<T>> newInstance(ShardingSphereDatabase database, 
T rule, ConfigurationProperties props, SQLStatementContext sqlStatementContext);
+    Optional<ResultDecorator<T>> newInstance(RuleMetaData globalRuleMetaData, 
ShardingSphereDatabase database, T rule, ConfigurationProperties props, 
SQLStatementContext sqlStatementContext);
 }
diff --git 
a/infra/merge/src/test/java/org/apache/shardingsphere/infra/merge/MergeEngineTest.java
 
b/infra/merge/src/test/java/org/apache/shardingsphere/infra/merge/MergeEngineTest.java
index d40395b26f8..e22aed41204 100644
--- 
a/infra/merge/src/test/java/org/apache/shardingsphere/infra/merge/MergeEngineTest.java
+++ 
b/infra/merge/src/test/java/org/apache/shardingsphere/infra/merge/MergeEngineTest.java
@@ -19,6 +19,7 @@ package org.apache.shardingsphere.infra.merge;
 
 import 
org.apache.shardingsphere.infra.binder.context.statement.SQLStatementContext;
 import org.apache.shardingsphere.infra.config.props.ConfigurationProperties;
+import org.apache.shardingsphere.infra.metadata.database.rule.RuleMetaData;
 import org.apache.shardingsphere.infra.session.connection.ConnectionContext;
 import 
org.apache.shardingsphere.infra.executor.sql.execute.result.query.QueryResult;
 import org.apache.shardingsphere.infra.merge.fixture.rule.DecoratorRuleFixture;
@@ -58,32 +59,36 @@ class MergeEngineTest {
     void assertMergeWithIndependentRule() throws SQLException {
         
when(database.getRuleMetaData().getRules()).thenReturn(Collections.singleton(new
 MockedRule()));
         when(queryResult.getValue(1, String.class)).thenReturn("test");
-        MergedResult actual = new MergeEngine(database, new 
ConfigurationProperties(new Properties()), 
mock(ConnectionContext.class)).merge(Collections.singletonList(queryResult),
-                mock(SQLStatementContext.class));
+        MergedResult actual =
+                new MergeEngine(mock(RuleMetaData.class), database, new 
ConfigurationProperties(new Properties()), 
mock(ConnectionContext.class)).merge(Collections.singletonList(queryResult),
+                        mock(SQLStatementContext.class));
         assertThat(actual.getValue(1, String.class), is("test"));
     }
     
     @Test
     void assertMergeWithMergerRuleOnly() throws SQLException {
         
when(database.getRuleMetaData().getRules()).thenReturn(Collections.singleton(new
 MergerRuleFixture()));
-        MergedResult actual = new MergeEngine(database, new 
ConfigurationProperties(new Properties()), 
mock(ConnectionContext.class)).merge(Collections.singletonList(queryResult),
-                mock(SQLStatementContext.class));
+        MergedResult actual =
+                new MergeEngine(mock(RuleMetaData.class), database, new 
ConfigurationProperties(new Properties()), 
mock(ConnectionContext.class)).merge(Collections.singletonList(queryResult),
+                        mock(SQLStatementContext.class));
         assertThat(actual.getValue(1, String.class), is("merged_value"));
     }
     
     @Test
     void assertMergeWithDecoratorRuleOnly() throws SQLException {
         
when(database.getRuleMetaData().getRules()).thenReturn(Collections.singleton(new
 DecoratorRuleFixture()));
-        MergedResult actual = new MergeEngine(database, new 
ConfigurationProperties(new Properties()), 
mock(ConnectionContext.class)).merge(Collections.singletonList(queryResult),
-                mock(SQLStatementContext.class));
+        MergedResult actual =
+                new MergeEngine(mock(RuleMetaData.class), database, new 
ConfigurationProperties(new Properties()), 
mock(ConnectionContext.class)).merge(Collections.singletonList(queryResult),
+                        mock(SQLStatementContext.class));
         assertThat(actual.getValue(1, String.class), is("decorated_value"));
     }
     
     @Test
     void assertMergeWithMergerRuleAndDecoratorRuleTogether() throws 
SQLException {
         
when(database.getRuleMetaData().getRules()).thenReturn(Arrays.asList(new 
MergerRuleFixture(), new DecoratorRuleFixture()));
-        MergedResult actual = new MergeEngine(database, new 
ConfigurationProperties(new Properties()), 
mock(ConnectionContext.class)).merge(Collections.singletonList(queryResult),
-                mock(SQLStatementContext.class));
+        MergedResult actual =
+                new MergeEngine(mock(RuleMetaData.class), database, new 
ConfigurationProperties(new Properties()), 
mock(ConnectionContext.class)).merge(Collections.singletonList(queryResult),
+                        mock(SQLStatementContext.class));
         assertThat(actual.getValue(1, String.class), 
is("decorated_merged_value"));
     }
 }
diff --git 
a/infra/merge/src/test/java/org/apache/shardingsphere/infra/merge/fixture/decorator/ResultDecoratorEngineFixture.java
 
b/infra/merge/src/test/java/org/apache/shardingsphere/infra/merge/fixture/decorator/ResultDecoratorEngineFixture.java
index 608c044eac4..fe559ebbae9 100644
--- 
a/infra/merge/src/test/java/org/apache/shardingsphere/infra/merge/fixture/decorator/ResultDecoratorEngineFixture.java
+++ 
b/infra/merge/src/test/java/org/apache/shardingsphere/infra/merge/fixture/decorator/ResultDecoratorEngineFixture.java
@@ -23,13 +23,14 @@ import 
org.apache.shardingsphere.infra.merge.engine.decorator.ResultDecorator;
 import 
org.apache.shardingsphere.infra.merge.engine.decorator.ResultDecoratorEngine;
 import org.apache.shardingsphere.infra.merge.fixture.rule.DecoratorRuleFixture;
 import 
org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
+import org.apache.shardingsphere.infra.metadata.database.rule.RuleMetaData;
 
 import java.util.Optional;
 
 public final class ResultDecoratorEngineFixture implements 
ResultDecoratorEngine<DecoratorRuleFixture> {
     
     @Override
-    public Optional<ResultDecorator<DecoratorRuleFixture>> newInstance(final 
ShardingSphereDatabase database,
+    public Optional<ResultDecorator<DecoratorRuleFixture>> newInstance(final 
RuleMetaData globalRuleMetaData, final ShardingSphereDatabase database,
                                                                        final 
DecoratorRuleFixture rule, final ConfigurationProperties props, final 
SQLStatementContext sqlStatementContext) {
         return Optional.of(new ResultDecoratorFixture());
     }
diff --git 
a/jdbc/src/main/java/org/apache/shardingsphere/driver/jdbc/core/statement/ShardingSpherePreparedStatement.java
 
b/jdbc/src/main/java/org/apache/shardingsphere/driver/jdbc/core/statement/ShardingSpherePreparedStatement.java
index a3afae022b5..9a2e1320203 100644
--- 
a/jdbc/src/main/java/org/apache/shardingsphere/driver/jdbc/core/statement/ShardingSpherePreparedStatement.java
+++ 
b/jdbc/src/main/java/org/apache/shardingsphere/driver/jdbc/core/statement/ShardingSpherePreparedStatement.java
@@ -597,7 +597,7 @@ public final class ShardingSpherePreparedStatement extends 
AbstractPreparedState
     }
     
     private MergedResult mergeQuery(final List<QueryResult> queryResults, 
final SQLStatementContext sqlStatementContext) throws SQLException {
-        MergeEngine mergeEngine = new 
MergeEngine(metaDataContexts.getMetaData().getDatabase(databaseName),
+        MergeEngine mergeEngine = new 
MergeEngine(metaDataContexts.getMetaData().getGlobalRuleMetaData(), 
metaDataContexts.getMetaData().getDatabase(databaseName),
                 metaDataContexts.getMetaData().getProps(), 
connection.getDatabaseConnectionManager().getConnectionContext());
         return mergeEngine.merge(queryResults, sqlStatementContext);
     }
diff --git 
a/jdbc/src/main/java/org/apache/shardingsphere/driver/jdbc/core/statement/ShardingSphereStatement.java
 
b/jdbc/src/main/java/org/apache/shardingsphere/driver/jdbc/core/statement/ShardingSphereStatement.java
index fb9e7012826..aea3748b502 100644
--- 
a/jdbc/src/main/java/org/apache/shardingsphere/driver/jdbc/core/statement/ShardingSphereStatement.java
+++ 
b/jdbc/src/main/java/org/apache/shardingsphere/driver/jdbc/core/statement/ShardingSphereStatement.java
@@ -29,7 +29,6 @@ import 
org.apache.shardingsphere.driver.jdbc.adapter.AbstractStatementAdapter;
 import 
org.apache.shardingsphere.driver.jdbc.core.connection.ShardingSphereConnection;
 import 
org.apache.shardingsphere.driver.jdbc.core.resultset.GeneratedKeysResultSet;
 import 
org.apache.shardingsphere.driver.jdbc.core.resultset.ShardingSphereResultSet;
-import 
org.apache.shardingsphere.infra.exception.kernel.syntax.EmptySQLException;
 import org.apache.shardingsphere.infra.annotation.HighFrequencyInvocation;
 import 
org.apache.shardingsphere.infra.binder.context.segment.insert.keygen.GeneratedKeyContext;
 import 
org.apache.shardingsphere.infra.binder.context.statement.SQLStatementContext;
@@ -41,6 +40,7 @@ import 
org.apache.shardingsphere.infra.connection.kernel.KernelProcessor;
 import org.apache.shardingsphere.infra.database.core.type.DatabaseType;
 import org.apache.shardingsphere.infra.database.mysql.type.MySQLDatabaseType;
 import 
org.apache.shardingsphere.infra.exception.dialect.SQLExceptionTransformEngine;
+import 
org.apache.shardingsphere.infra.exception.kernel.syntax.EmptySQLException;
 import org.apache.shardingsphere.infra.executor.audit.SQLAuditEngine;
 import org.apache.shardingsphere.infra.executor.kernel.model.ExecutionGroup;
 import 
org.apache.shardingsphere.infra.executor.kernel.model.ExecutionGroupContext;
@@ -642,7 +642,7 @@ public final class ShardingSphereStatement extends 
AbstractStatementAdapter {
     }
     
     private MergedResult mergeQuery(final List<QueryResult> queryResults, 
final SQLStatementContext sqlStatementContext) throws SQLException {
-        MergeEngine mergeEngine = new 
MergeEngine(metaDataContexts.getMetaData().getDatabase(databaseName),
+        MergeEngine mergeEngine = new 
MergeEngine(metaDataContexts.getMetaData().getGlobalRuleMetaData(), 
metaDataContexts.getMetaData().getDatabase(databaseName),
                 metaDataContexts.getMetaData().getProps(), 
connection.getDatabaseConnectionManager().getConnectionContext());
         return mergeEngine.merge(queryResults, sqlStatementContext);
     }
diff --git 
a/kernel/sql-federation/executor/src/main/java/org/apache/shardingsphere/sqlfederation/executor/enumerable/EnumerableScanExecutor.java
 
b/kernel/sql-federation/executor/src/main/java/org/apache/shardingsphere/sqlfederation/executor/enumerable/EnumerableScanExecutor.java
index 811d5203d49..cce7fc4e64d 100644
--- 
a/kernel/sql-federation/executor/src/main/java/org/apache/shardingsphere/sqlfederation/executor/enumerable/EnumerableScanExecutor.java
+++ 
b/kernel/sql-federation/executor/src/main/java/org/apache/shardingsphere/sqlfederation/executor/enumerable/EnumerableScanExecutor.java
@@ -114,12 +114,12 @@ public final class EnumerableScanExecutor implements 
ScanExecutor {
         }
         QueryContext queryContext = 
createQueryContext(federationContext.getMetaData(), scanContext, databaseType, 
federationContext.getQueryContext().isUseCache());
         ShardingSphereDatabase database = 
federationContext.getMetaData().getDatabase(databaseName);
-        ExecutionContext context = new 
KernelProcessor().generateExecutionContext(queryContext, database, 
globalRuleMetaData, executorContext.getProps(), new ConnectionContext());
+        ExecutionContext executionContext = new 
KernelProcessor().generateExecutionContext(queryContext, database, 
globalRuleMetaData, executorContext.getProps(), new ConnectionContext());
         if (federationContext.isPreview()) {
-            
federationContext.getPreviewExecutionUnits().addAll(context.getExecutionUnits());
+            
federationContext.getPreviewExecutionUnits().addAll(executionContext.getExecutionUnits());
             return createEmptyEnumerable();
         }
-        return createJDBCEnumerable(queryContext, database, context);
+        return createJDBCEnumerable(queryContext, database, executionContext);
     }
     
     private AbstractEnumerable<Object> createJDBCEnumerable(final QueryContext 
queryContext, final ShardingSphereDatabase database, final ExecutionContext 
context) {
@@ -137,7 +137,7 @@ public final class EnumerableScanExecutor implements 
ScanExecutor {
                         SQLExecutionInterruptedException::new);
                 processEngine.executeSQL(executionGroupContext, 
federationContext.getQueryContext());
                 List<QueryResult> queryResults = 
jdbcExecutor.execute(executionGroupContext, 
callback).stream().map(QueryResult.class::cast).collect(Collectors.toList());
-                MergeEngine mergeEngine = new MergeEngine(database, 
executorContext.getProps(), new ConnectionContext());
+                MergeEngine mergeEngine = new 
MergeEngine(federationContext.getMetaData().getGlobalRuleMetaData(), database, 
executorContext.getProps(), new ConnectionContext());
                 MergedResult mergedResult = mergeEngine.merge(queryResults, 
queryContext.getSqlStatementContext());
                 Collection<Statement> statements = 
getStatements(executionGroupContext.getInputGroups());
                 return new JDBCRowEnumerator(mergedResult, 
queryResults.get(0).getMetaData(), statements);
diff --git 
a/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/connector/DatabaseConnector.java
 
b/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/connector/DatabaseConnector.java
index 9946dcc9c85..41ad964d490 100644
--- 
a/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/connector/DatabaseConnector.java
+++ 
b/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/connector/DatabaseConnector.java
@@ -321,8 +321,8 @@ public final class DatabaseConnector implements 
DatabaseBackendHandler {
     }
     
     private MergedResult mergeQuery(final SQLStatementContext 
sqlStatementContext, final List<QueryResult> queryResults) throws SQLException {
-        MergeEngine mergeEngine = new MergeEngine(database, 
ProxyContext.getInstance().getContextManager().getMetaDataContexts().getMetaData().getProps(),
-                
databaseConnectionManager.getConnectionSession().getConnectionContext());
+        ShardingSphereMetaData metaData = 
ProxyContext.getInstance().getContextManager().getMetaDataContexts().getMetaData();
+        MergeEngine mergeEngine = new 
MergeEngine(metaData.getGlobalRuleMetaData(), database, metaData.getProps(), 
databaseConnectionManager.getConnectionSession().getConnectionContext());
         return mergeEngine.merge(queryResults, sqlStatementContext);
     }
     

Reply via email to