This is an automated email from the ASF dual-hosted git repository. jiangmaolin pushed a commit to branch dev-5.5.1 in repository https://gitbox.apache.org/repos/asf/shardingsphere.git
commit 603c222daaf7e4db275725ac56d08f77d70ed3ae Author: Raigor <[email protected]> AuthorDate: Wed Oct 30 22:59:49 2024 +0800 Pick fix commits in 5.5.1-fix from apache (#27) * Pick 5.5.0-fix #15, optimize the rollback strategy for import database config failed * Pick #33248, Check weight load balancer props when create readwrite-splitting rule * Pick #33274, Add query parameters and check for mysql kill processId * Pick #33367, Remove ShardingRouteAlgorithmException check logic temporarily to support different actual table name config * Pick #33346, Fix missing logic db when query information_schema.SCHEMATA with NOT IN clause * Pick #33370, Fix table does not exist exception when use HintManager#setDatabaseName to transparent --- .../ReadwriteSplittingRuleStatementChecker.java | 30 +++++++++++++--- .../AlterReadwriteSplittingRuleExecutorTest.java | 40 ++++++++++++++------- .../CreateReadwriteSplittingRuleExecutorTest.java | 41 ++++++++++++++-------- .../type/standard/StandardShardingStrategy.java | 4 +-- .../ShardingStandardRoutingEngineTest.java | 3 ++ .../infra/binder/engine/SQLBindEngine.java | 3 +- .../driver/ShardingSphereDriverTest.java | 24 +++++++++++++ .../statement/type/MySQLDALStatementVisitor.java | 6 ++++ .../core/statement/dal/KillStatement.java | 2 ++ .../YamlDatabaseConfigurationImportExecutor.java | 17 ++++++++- .../admin/executor/KillProcessExecutor.java | 6 ++++ .../SelectInformationSchemataExecutor.java | 2 +- 12 files changed, 140 insertions(+), 38 deletions(-) diff --git a/features/readwrite-splitting/distsql/handler/src/main/java/org/apache/shardingsphere/readwritesplitting/distsql/handler/checker/ReadwriteSplittingRuleStatementChecker.java b/features/readwrite-splitting/distsql/handler/src/main/java/org/apache/shardingsphere/readwritesplitting/distsql/handler/checker/ReadwriteSplittingRuleStatementChecker.java index 17f69afec6b..894a61dc1c9 100644 --- a/features/readwrite-splitting/distsql/handler/src/main/java/org/apache/shardingsphere/readwritesplitting/distsql/handler/checker/ReadwriteSplittingRuleStatementChecker.java +++ b/features/readwrite-splitting/distsql/handler/src/main/java/org/apache/shardingsphere/readwritesplitting/distsql/handler/checker/ReadwriteSplittingRuleStatementChecker.java @@ -20,6 +20,8 @@ package org.apache.shardingsphere.readwritesplitting.distsql.handler.checker; import com.google.common.base.Strings; import lombok.AccessLevel; import lombok.NoArgsConstructor; +import org.apache.shardingsphere.distsql.segment.AlgorithmSegment; +import org.apache.shardingsphere.infra.algorithm.core.exception.InvalidAlgorithmConfigurationException; import org.apache.shardingsphere.infra.algorithm.loadbalancer.core.LoadBalanceAlgorithm; import org.apache.shardingsphere.infra.exception.core.ShardingSpherePreconditions; import org.apache.shardingsphere.infra.exception.kernel.metadata.resource.storageunit.MissingRequiredStorageUnitsException; @@ -33,11 +35,11 @@ import org.apache.shardingsphere.infra.rule.attribute.datasource.DataSourceMappe import org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader; import org.apache.shardingsphere.readwritesplitting.config.ReadwriteSplittingRuleConfiguration; import org.apache.shardingsphere.readwritesplitting.config.rule.ReadwriteSplittingDataSourceGroupRuleConfiguration; -import org.apache.shardingsphere.readwritesplitting.transaction.TransactionalReadQueryStrategy; import org.apache.shardingsphere.readwritesplitting.constant.ReadwriteSplittingDataSourceType; import org.apache.shardingsphere.readwritesplitting.distsql.segment.ReadwriteSplittingRuleSegment; import org.apache.shardingsphere.readwritesplitting.exception.ReadwriteSplittingRuleExceptionIdentifier; import org.apache.shardingsphere.readwritesplitting.exception.actual.DuplicateReadwriteSplittingActualDataSourceException; +import org.apache.shardingsphere.readwritesplitting.transaction.TransactionalReadQueryStrategy; import java.util.Arrays; import java.util.Collection; @@ -46,7 +48,6 @@ import java.util.HashSet; import java.util.LinkedHashSet; import java.util.LinkedList; import java.util.Map.Entry; -import java.util.Objects; import java.util.stream.Collectors; /** @@ -218,7 +219,28 @@ public final class ReadwriteSplittingRuleStatementChecker { } private static void checkLoadBalancers(final Collection<ReadwriteSplittingRuleSegment> segments) { - segments.stream().map(ReadwriteSplittingRuleSegment::getLoadBalancer).filter(Objects::nonNull) - .forEach(each -> TypedSPILoader.checkService(LoadBalanceAlgorithm.class, each.getName(), each.getProps())); + for (ReadwriteSplittingRuleSegment each : segments) { + AlgorithmSegment loadBalancer = each.getLoadBalancer(); + if (loadBalancer != null) { + TypedSPILoader.checkService(LoadBalanceAlgorithm.class, loadBalancer.getName(), loadBalancer.getProps()); + checkProperties(each); + } + } + } + + private static void checkProperties(final ReadwriteSplittingRuleSegment each) { + if ("WEIGHT".equalsIgnoreCase(each.getLoadBalancer().getName())) { + ShardingSpherePreconditions.checkNotEmpty(each.getLoadBalancer().getProps(), + () -> new InvalidAlgorithmConfigurationException("Load balancer", each.getLoadBalancer().getName())); + checkDataSource(each); + } + } + + private static void checkDataSource(final ReadwriteSplittingRuleSegment ruleSegment) { + for (Object each : ruleSegment.getLoadBalancer().getProps().keySet()) { + String dataSourceName = (String) each; + ShardingSpherePreconditions.checkState(ruleSegment.getReadDataSources().contains(dataSourceName) || ruleSegment.getWriteDataSource().equals(dataSourceName), + () -> new InvalidAlgorithmConfigurationException("Load balancer", ruleSegment.getLoadBalancer().getName())); + } } } diff --git a/features/readwrite-splitting/distsql/handler/src/test/java/org/apache/shardingsphere/readwritesplitting/distsql/handler/update/AlterReadwriteSplittingRuleExecutorTest.java b/features/readwrite-splitting/distsql/handler/src/test/java/org/apache/shardingsphere/readwritesplitting/distsql/handler/update/AlterReadwriteSplittingRuleExecutorTest.java index 9db2fe18acb..f8f97d97dd5 100644 --- a/features/readwrite-splitting/distsql/handler/src/test/java/org/apache/shardingsphere/readwritesplitting/distsql/handler/update/AlterReadwriteSplittingRuleExecutorTest.java +++ b/features/readwrite-splitting/distsql/handler/src/test/java/org/apache/shardingsphere/readwritesplitting/distsql/handler/update/AlterReadwriteSplittingRuleExecutorTest.java @@ -18,6 +18,7 @@ package org.apache.shardingsphere.readwritesplitting.distsql.handler.update; import org.apache.shardingsphere.distsql.segment.AlgorithmSegment; +import org.apache.shardingsphere.infra.algorithm.core.exception.InvalidAlgorithmConfigurationException; import org.apache.shardingsphere.infra.exception.kernel.metadata.resource.storageunit.MissingRequiredStorageUnitsException; import org.apache.shardingsphere.infra.exception.kernel.metadata.rule.MissingRequiredRuleException; import org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase; @@ -29,6 +30,8 @@ import org.apache.shardingsphere.readwritesplitting.distsql.segment.ReadwriteSpl import org.apache.shardingsphere.readwritesplitting.distsql.statement.AlterReadwriteSplittingRuleStatement; import org.apache.shardingsphere.readwritesplitting.exception.actual.DuplicateReadwriteSplittingActualDataSourceException; import org.apache.shardingsphere.readwritesplitting.rule.ReadwriteSplittingRule; +import org.apache.shardingsphere.test.util.PropertiesBuilder; +import org.apache.shardingsphere.test.util.PropertiesBuilder.Property; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -74,7 +77,7 @@ class AlterReadwriteSplittingRuleExecutorTest { } @Test - void assertCheckSQLStatementWithoutExistedResources() { + void assertCheckSQLStatementWithNotExistedDataSources() { when(resourceMetaData.getNotExistedDataSources(any())).thenReturn(Collections.singleton("read_ds_0")); ReadwriteSplittingRule rule = mock(ReadwriteSplittingRule.class); when(rule.getConfiguration()).thenReturn(createCurrentRuleConfiguration()); @@ -93,18 +96,18 @@ class AlterReadwriteSplittingRuleExecutorTest { } @Test - void assertCheckSQLStatementWithDuplicateWriteResourceNamesInStatement() { + void assertCheckSQLStatementWithDuplicateWriteDataSourcesInStatement() { ShardingSphereDatabase database = mock(ShardingSphereDatabase.class, RETURNS_DEEP_STUBS); when(database.getResourceMetaData()).thenReturn(resourceMetaData); ReadwriteSplittingRule rule = mock(ReadwriteSplittingRule.class); when(rule.getConfiguration()).thenReturn(createCurrentRuleConfigurationWithMultipleRules()); executor.setRule(rule); assertThrows(DuplicateReadwriteSplittingActualDataSourceException.class, - () -> executor.checkBeforeUpdate(createSQLStatementWithDuplicateWriteResourceNames("readwrite_ds_0", "readwrite_ds_1", "TEST"))); + () -> executor.checkBeforeUpdate(createSQLStatementWithDuplicateWriteDataSources("readwrite_ds_0", "readwrite_ds_1", "TEST"))); } @Test - void assertCheckSQLStatementWithDuplicateWriteResourceNames() { + void assertCheckSQLStatementWithDuplicateWriteDataSources() { ShardingSphereDatabase database = mock(ShardingSphereDatabase.class, RETURNS_DEEP_STUBS); when(database.getResourceMetaData()).thenReturn(resourceMetaData); ReadwriteSplittingRule rule = mock(ReadwriteSplittingRule.class); @@ -112,29 +115,39 @@ class AlterReadwriteSplittingRuleExecutorTest { executor.setRule(rule); assertThrows(DuplicateReadwriteSplittingActualDataSourceException.class, () -> executor.checkBeforeUpdate( - createSQLStatement("readwrite_ds_0", "ds_write_1", Arrays.asList("read_ds_0", "read_ds_1"), "TEST"))); + createSQLStatement("readwrite_ds_0", "ds_write_1", Arrays.asList("read_ds_0", "read_ds_1"), "TEST", new Properties()))); } @Test - void assertCheckSQLStatementWithDuplicateReadResourceNamesInStatement() { + void assertCheckSQLStatementWithDuplicateReadDataSourcesInStatement() { ShardingSphereDatabase database = mock(ShardingSphereDatabase.class, RETURNS_DEEP_STUBS); when(database.getResourceMetaData()).thenReturn(resourceMetaData); ReadwriteSplittingRule rule = mock(ReadwriteSplittingRule.class); when(rule.getConfiguration()).thenReturn(createCurrentRuleConfigurationWithMultipleRules()); executor.setRule(rule); assertThrows(DuplicateReadwriteSplittingActualDataSourceException.class, - () -> executor.checkBeforeUpdate(createSQLStatementWithDuplicateReadResourceNames("readwrite_ds_0", "readwrite_ds_1", "TEST"))); + () -> executor.checkBeforeUpdate(createSQLStatementWithDuplicateReadDataSources("readwrite_ds_0", "readwrite_ds_1", "TEST"))); } @Test - void assertCheckSQLStatementWithDuplicateReadResourceNames() { + void assertCheckSQLStatementWithDuplicateReadDataSources() { ShardingSphereDatabase database = mock(ShardingSphereDatabase.class, RETURNS_DEEP_STUBS); when(database.getResourceMetaData()).thenReturn(resourceMetaData); ReadwriteSplittingRule rule = mock(ReadwriteSplittingRule.class); when(rule.getConfiguration()).thenReturn(createCurrentRuleConfigurationWithMultipleRules()); executor.setRule(rule); assertThrows(DuplicateReadwriteSplittingActualDataSourceException.class, - () -> executor.checkBeforeUpdate(createSQLStatement("readwrite_ds_1", "write_ds_1", Arrays.asList("read_ds_0_0", "read_ds_0_1"), "TEST"))); + () -> executor.checkBeforeUpdate(createSQLStatement("readwrite_ds_1", "write_ds_1", Arrays.asList("read_ds_0_0", "read_ds_0_1"), "TEST", new Properties()))); + } + + @Test + void assertCheckSQLStatementWithInvalidLoadBalancerProperties() { + ReadwriteSplittingRule rule = mock(ReadwriteSplittingRule.class); + when(rule.getConfiguration()).thenReturn(createCurrentRuleConfiguration()); + executor.setRule(rule); + assertThrows(InvalidAlgorithmConfigurationException.class, + () -> executor.checkBeforeUpdate(createSQLStatement("readwrite_ds", "write_ds", Arrays.asList("read_ds_0", "read_ds_1"), "weight", + PropertiesBuilder.build(new Property("read_ds_0", "5"), new Property("read_ds_2", "5"))))); } private AlterReadwriteSplittingRuleStatement createSQLStatement(final String loadBalancerTypeName) { @@ -143,12 +156,13 @@ class AlterReadwriteSplittingRuleExecutorTest { return new AlterReadwriteSplittingRuleStatement(Collections.singleton(ruleSegment)); } - private AlterReadwriteSplittingRuleStatement createSQLStatement(final String ruleName, final String writeDataSource, final Collection<String> readDataSources, final String loadBalancerName) { - ReadwriteSplittingRuleSegment ruleSegment = new ReadwriteSplittingRuleSegment(ruleName, writeDataSource, readDataSources, new AlgorithmSegment(loadBalancerName, new Properties())); + private AlterReadwriteSplittingRuleStatement createSQLStatement(final String ruleName, final String writeDataSource, final Collection<String> readDataSources, + final String loadBalancerName, final Properties props) { + ReadwriteSplittingRuleSegment ruleSegment = new ReadwriteSplittingRuleSegment(ruleName, writeDataSource, readDataSources, new AlgorithmSegment(loadBalancerName, props)); return new AlterReadwriteSplittingRuleStatement(Collections.singleton(ruleSegment)); } - private AlterReadwriteSplittingRuleStatement createSQLStatementWithDuplicateWriteResourceNames(final String ruleName0, final String ruleName1, final String loadBalancerName) { + private AlterReadwriteSplittingRuleStatement createSQLStatementWithDuplicateWriteDataSources(final String ruleName0, final String ruleName1, final String loadBalancerName) { ReadwriteSplittingRuleSegment ruleSegment0 = new ReadwriteSplittingRuleSegment(ruleName0, "write_ds", Arrays.asList("read_ds_0", "read_ds_1"), new AlgorithmSegment(loadBalancerName, new Properties())); ReadwriteSplittingRuleSegment ruleSegment1 = new ReadwriteSplittingRuleSegment(ruleName1, "write_ds", Arrays.asList("read_ds_2", "read_ds_3"), @@ -156,7 +170,7 @@ class AlterReadwriteSplittingRuleExecutorTest { return new AlterReadwriteSplittingRuleStatement(Arrays.asList(ruleSegment0, ruleSegment1)); } - private AlterReadwriteSplittingRuleStatement createSQLStatementWithDuplicateReadResourceNames(final String ruleName0, final String ruleName1, final String loadBalancerName) { + private AlterReadwriteSplittingRuleStatement createSQLStatementWithDuplicateReadDataSources(final String ruleName0, final String ruleName1, final String loadBalancerName) { ReadwriteSplittingRuleSegment ruleSegment0 = new ReadwriteSplittingRuleSegment(ruleName0, "write_ds_0", Arrays.asList("read_ds_0", "read_ds_1"), new AlgorithmSegment(loadBalancerName, new Properties())); ReadwriteSplittingRuleSegment ruleSegment1 = new ReadwriteSplittingRuleSegment(ruleName1, "write_ds_1", Arrays.asList("read_ds_0", "read_ds_1"), diff --git a/features/readwrite-splitting/distsql/handler/src/test/java/org/apache/shardingsphere/readwritesplitting/distsql/handler/update/CreateReadwriteSplittingRuleExecutorTest.java b/features/readwrite-splitting/distsql/handler/src/test/java/org/apache/shardingsphere/readwritesplitting/distsql/handler/update/CreateReadwriteSplittingRuleExecutorTest.java index f8654c06fe3..f12739e47bd 100644 --- a/features/readwrite-splitting/distsql/handler/src/test/java/org/apache/shardingsphere/readwritesplitting/distsql/handler/update/CreateReadwriteSplittingRuleExecutorTest.java +++ b/features/readwrite-splitting/distsql/handler/src/test/java/org/apache/shardingsphere/readwritesplitting/distsql/handler/update/CreateReadwriteSplittingRuleExecutorTest.java @@ -18,6 +18,7 @@ package org.apache.shardingsphere.readwritesplitting.distsql.handler.update; import org.apache.shardingsphere.distsql.segment.AlgorithmSegment; +import org.apache.shardingsphere.infra.algorithm.core.exception.InvalidAlgorithmConfigurationException; import org.apache.shardingsphere.infra.exception.kernel.metadata.resource.storageunit.MissingRequiredStorageUnitsException; import org.apache.shardingsphere.infra.exception.kernel.metadata.rule.DuplicateRuleException; import org.apache.shardingsphere.infra.exception.kernel.metadata.rule.InvalidRuleConfigurationException; @@ -33,6 +34,8 @@ import org.apache.shardingsphere.readwritesplitting.exception.actual.DuplicateRe import org.apache.shardingsphere.readwritesplitting.rule.ReadwriteSplittingRule; import org.apache.shardingsphere.test.mock.AutoMockExtension; import org.apache.shardingsphere.test.mock.StaticMockSettings; +import org.apache.shardingsphere.test.util.PropertiesBuilder; +import org.apache.shardingsphere.test.util.PropertiesBuilder.Property; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -81,7 +84,7 @@ class CreateReadwriteSplittingRuleExecutorTest { } @Test - void assertCheckSQLStatementWithDuplicateResource() { + void assertCheckSQLStatementWithDuplicateDataSources() { when(resourceMetaData.getStorageUnits()).thenReturn(Collections.singletonMap("write_ds", null)); ReadwriteSplittingRule rule = mock(ReadwriteSplittingRule.class); when(rule.getConfiguration()).thenReturn(createCurrentRuleConfiguration()); @@ -90,13 +93,13 @@ class CreateReadwriteSplittingRuleExecutorTest { } @Test - void assertCheckSQLStatementWithoutExistedResources() { + void assertCheckSQLStatementWithNotExistedDataSources() { when(resourceMetaData.getNotExistedDataSources(any())).thenReturn(Arrays.asList("read_ds_0", "read_ds_1")); assertThrows(MissingRequiredStorageUnitsException.class, () -> executor.checkBeforeUpdate(createSQLStatement("TEST"))); } @Test - void assertCheckSQLStatementWithDuplicateLogicResource() { + void assertCheckSQLStatementWithDuplicateLogicDataSource() { DataSourceMapperRuleAttribute ruleAttribute = mock(DataSourceMapperRuleAttribute.class); when(ruleAttribute.getDataSourceMapper()).thenReturn(Collections.singletonMap("duplicate_ds", Collections.singleton("ds_0"))); when(database.getRuleMetaData().getAttributes(DataSourceMapperRuleAttribute.class)).thenReturn(Collections.singleton(ruleAttribute)); @@ -107,33 +110,40 @@ class CreateReadwriteSplittingRuleExecutorTest { } @Test - void assertCheckSQLStatementWithDuplicateWriteResourceNamesInStatement() { + void assertCheckSQLStatementWithDuplicateWriteDataSourcesInStatement() { assertThrows(DuplicateReadwriteSplittingActualDataSourceException.class, - () -> executor.checkBeforeUpdate(createSQLStatementWithDuplicateWriteResourceNames("write_ds_0", "write_ds_1", "TEST"))); + () -> executor.checkBeforeUpdate(createSQLStatementWithDuplicateWriteDataSources("write_ds_0", "write_ds_1", "TEST"))); } @Test - void assertCheckSQLStatementWithDuplicateWriteResourceNames() { + void assertCheckSQLStatementWithDuplicateWriteDataSources() { ReadwriteSplittingRule rule = mock(ReadwriteSplittingRule.class); when(rule.getConfiguration()).thenReturn(createCurrentRuleConfiguration()); executor.setRule(rule); assertThrows(DuplicateReadwriteSplittingActualDataSourceException.class, - () -> executor.checkBeforeUpdate(createSQLStatement("readwrite_ds_1", "ds_write", Arrays.asList("read_ds_0", "read_ds_1"), "TEST"))); + () -> executor.checkBeforeUpdate(createSQLStatement("readwrite_ds_1", "ds_write", Arrays.asList("read_ds_0", "read_ds_1"), "TEST", new Properties()))); } @Test - void assertCheckSQLStatementWithDuplicateReadResourceNamesInStatement() { + void assertCheckSQLStatementWithDuplicateReadDataSourcesInStatement() { assertThrows(DuplicateReadwriteSplittingActualDataSourceException.class, - () -> executor.checkBeforeUpdate(createSQLStatementWithDuplicateReadResourceNames("write_ds_0", "write_ds_1", "TEST"))); + () -> executor.checkBeforeUpdate(createSQLStatementWithDuplicateReadDataSources("write_ds_0", "write_ds_1", "TEST"))); } @Test - void assertCheckSQLStatementWithDuplicateReadResourceNames() { + void assertCheckSQLStatementWithDuplicateReadDataSources() { ReadwriteSplittingRule rule = mock(ReadwriteSplittingRule.class); when(rule.getConfiguration()).thenReturn(createCurrentRuleConfiguration()); executor.setRule(rule); assertThrows(DuplicateReadwriteSplittingActualDataSourceException.class, - () -> executor.checkBeforeUpdate(createSQLStatement("readwrite_ds_1", "write_ds_1", Arrays.asList("read_ds_0", "read_ds_1"), "TEST"))); + () -> executor.checkBeforeUpdate(createSQLStatement("readwrite_ds_1", "write_ds_1", Arrays.asList("read_ds_0", "read_ds_1"), "TEST", new Properties()))); + } + + @Test + void assertCheckSQLStatementWithInvalidLoadBalancerProperties() { + assertThrows(InvalidAlgorithmConfigurationException.class, + () -> executor.checkBeforeUpdate(createSQLStatement("readwrite_group", "write_ds", Arrays.asList("read_ds_0", "read_ds_1"), "weight", + PropertiesBuilder.build(new Property("read_ds_0", "5"), new Property("read_ds_2", "5"))))); } @Test @@ -172,15 +182,16 @@ class CreateReadwriteSplittingRuleExecutorTest { new AlgorithmSegment(loadBalancerName, new Properties()))); } - private CreateReadwriteSplittingRuleStatement createSQLStatement(final String ruleName, final String writeDataSource, final Collection<String> readDataSources, final String loadBalancerName) { - return createSQLStatement(false, new ReadwriteSplittingRuleSegment(ruleName, writeDataSource, readDataSources, new AlgorithmSegment(loadBalancerName, new Properties()))); + private CreateReadwriteSplittingRuleStatement createSQLStatement(final String ruleName, final String writeDataSource, final Collection<String> readDataSources, + final String loadBalancerName, final Properties props) { + return createSQLStatement(false, new ReadwriteSplittingRuleSegment(ruleName, writeDataSource, readDataSources, new AlgorithmSegment(loadBalancerName, props))); } private CreateReadwriteSplittingRuleStatement createSQLStatement(final boolean ifNotExists, final ReadwriteSplittingRuleSegment... ruleSegments) { return new CreateReadwriteSplittingRuleStatement(ifNotExists, Arrays.asList(ruleSegments)); } - private CreateReadwriteSplittingRuleStatement createSQLStatementWithDuplicateWriteResourceNames(final String ruleName0, final String ruleName1, final String loadBalancerName) { + private CreateReadwriteSplittingRuleStatement createSQLStatementWithDuplicateWriteDataSources(final String ruleName0, final String ruleName1, final String loadBalancerName) { ReadwriteSplittingRuleSegment ruleSegment0 = new ReadwriteSplittingRuleSegment(ruleName0, "write_ds", Arrays.asList("read_ds_0", "read_ds_1"), new AlgorithmSegment(loadBalancerName, new Properties())); ReadwriteSplittingRuleSegment ruleSegment1 = new ReadwriteSplittingRuleSegment(ruleName1, "write_ds", Arrays.asList("read_ds_2", "read_ds_3"), @@ -188,7 +199,7 @@ class CreateReadwriteSplittingRuleExecutorTest { return createSQLStatement(false, ruleSegment0, ruleSegment1); } - private CreateReadwriteSplittingRuleStatement createSQLStatementWithDuplicateReadResourceNames(final String ruleName0, final String ruleName1, final String loadBalancerName) { + private CreateReadwriteSplittingRuleStatement createSQLStatementWithDuplicateReadDataSources(final String ruleName0, final String ruleName1, final String loadBalancerName) { ReadwriteSplittingRuleSegment ruleSegment0 = new ReadwriteSplittingRuleSegment(ruleName0, "write_ds_0", Arrays.asList("read_ds_0", "read_ds_1"), new AlgorithmSegment(loadBalancerName, new Properties())); ReadwriteSplittingRuleSegment ruleSegment1 = new ReadwriteSplittingRuleSegment(ruleName1, "write_ds_1", Arrays.asList("read_ds_0", "read_ds_1"), diff --git a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/route/strategy/type/standard/StandardShardingStrategy.java b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/route/strategy/type/standard/StandardShardingStrategy.java index d46fb4922cb..d9879570892 100644 --- a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/route/strategy/type/standard/StandardShardingStrategy.java +++ b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/route/strategy/type/standard/StandardShardingStrategy.java @@ -24,7 +24,6 @@ import org.apache.shardingsphere.infra.exception.core.ShardingSpherePrecondition import org.apache.shardingsphere.sharding.api.sharding.standard.PreciseShardingValue; import org.apache.shardingsphere.sharding.api.sharding.standard.RangeShardingValue; import org.apache.shardingsphere.sharding.api.sharding.standard.StandardShardingAlgorithm; -import org.apache.shardingsphere.sharding.exception.algorithm.ShardingRouteAlgorithmException; import org.apache.shardingsphere.sharding.exception.metadata.MissingRequiredShardingConfigurationException; import org.apache.shardingsphere.sharding.route.engine.condition.value.ListShardingConditionValue; import org.apache.shardingsphere.sharding.route.engine.condition.value.RangeShardingConditionValue; @@ -76,9 +75,8 @@ public final class StandardShardingStrategy implements ShardingStrategy { new PreciseShardingValue(shardingValue.getTableName(), shardingValue.getColumnName(), dataNodeInfo, each)); if (null != target && availableTargetNames.contains(target)) { result.add(target); - } else if (null != target && !availableTargetNames.contains(target)) { - throw new ShardingRouteAlgorithmException(target, availableTargetNames); } + // TODO add ShardingRouteAlgorithmException check when autoTables support config actualDataNodes in #33364 } return result; } diff --git a/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/route/engine/type/standard/ShardingStandardRoutingEngineTest.java b/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/route/engine/type/standard/ShardingStandardRoutingEngineTest.java index fc166d3f75e..14138504656 100644 --- a/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/route/engine/type/standard/ShardingStandardRoutingEngineTest.java +++ b/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/route/engine/type/standard/ShardingStandardRoutingEngineTest.java @@ -29,6 +29,7 @@ import org.apache.shardingsphere.sharding.route.engine.condition.ShardingConditi import org.apache.shardingsphere.sharding.route.engine.fixture.ShardingRoutingEngineFixtureBuilder; import org.apache.shardingsphere.sharding.rule.ShardingRule; import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import java.util.ArrayList; @@ -89,6 +90,8 @@ class ShardingStandardRoutingEngineTest { assertThat(routeUnits.get(0).getTableMappers().iterator().next().getLogicName(), is("t_order")); } + // TODO remove @Disabled when autoTables support config actualDataNodes in #33364 + @Disabled @Test void assertRouteByErrorShardingTableStrategy() { ShardingStandardRoutingEngine standardRoutingEngine = createShardingStandardRoutingEngine("t_order", ShardingRoutingEngineFixtureBuilder.createErrorShardingConditions("t_order"), diff --git a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/SQLBindEngine.java b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/SQLBindEngine.java index 4dde1b07274..df2059e29ef 100644 --- a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/SQLBindEngine.java +++ b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/SQLBindEngine.java @@ -22,6 +22,7 @@ import org.apache.shardingsphere.infra.binder.context.statement.SQLStatementCont import org.apache.shardingsphere.infra.binder.context.statement.SQLStatementContextFactory; import org.apache.shardingsphere.infra.binder.engine.type.DDLStatementBindEngine; import org.apache.shardingsphere.infra.binder.engine.type.DMLStatementBindEngine; +import org.apache.shardingsphere.infra.hint.HintManager; import org.apache.shardingsphere.infra.hint.HintValueContext; import org.apache.shardingsphere.infra.metadata.ShardingSphereMetaData; import org.apache.shardingsphere.sql.parser.statement.core.statement.SQLStatement; @@ -55,7 +56,7 @@ public final class SQLBindEngine { } private boolean isNeedBind() { - return !hintValueContext.findHintDataSourceName().isPresent(); + return !hintValueContext.findHintDataSourceName().isPresent() && !HintManager.getDataSourceName().isPresent(); } private SQLStatement bindSQLStatement(final SQLStatement statement) { diff --git a/jdbc/src/test/java/org/apache/shardingsphere/driver/ShardingSphereDriverTest.java b/jdbc/src/test/java/org/apache/shardingsphere/driver/ShardingSphereDriverTest.java index a4b032bf6c0..199553d049e 100644 --- a/jdbc/src/test/java/org/apache/shardingsphere/driver/ShardingSphereDriverTest.java +++ b/jdbc/src/test/java/org/apache/shardingsphere/driver/ShardingSphereDriverTest.java @@ -18,6 +18,7 @@ package org.apache.shardingsphere.driver; import org.apache.shardingsphere.driver.jdbc.core.connection.ShardingSphereConnection; +import org.apache.shardingsphere.infra.hint.HintManager; import org.junit.jupiter.api.Test; import java.sql.Connection; @@ -91,4 +92,27 @@ class ShardingSphereDriverTest { } } } + + @Test + void assertDatabaseNameTransparentWithHintManager() throws SQLException { + try ( + Connection connection = DriverManager.getConnection("jdbc:shardingsphere:classpath:config/driver/foo-driver-fixture.yaml"); + Statement statement = connection.createStatement()) { + assertThat(connection, instanceOf(ShardingSphereConnection.class)); + statement.execute("DROP TABLE IF EXISTS t_order"); + statement.execute("CREATE TABLE t_order (order_id INT PRIMARY KEY, user_id INT)"); + statement.execute("INSERT INTO t_order (order_id, user_id) VALUES (1, 101), (2, 102)"); + try (HintManager hintManager = HintManager.getInstance()) { + executeQueryWithHintManager(hintManager, statement); + } + } + } + + private void executeQueryWithHintManager(final HintManager hintManager, final Statement statement) throws SQLException { + hintManager.setDataSourceName("ds_0"); + try (ResultSet resultSet = statement.executeQuery("SELECT COUNT(1) FROM t_order_0")) { + assertTrue(resultSet.next()); + assertThat(resultSet.getInt(1), is(1)); + } + } } diff --git a/parser/sql/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/mysql/visitor/statement/type/MySQLDALStatementVisitor.java b/parser/sql/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/mysql/visitor/statement/type/MySQLDALStatementVisitor.java index 71f24332f42..99ce94601c2 100644 --- a/parser/sql/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/mysql/visitor/statement/type/MySQLDALStatementVisitor.java +++ b/parser/sql/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/mysql/visitor/statement/type/MySQLDALStatementVisitor.java @@ -479,6 +479,12 @@ public final class MySQLDALStatementVisitor extends MySQLStatementVisitor implem } else { result.setProcessId(ctx.IDENTIFIER_().getText()); } + if (null != ctx.QUERY()) { + result.setScope(ctx.QUERY().getText()); + } + if (null != ctx.CONNECTION()) { + result.setScope(ctx.CONNECTION().getText()); + } return result; } diff --git a/parser/sql/statement/core/src/main/java/org/apache/shardingsphere/sql/parser/statement/core/statement/dal/KillStatement.java b/parser/sql/statement/core/src/main/java/org/apache/shardingsphere/sql/parser/statement/core/statement/dal/KillStatement.java index 16134a95050..b7b81c232e2 100644 --- a/parser/sql/statement/core/src/main/java/org/apache/shardingsphere/sql/parser/statement/core/statement/dal/KillStatement.java +++ b/parser/sql/statement/core/src/main/java/org/apache/shardingsphere/sql/parser/statement/core/statement/dal/KillStatement.java @@ -29,4 +29,6 @@ import org.apache.shardingsphere.sql.parser.statement.core.statement.AbstractSQL public abstract class KillStatement extends AbstractSQLStatement implements DALStatement { private String processId; + + private String scope; } diff --git a/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/util/YamlDatabaseConfigurationImportExecutor.java b/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/util/YamlDatabaseConfigurationImportExecutor.java index 7c8df9943f5..63e257e4818 100644 --- a/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/util/YamlDatabaseConfigurationImportExecutor.java +++ b/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/util/YamlDatabaseConfigurationImportExecutor.java @@ -44,6 +44,7 @@ import org.apache.shardingsphere.infra.rule.builder.database.DatabaseRuleBuilder import org.apache.shardingsphere.infra.spi.type.ordered.OrderedSPILoader; import org.apache.shardingsphere.infra.yaml.config.pojo.rule.YamlRuleConfiguration; import org.apache.shardingsphere.infra.yaml.config.swapper.rule.YamlRuleConfigurationSwapper; +import org.apache.shardingsphere.metadata.persist.node.DatabaseMetaDataNode; import org.apache.shardingsphere.mode.manager.ContextManager; import org.apache.shardingsphere.mode.metadata.MetaDataContexts; import org.apache.shardingsphere.proxy.backend.config.yaml.YamlProxyDataSourceConfiguration; @@ -60,6 +61,7 @@ import java.util.LinkedList; import java.util.Map; import java.util.Map.Entry; import java.util.TreeMap; +import java.util.concurrent.TimeUnit; /** * Yaml database configuration import executor. @@ -85,11 +87,24 @@ public final class YamlDatabaseConfigurationImportExecutor { importDataSources(databaseName, yamlConfig.getDataSources()); importRules(databaseName, yamlConfig.getRules()); } catch (final ShardingSphereSQLException ex) { - dropDatabase(databaseName); + // SPEX CHANGED: BEGIN + dropDatabaseUntilSuccessful(databaseName); + // SPEX CHANGED: END throw ex; } } + @SphereEx + private void dropDatabaseUntilSuccessful(final String databaseName) { + do { + try { + dropDatabase(databaseName); + TimeUnit.MILLISECONDS.sleep(200); + } catch (final SQLException | InterruptedException ignored) { + } + } while (ProxyContext.getInstance().getContextManager().getPersistServiceFacade().getRepository().isExisted(DatabaseMetaDataNode.getDatabaseNamePath(databaseName))); + } + private void checkDataSources(final String databaseName, final Map<String, YamlProxyDataSourceConfiguration> dataSources) { ShardingSpherePreconditions.checkNotEmpty(dataSources, () -> new EmptyStorageUnitException(databaseName)); } diff --git a/proxy/backend/type/mysql/src/main/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/executor/KillProcessExecutor.java b/proxy/backend/type/mysql/src/main/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/executor/KillProcessExecutor.java index fdc2280f438..8fe70daa26c 100644 --- a/proxy/backend/type/mysql/src/main/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/executor/KillProcessExecutor.java +++ b/proxy/backend/type/mysql/src/main/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/executor/KillProcessExecutor.java @@ -18,6 +18,8 @@ package org.apache.shardingsphere.proxy.backend.mysql.handler.admin.executor; import lombok.RequiredArgsConstructor; +import org.apache.shardingsphere.infra.exception.core.ShardingSpherePreconditions; +import org.apache.shardingsphere.infra.exception.generic.UnsupportedSQLOperationException; import org.apache.shardingsphere.proxy.backend.context.ProxyContext; import org.apache.shardingsphere.proxy.backend.handler.admin.executor.DatabaseAdminExecutor; import org.apache.shardingsphere.proxy.backend.session.ConnectionSession; @@ -31,6 +33,8 @@ import java.sql.SQLException; @RequiredArgsConstructor public final class KillProcessExecutor implements DatabaseAdminExecutor { + private static final String QUERY_SCOPE = "QUERY"; + private final KillStatement killStatement; /** @@ -40,6 +44,8 @@ public final class KillProcessExecutor implements DatabaseAdminExecutor { */ @Override public void execute(final ConnectionSession connectionSession) throws SQLException { + ShardingSpherePreconditions.checkState(QUERY_SCOPE.equalsIgnoreCase(killStatement.getScope()), + () -> new UnsupportedSQLOperationException("Only `KILL QUERY <processId>` SQL syntax is supported")); String processId = killStatement.getProcessId(); ProxyContext.getInstance().getContextManager().getPersistServiceFacade().getProcessPersistService().killProcess(processId); } diff --git a/proxy/backend/type/mysql/src/main/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/executor/information/SelectInformationSchemataExecutor.java b/proxy/backend/type/mysql/src/main/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/executor/information/SelectInformationSchemataExecutor.java index 0f463b38210..972c9ab8fe7 100644 --- a/proxy/backend/type/mysql/src/main/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/executor/information/SelectInformationSchemataExecutor.java +++ b/proxy/backend/type/mysql/src/main/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/executor/information/SelectInformationSchemataExecutor.java @@ -142,7 +142,7 @@ public final class SelectInformationSchemataExecutor extends DefaultDatabaseMeta protected void preProcess(final String databaseName, final Map<String, Object> rows, final Map<String, String> alias) throws SQLException { ResourceMetaData resourceMetaData = ProxyContext.getInstance().getContextManager().getMetaDataContexts().getMetaData().getDatabase(databaseName).getResourceMetaData(); Collection<String> catalogs = getCatalogs(resourceMetaData); - schemaNameAlias = alias.getOrDefault(SCHEMA_NAME, ""); + schemaNameAlias = alias.getOrDefault(SCHEMA_NAME, alias.getOrDefault(schemaNameAlias, schemaNameAlias)); String rowValue = rows.getOrDefault(schemaNameAlias, "").toString(); queryDatabase = !rowValue.isEmpty(); if (catalogs.contains(rowValue)) {
