From 9f34f5b6f892db50061f958e1b09d44cfe61d497 Mon Sep 17 00:00:00 2001 From: duanzhengqiang Date: Fri, 26 Apr 2024 17:16:56 +0800 Subject: [PATCH] Fix show create table wrong result with encrypt when data type contains float --- features/encrypt/core/pom.xml | 41 ++++++++++++++++++ .../merge/EncryptResultDecoratorEngine.java | 5 ++- .../merge/dal/EncryptDALResultDecorator.java | 9 +++- ...tedEncryptShowCreateTableMergedResult.java | 6 ++- .../EncryptShowCreateTableMergedResult.java | 43 +++++++++++-------- ...gedEncryptShowCreateTableMergedResult.java | 6 ++- .../EncryptResultDecoratorEngineTest.java | 8 ++-- .../dal/EncryptDALResultDecoratorTest.java | 12 ++++-- ...ncryptShowCreateTableMergedResultTest.java | 22 +++++++++- ...ncryptShowCreateTableMergedResultTest.java | 22 +++++++++- .../mask/merge/MaskResultDecoratorEngine.java | 3 +- .../merge/MaskResultDecoratorEngineTest.java | 6 ++- .../infra/merge/MergeEngine.java | 9 +++- .../decorator/ResultDecoratorEngine.java | 6 ++- .../infra/merge/MergeEngineTest.java | 21 +++++---- .../ResultDecoratorEngineFixture.java | 3 +- .../ShardingSpherePreparedStatement.java | 2 +- .../statement/ShardingSphereStatement.java | 4 +- .../enumerable/EnumerableScanExecutor.java | 8 ++-- .../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 f9229753b572f..b35757923476e 100644 --- a/features/encrypt/core/pom.xml +++ b/features/encrypt/core/pom.xml @@ -52,6 +52,11 @@ shardingsphere-infra-algorithm-message-digest-md5 ${project.version} + + org.apache.shardingsphere + shardingsphere-sql-parser-core + ${project.version} + org.apache.shardingsphere @@ -77,6 +82,42 @@ ${project.version} test + + org.apache.shardingsphere + shardingsphere-parser-sql-sql92 + ${project.version} + test + + + org.apache.shardingsphere + shardingsphere-parser-sql-mysql + ${project.version} + test + + + org.apache.shardingsphere + shardingsphere-parser-sql-postgresql + ${project.version} + test + + + org.apache.shardingsphere + shardingsphere-parser-sql-opengauss + ${project.version} + test + + + org.apache.shardingsphere + shardingsphere-parser-sql-oracle + ${project.version} + test + + + org.apache.shardingsphere + shardingsphere-parser-sql-sqlserver + ${project.version} + test + commons-codec 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 545e410d01fbb..becf7a42d32b6 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.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 @@ public final class EncryptResultDecoratorEngine implements ResultDecoratorEngine { @Override - public Optional> newInstance(final ShardingSphereDatabase database, + public Optional> 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 26a941fb08602..40056628d43cb 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.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 @@ /** * DAL result decorator for encrypt. */ +@RequiredArgsConstructor public final class EncryptDALResultDecorator implements ResultDecorator { + 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 MergedResult decorate(final QueryResult queryResult, final SQLStatementCo 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 MergedResult decorate(final MergedResult mergedResult, final SQLStatement 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 6e86e6bd0d717..2c8b6624cba0a 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 @@ 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 77f5256c32310..01ff9de14563f 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 @@ */ 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 final Object getValue(final int columnIndex, final Class type) throws if (!encryptTable.isPresent() || !result.contains("(")) { return result; } - StringBuilder builder = new StringBuilder(result.substring(0, result.indexOf('(') + 1)); - List 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 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 findLogicColumnDefinition(final String columnDefinition, final EncryptTable encryptTable) { - String columnName = dialectDatabaseMetaData.getQuoteCharacter().unwrap(columnDefinition.trim().split("\\s+")[0]); + private Optional 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 c906f0a06cfd0..db7485ea2ec6f 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 @@ 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 ec44ff8b05cb0..d29ea872841de 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.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> actual = engine.newInstance(database, rule, mock(ConfigurationProperties.class), mock(SelectStatementContext.class, RETURNS_DEEP_STUBS)); + Optional> 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 @@ void assertNewInstanceWithDALStatement() { 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> actual = engine.newInstance(database, rule, mock(ConfigurationProperties.class), sqlStatementContext); + Optional> 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 @@ void assertNewInstanceWithDALStatement() { @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 c8393c1778445..76565afbb9854 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.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 @@ void assertMergedResultWithDescribeStatement() { @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 @@ void assertMergedResultWithShowColumnsStatement() { @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 @@ void assertMergedResultWithShowCreateTableStatement() { @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 3eaa8e52b2f1a..4ee123b250770 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.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 @@ void assertNextWhenNextNotExist() throws SQLException { 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 @@ private DecoratedEncryptShowCreateTableMergedResult createDecoratedEncryptShowCr 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 d151f935e51d3..fcf54f229cf90 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.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 @@ void assertNextWhenNextNotExist() throws SQLException { 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 @@ private MergedEncryptShowCreateTableMergedResult createMergedEncryptShowCreateTa 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 ff18206964948..01d8e896e204f 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.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 @@ public final class MaskResultDecoratorEngine implements ResultDecoratorEngine { @Override - public Optional> newInstance(final ShardingSphereDatabase database, + public Optional> 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 f1b6a65083b43..c7db8e8109655 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.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> actual = engine.newInstance(database, rule, mock(ConfigurationProperties.class), mock(SelectStatementContext.class, RETURNS_DEEP_STUBS)); + Optional> 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 @@ void assertNewInstanceWithSelectStatement() { @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 2f3155966fa18..cd931787c1db8 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.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 @@ @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 @@ private Optional decorate(final QueryResult queryResult, final SQL @SuppressWarnings({"unchecked", "rawtypes"}) private ResultDecorator getResultDecorator(final SQLStatementContext sqlStatementContext, final Entry 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 c41ec08dcc5fa..83baab91121b7 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.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 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> newInstance(ShardingSphereDatabase database, T rule, ConfigurationProperties props, SQLStatementContext sqlStatementContext); + Optional> 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 d40395b26f861..e22aed412046a 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 @@ 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 608c044eac483..fe559ebbae985 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.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 { @Override - public Optional> newInstance(final ShardingSphereDatabase database, + public Optional> 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 a3afae022b523..9a2e1320203c6 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 @@ private QueryContext createQueryContext() { } private MergedResult mergeQuery(final List 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 fb9e701282624..aea3748b5024b 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.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.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 @@ private List getQueryResults(final List resultSets) thro } private MergedResult mergeQuery(final List 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 811d5203d4960..cce7fc4e64d66 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 Enumerable execute(final ShardingSphereTable table, final ScanExe } 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 createJDBCEnumerable(final QueryContext queryContext, final ShardingSphereDatabase database, final ExecutionContext context) { @@ -137,7 +137,7 @@ public Enumerator enumerator() { SQLExecutionInterruptedException::new); processEngine.executeSQL(executionGroupContext, federationContext.getQueryContext()); List 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 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 9946dcc9c853d..41ad964d490b7 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 @@ private QueryHeader createQueryHeader(final QueryHeaderBuilderEngine queryHeader } private MergedResult mergeQuery(final SQLStatementContext sqlStatementContext, final List 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); }