This is an automated email from the ASF dual-hosted git repository.
duanzhengqiang 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 e4325be0117 Check duplicate actual data nodes when create or alter
sharding table rule (#33138)
e4325be0117 is described below
commit e4325be0117a939aa7de1a0f4c4f47ab4c62a438
Author: Raigor <[email protected]>
AuthorDate: Mon Oct 7 16:12:18 2024 +0800
Check duplicate actual data nodes when create or alter sharding table rule
(#33138)
* Check duplicate actual data nodes when create or alter sharding table
rule.
* Fix AlterShardingTableRuleExecutorTest
* Fix checkstyle
* Fix CreateShardingTableRuleExecutorTest
---
.../shardingsphere/sharding/rule/ShardingRule.java | 2 -
.../sharding/rule/checker/ShardingRuleChecker.java | 33 +++++++++++----
.../checker/ShardingTableRuleStatementChecker.java | 16 ++++++++
.../ShardingTableRuleStatementConverter.java | 47 ++++++++++++++++++++++
.../update/AlterShardingTableRuleExecutor.java | 7 +++-
.../update/CreateShardingTableRuleExecutor.java | 22 ++++++----
.../update/AlterShardingTableRuleExecutorTest.java | 45 ++++++++++++++++-----
.../CreateShardingTableRuleExecutorTest.java | 27 +++++++++++--
8 files changed, 168 insertions(+), 31 deletions(-)
diff --git
a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/rule/ShardingRule.java
b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/rule/ShardingRule.java
index 393caab4964..d6c0938ef5a 100644
---
a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/rule/ShardingRule.java
+++
b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/rule/ShardingRule.java
@@ -84,8 +84,6 @@ import java.util.stream.Collectors;
@Getter
public final class ShardingRule implements DatabaseRule {
- private static final String ALGORITHM_EXPRESSION_KEY =
"algorithm-expression";
-
private final ShardingRuleConfiguration configuration;
private final Collection<String> dataSourceNames;
diff --git
a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/rule/checker/ShardingRuleChecker.java
b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/rule/checker/ShardingRuleChecker.java
index 41e55f1613a..4713cd900a6 100644
---
a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/rule/checker/ShardingRuleChecker.java
+++
b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/rule/checker/ShardingRuleChecker.java
@@ -44,7 +44,6 @@ import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Optional;
-import java.util.Set;
import java.util.stream.Collectors;
@RequiredArgsConstructor
@@ -64,13 +63,14 @@ public class ShardingRuleChecker {
}
private void checkUniqueActualDataNodesInTableRules() {
- Set<DataNode> uniqueActualDataNodes = new
HashSet<>(shardingRule.getShardingTables().size(), 1F);
- shardingRule.getShardingTables().forEach((key, value) -> {
- DataNode sampleActualDataNode =
value.getActualDataNodes().iterator().next();
-
ShardingSpherePreconditions.checkNotContains(uniqueActualDataNodes,
sampleActualDataNode,
- () -> new DuplicateShardingActualDataNodeException(key,
sampleActualDataNode.getDataSourceName(), sampleActualDataNode.getTableName()));
- uniqueActualDataNodes.add(sampleActualDataNode);
- });
+ Collection<DataNode> uniqueActualDataNodes = new
HashSet<>(shardingRule.getShardingTables().size(), 1F);
+ shardingRule.getShardingTables().forEach((key, value) ->
checkUniqueActualDataNodes(uniqueActualDataNodes, key,
value.getActualDataNodes().iterator().next()));
+ }
+
+ private void checkUniqueActualDataNodes(final Collection<DataNode>
uniqueActualDataNodes, final String logicTable, final DataNode
sampleActualDataNode) {
+ ShardingSpherePreconditions.checkNotContains(uniqueActualDataNodes,
sampleActualDataNode,
+ () -> new DuplicateShardingActualDataNodeException(logicTable,
sampleActualDataNode.getDataSourceName(), sampleActualDataNode.getTableName()));
+ uniqueActualDataNodes.add(sampleActualDataNode);
}
private void checkBindingTableConfiguration(final
ShardingRuleConfiguration ruleConfig) {
@@ -178,4 +178,21 @@ public class ShardingRuleChecker {
shardingStrategy.getShardingAlgorithmName(),
shardingTable.getLogicTable()));
}
}
+
+ /**
+ * Check to be added data nodes.
+ *
+ * @param toBeAddedDataNodes to be added data nodes
+ * @param isAlteration is alteration
+ */
+ public void checkToBeAddedDataNodes(final Map<String,
Collection<DataNode>> toBeAddedDataNodes, final boolean isAlteration) {
+ Collection<DataNode> uniqueActualDataNodes = new
HashSet<>(shardingRule.getShardingTables().size() + toBeAddedDataNodes.size(),
1F);
+ shardingRule.getShardingTables().forEach((key, value) -> {
+ if (isAlteration && toBeAddedDataNodes.containsKey(key)) {
+ return;
+ }
+ checkUniqueActualDataNodes(uniqueActualDataNodes, key,
value.getActualDataNodes().iterator().next());
+ });
+ toBeAddedDataNodes.forEach((key, value) ->
checkUniqueActualDataNodes(uniqueActualDataNodes, key,
value.iterator().next()));
+ }
}
diff --git
a/features/sharding/distsql/handler/src/main/java/org/apache/shardingsphere/sharding/distsql/handler/checker/ShardingTableRuleStatementChecker.java
b/features/sharding/distsql/handler/src/main/java/org/apache/shardingsphere/sharding/distsql/handler/checker/ShardingTableRuleStatementChecker.java
index bf51ee86f33..eb5c7407e4e 100644
---
a/features/sharding/distsql/handler/src/main/java/org/apache/shardingsphere/sharding/distsql/handler/checker/ShardingTableRuleStatementChecker.java
+++
b/features/sharding/distsql/handler/src/main/java/org/apache/shardingsphere/sharding/distsql/handler/checker/ShardingTableRuleStatementChecker.java
@@ -55,6 +55,7 @@ import
org.apache.shardingsphere.sharding.distsql.segment.table.AbstractTableRul
import
org.apache.shardingsphere.sharding.distsql.segment.table.AutoTableRuleSegment;
import
org.apache.shardingsphere.sharding.distsql.segment.table.TableRuleSegment;
import
org.apache.shardingsphere.sharding.exception.algorithm.ShardingAlgorithmClassImplementationException;
+import
org.apache.shardingsphere.sharding.exception.metadata.DuplicateShardingActualDataNodeException;
import
org.apache.shardingsphere.sharding.exception.metadata.ShardingTableRuleNotFoundException;
import
org.apache.shardingsphere.sharding.exception.strategy.InvalidShardingStrategyConfigurationException;
import
org.apache.shardingsphere.sharding.rule.BindingTableCheckedConfiguration;
@@ -525,4 +526,19 @@ public final class ShardingTableRuleStatementChecker {
result.addAll(toBeAlteredRuleConfig.getAutoTables().stream().map(ShardingAutoTableRuleConfiguration::getLogicTable).collect(Collectors.toList()));
return result;
}
+
+ /**
+ * Check to be added data nodes.
+ *
+ * @param toBeAddedDataNodes to be added data nodes
+ */
+ public static void checkToBeAddedDataNodes(final Map<String,
Collection<DataNode>> toBeAddedDataNodes) {
+ Collection<DataNode> uniqueActualDataNodes = new
HashSet<>(toBeAddedDataNodes.size(), 1F);
+ toBeAddedDataNodes.forEach((key, value) -> {
+ DataNode sampleActualDataNode = value.iterator().next();
+
ShardingSpherePreconditions.checkNotContains(uniqueActualDataNodes,
sampleActualDataNode,
+ () -> new DuplicateShardingActualDataNodeException(key,
sampleActualDataNode.getDataSourceName(), sampleActualDataNode.getTableName()));
+ uniqueActualDataNodes.add(sampleActualDataNode);
+ });
+ }
}
diff --git
a/features/sharding/distsql/handler/src/main/java/org/apache/shardingsphere/sharding/distsql/handler/converter/ShardingTableRuleStatementConverter.java
b/features/sharding/distsql/handler/src/main/java/org/apache/shardingsphere/sharding/distsql/handler/converter/ShardingTableRuleStatementConverter.java
index 89822c253a6..3a5502076a3 100644
---
a/features/sharding/distsql/handler/src/main/java/org/apache/shardingsphere/sharding/distsql/handler/converter/ShardingTableRuleStatementConverter.java
+++
b/features/sharding/distsql/handler/src/main/java/org/apache/shardingsphere/sharding/distsql/handler/converter/ShardingTableRuleStatementConverter.java
@@ -21,6 +21,12 @@ import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import org.apache.shardingsphere.distsql.segment.AlgorithmSegment;
import
org.apache.shardingsphere.infra.algorithm.core.config.AlgorithmConfiguration;
+import
org.apache.shardingsphere.infra.algorithm.core.exception.AlgorithmInitializationException;
+import org.apache.shardingsphere.infra.datanode.DataNode;
+import org.apache.shardingsphere.infra.datanode.DataNodeUtils;
+import
org.apache.shardingsphere.infra.exception.core.ShardingSpherePreconditions;
+import org.apache.shardingsphere.infra.expr.core.InlineExpressionParserFactory;
+import org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader;
import org.apache.shardingsphere.sharding.api.config.ShardingRuleConfiguration;
import
org.apache.shardingsphere.sharding.api.config.rule.ShardingAutoTableRuleConfiguration;
import
org.apache.shardingsphere.sharding.api.config.rule.ShardingTableRuleConfiguration;
@@ -28,6 +34,7 @@ import
org.apache.shardingsphere.sharding.api.config.strategy.audit.ShardingAudi
import
org.apache.shardingsphere.sharding.api.config.strategy.keygen.KeyGenerateStrategyConfiguration;
import
org.apache.shardingsphere.sharding.api.config.strategy.sharding.NoneShardingStrategyConfiguration;
import
org.apache.shardingsphere.sharding.api.config.strategy.sharding.ShardingStrategyConfiguration;
+import
org.apache.shardingsphere.sharding.api.sharding.ShardingAutoTableAlgorithm;
import
org.apache.shardingsphere.sharding.distsql.handler.enums.ShardingStrategyLevelType;
import
org.apache.shardingsphere.sharding.distsql.handler.enums.ShardingStrategyType;
import
org.apache.shardingsphere.sharding.distsql.segment.strategy.AuditStrategySegment;
@@ -37,9 +44,12 @@ import
org.apache.shardingsphere.sharding.distsql.segment.strategy.ShardingStrat
import
org.apache.shardingsphere.sharding.distsql.segment.table.AbstractTableRuleSegment;
import
org.apache.shardingsphere.sharding.distsql.segment.table.AutoTableRuleSegment;
import
org.apache.shardingsphere.sharding.distsql.segment.table.TableRuleSegment;
+import org.apache.shardingsphere.sharding.spi.ShardingAlgorithm;
import java.util.Collection;
import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
@@ -195,4 +205,41 @@ public final class ShardingTableRuleStatementConverter {
private static String getKeyGeneratorName(final String tableName, final
String algorithmType) {
return String.format("%s_%s", tableName, algorithmType).toLowerCase();
}
+
+ /**
+ * Convert rule segments to data nodes.
+ *
+ * @param segments sharding table rule segments
+ * @return data nodes map
+ */
+ public static Map<String, Collection<DataNode>> convertDataNodes(final
Collection<AbstractTableRuleSegment> segments) {
+ Map<String, Collection<DataNode>> result = new
HashMap<>(segments.size(), 1F);
+ for (AbstractTableRuleSegment each : segments) {
+ if (each instanceof TableRuleSegment) {
+ result.put(each.getLogicTable(),
getActualDataNodes((TableRuleSegment) each));
+ continue;
+ }
+ result.put(each.getLogicTable(),
getActualDataNodes((AutoTableRuleSegment) each));
+ }
+ return result;
+ }
+
+ private static Collection<DataNode> getActualDataNodes(final
TableRuleSegment ruleSegment) {
+ Collection<DataNode> result = new LinkedList<>();
+ for (String each : ruleSegment.getDataSourceNodes()) {
+ List<String> dataNodes =
InlineExpressionParserFactory.newInstance(each).splitAndEvaluate();
+
result.addAll(dataNodes.stream().map(DataNode::new).collect(Collectors.toList()));
+ }
+ return result;
+ }
+
+ private static Collection<DataNode> getActualDataNodes(final
AutoTableRuleSegment ruleSegment) {
+ ShardingAlgorithm shardingAlgorithm =
+ TypedSPILoader.getService(ShardingAlgorithm.class,
ruleSegment.getShardingAlgorithmSegment().getName(),
ruleSegment.getShardingAlgorithmSegment().getProps());
+ ShardingSpherePreconditions.checkState(shardingAlgorithm instanceof
ShardingAutoTableAlgorithm,
+ () -> new AlgorithmInitializationException(shardingAlgorithm,
"Auto sharding algorithm is required for table '%s'",
ruleSegment.getLogicTable()));
+ List<String> dataNodes =
DataNodeUtils.getFormatDataNodes(((ShardingAutoTableAlgorithm)
shardingAlgorithm).getAutoTablesAmount(),
+ ruleSegment.getLogicTable(), ruleSegment.getDataSourceNodes());
+ return
dataNodes.stream().map(DataNode::new).collect(Collectors.toList());
+ }
}
diff --git
a/features/sharding/distsql/handler/src/main/java/org/apache/shardingsphere/sharding/distsql/handler/update/AlterShardingTableRuleExecutor.java
b/features/sharding/distsql/handler/src/main/java/org/apache/shardingsphere/sharding/distsql/handler/update/AlterShardingTableRuleExecutor.java
index 3263560a1a8..49080b33a00 100644
---
a/features/sharding/distsql/handler/src/main/java/org/apache/shardingsphere/sharding/distsql/handler/update/AlterShardingTableRuleExecutor.java
+++
b/features/sharding/distsql/handler/src/main/java/org/apache/shardingsphere/sharding/distsql/handler/update/AlterShardingTableRuleExecutor.java
@@ -18,8 +18,8 @@
package org.apache.shardingsphere.sharding.distsql.handler.update;
import lombok.Setter;
-import
org.apache.shardingsphere.distsql.handler.required.DistSQLExecutorCurrentRuleRequired;
import
org.apache.shardingsphere.distsql.handler.engine.update.rdl.rule.spi.database.DatabaseRuleAlterExecutor;
+import
org.apache.shardingsphere.distsql.handler.required.DistSQLExecutorCurrentRuleRequired;
import
org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
import org.apache.shardingsphere.sharding.api.config.ShardingRuleConfiguration;
import
org.apache.shardingsphere.sharding.api.config.rule.ShardingAutoTableRuleConfiguration;
@@ -46,6 +46,11 @@ public final class AlterShardingTableRuleExecutor implements
DatabaseRuleAlterEx
@Override
public void checkBeforeUpdate(final AlterShardingTableRuleStatement
sqlStatement) {
ShardingTableRuleStatementChecker.checkAlteration(database,
sqlStatement.getRules(), rule.getConfiguration());
+ checkUniqueActualDataNodes(sqlStatement);
+ }
+
+ private void checkUniqueActualDataNodes(final
AlterShardingTableRuleStatement sqlStatement) {
+
rule.getShardingRuleChecker().checkToBeAddedDataNodes(ShardingTableRuleStatementConverter.convertDataNodes(sqlStatement.getRules()),
true);
}
@Override
diff --git
a/features/sharding/distsql/handler/src/main/java/org/apache/shardingsphere/sharding/distsql/handler/update/CreateShardingTableRuleExecutor.java
b/features/sharding/distsql/handler/src/main/java/org/apache/shardingsphere/sharding/distsql/handler/update/CreateShardingTableRuleExecutor.java
index 7dbcdf6ceb8..d842b3bd78b 100644
---
a/features/sharding/distsql/handler/src/main/java/org/apache/shardingsphere/sharding/distsql/handler/update/CreateShardingTableRuleExecutor.java
+++
b/features/sharding/distsql/handler/src/main/java/org/apache/shardingsphere/sharding/distsql/handler/update/CreateShardingTableRuleExecutor.java
@@ -17,6 +17,7 @@
package org.apache.shardingsphere.sharding.distsql.handler.update;
+import com.cedarsoftware.util.CaseInsensitiveSet;
import lombok.Setter;
import
org.apache.shardingsphere.distsql.handler.engine.update.rdl.rule.spi.database.DatabaseRuleCreateExecutor;
import
org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
@@ -31,7 +32,6 @@ import org.apache.shardingsphere.sharding.rule.ShardingRule;
import java.util.Collection;
import java.util.Collections;
-import java.util.LinkedList;
import java.util.stream.Collectors;
/**
@@ -47,16 +47,24 @@ public final class CreateShardingTableRuleExecutor
implements DatabaseRuleCreate
@Override
public void checkBeforeUpdate(final CreateShardingTableRuleStatement
sqlStatement) {
ShardingTableRuleStatementChecker.checkCreation(database,
sqlStatement.getRules(), sqlStatement.isIfNotExists(), null == rule ? null :
rule.getConfiguration());
+ checkUniqueActualDataNodes(sqlStatement);
}
- @Override
- public ShardingRuleConfiguration buildToBeCreatedRuleConfiguration(final
CreateShardingTableRuleStatement sqlStatement) {
- Collection<AbstractTableRuleSegment> segments =
sqlStatement.getRules();
+ private void checkUniqueActualDataNodes(final
CreateShardingTableRuleStatement sqlStatement) {
+ if (null == rule) {
+
ShardingTableRuleStatementChecker.checkToBeAddedDataNodes(ShardingTableRuleStatementConverter.convertDataNodes(sqlStatement.getRules()));
+ return;
+ }
if (sqlStatement.isIfNotExists()) {
Collection<String> duplicatedRuleNames =
getDuplicatedRuleNames(sqlStatement);
- segments.removeIf(each ->
duplicatedRuleNames.contains(each.getLogicTable()));
+ sqlStatement.getRules().removeIf(each ->
duplicatedRuleNames.contains(each.getLogicTable()));
}
- return ShardingTableRuleStatementConverter.convert(segments);
+
rule.getShardingRuleChecker().checkToBeAddedDataNodes(ShardingTableRuleStatementConverter.convertDataNodes(sqlStatement.getRules()),
false);
+ }
+
+ @Override
+ public ShardingRuleConfiguration buildToBeCreatedRuleConfiguration(final
CreateShardingTableRuleStatement sqlStatement) {
+ return
ShardingTableRuleStatementConverter.convert(sqlStatement.getRules());
}
private Collection<String> getDuplicatedRuleNames(final
CreateShardingTableRuleStatement sqlStatement) {
@@ -65,7 +73,7 @@ public final class CreateShardingTableRuleExecutor implements
DatabaseRuleCreate
}
private Collection<String> getCurrentShardingTables() {
- Collection<String> result = new LinkedList<>();
+ Collection<String> result = new CaseInsensitiveSet<>();
result.addAll(rule.getConfiguration().getTables().stream().map(ShardingTableRuleConfiguration::getLogicTable).collect(Collectors.toSet()));
result.addAll(rule.getConfiguration().getAutoTables().stream().map(ShardingAutoTableRuleConfiguration::getLogicTable).collect(Collectors.toSet()));
return result;
diff --git
a/features/sharding/distsql/handler/src/test/java/org/apache/shardingsphere/sharding/distsql/update/AlterShardingTableRuleExecutorTest.java
b/features/sharding/distsql/handler/src/test/java/org/apache/shardingsphere/sharding/distsql/update/AlterShardingTableRuleExecutorTest.java
index 47714e66b55..44d2bb2800e 100644
---
a/features/sharding/distsql/handler/src/test/java/org/apache/shardingsphere/sharding/distsql/update/AlterShardingTableRuleExecutorTest.java
+++
b/features/sharding/distsql/handler/src/test/java/org/apache/shardingsphere/sharding/distsql/update/AlterShardingTableRuleExecutorTest.java
@@ -17,7 +17,9 @@
package org.apache.shardingsphere.sharding.distsql.update;
+import lombok.SneakyThrows;
import org.apache.shardingsphere.distsql.segment.AlgorithmSegment;
+import org.apache.shardingsphere.distsql.statement.DistSQLStatement;
import
org.apache.shardingsphere.infra.algorithm.core.config.AlgorithmConfiguration;
import
org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
import
org.apache.shardingsphere.infra.metadata.database.resource.ResourceMetaData;
@@ -28,12 +30,18 @@ import
org.apache.shardingsphere.sharding.api.config.rule.ShardingTableRuleConfi
import
org.apache.shardingsphere.sharding.api.config.strategy.keygen.KeyGenerateStrategyConfiguration;
import
org.apache.shardingsphere.sharding.api.config.strategy.sharding.StandardShardingStrategyConfiguration;
import
org.apache.shardingsphere.sharding.distsql.handler.update.AlterShardingTableRuleExecutor;
+import
org.apache.shardingsphere.sharding.distsql.parser.facade.ShardingDistSQLParserFacade;
import
org.apache.shardingsphere.sharding.distsql.segment.strategy.KeyGenerateStrategySegment;
import
org.apache.shardingsphere.sharding.distsql.segment.strategy.ShardingStrategySegment;
import
org.apache.shardingsphere.sharding.distsql.segment.table.AutoTableRuleSegment;
import
org.apache.shardingsphere.sharding.distsql.segment.table.TableRuleSegment;
import
org.apache.shardingsphere.sharding.distsql.statement.AlterShardingTableRuleStatement;
+import
org.apache.shardingsphere.sharding.exception.metadata.DuplicateShardingActualDataNodeException;
import org.apache.shardingsphere.sharding.rule.ShardingRule;
+import org.apache.shardingsphere.sharding.rule.checker.ShardingRuleChecker;
+import org.apache.shardingsphere.sql.parser.api.visitor.SQLVisitor;
+import org.apache.shardingsphere.sql.parser.core.ParseASTNode;
+import org.apache.shardingsphere.sql.parser.core.SQLParserFactory;
import org.apache.shardingsphere.test.fixture.jdbc.MockedDataSource;
import org.apache.shardingsphere.test.util.PropertiesBuilder;
import org.apache.shardingsphere.test.util.PropertiesBuilder.Property;
@@ -50,6 +58,7 @@ import java.util.Properties;
import static org.hamcrest.CoreMatchers.instanceOf;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@@ -69,14 +78,29 @@ class AlterShardingTableRuleExecutorTest {
when(database.getResourceMetaData()).thenReturn(resourceMetaData);
when(database.getRuleMetaData()).thenReturn(new
RuleMetaData(Collections.emptyList()));
executor.setDatabase(database);
+ ShardingRule rule = mock(ShardingRule.class);
+ when(rule.getConfiguration()).thenReturn(currentRuleConfig);
+ ShardingRuleChecker checker = new ShardingRuleChecker(rule);
+ when(rule.getShardingRuleChecker()).thenReturn(checker);
+ executor.setRule(rule);
+ }
+
+ @Test
+ void assertCheckWithDuplicateDataNodes() {
+ String sql = "ALTER SHARDING TABLE RULE t_order("
+ + "DATANODES('ds_${0..1}.t_order'),"
+ +
"DATABASE_STRATEGY(TYPE='standard',SHARDING_COLUMN=user_id,SHARDING_ALGORITHM(TYPE(NAME='inline',PROPERTIES('algorithm-expression'='ds_${user_id
% 2}'))))"
+ + "), t_order_item("
+ + "DATANODES('ds_${0..1}.t_order'),"
+ +
"DATABASE_STRATEGY(TYPE='standard',SHARDING_COLUMN=user_id,SHARDING_ALGORITHM(TYPE(NAME='inline',PROPERTIES('algorithm-expression'='ds_${user_id
% 2}'))))"
+ + ");";
+ AlterShardingTableRuleStatement sqlStatement =
(AlterShardingTableRuleStatement) getDistSQLStatement(sql);
+ assertThrows(DuplicateShardingActualDataNodeException.class, () ->
executor.checkBeforeUpdate(sqlStatement));
}
@Test
void assertUpdate() {
AlterShardingTableRuleStatement sqlStatement = new
AlterShardingTableRuleStatement(Arrays.asList(createCompleteAutoTableRule("t_order_item"),
createCompleteTableRule("t_order")));
- ShardingRule rule = mock(ShardingRule.class);
- when(rule.getConfiguration()).thenReturn(currentRuleConfig);
- executor.setRule(rule);
executor.checkBeforeUpdate(sqlStatement);
ShardingRuleConfiguration toBeAlteredRuleConfig =
executor.buildToBeAlteredRuleConfiguration(sqlStatement);
assertThat(toBeAlteredRuleConfig.getTables().size(), is(1));
@@ -101,9 +125,6 @@ class AlterShardingTableRuleExecutorTest {
@Test
void assertUpdateWithDifferentCase() {
AlterShardingTableRuleStatement sqlStatement = new
AlterShardingTableRuleStatement(Arrays.asList(createCompleteAutoTableRule("T_ORDER_ITEM"),
createCompleteTableRule("T_ORDER")));
- ShardingRule rule = mock(ShardingRule.class);
- when(rule.getConfiguration()).thenReturn(currentRuleConfig);
- executor.setRule(rule);
executor.checkBeforeUpdate(sqlStatement);
ShardingRuleConfiguration toBeAlteredRuleConfig =
executor.buildToBeAlteredRuleConfiguration(sqlStatement);
assertThat(toBeAlteredRuleConfig.getTables().size(), is(1));
@@ -128,9 +149,6 @@ class AlterShardingTableRuleExecutorTest {
@Test
void assertUpdateTableType() {
AlterShardingTableRuleStatement sqlStatement = new
AlterShardingTableRuleStatement(Arrays.asList(createCompleteAutoTableRule("t_order"),
createCompleteTableRule("t_order_item")));
- ShardingRule rule = mock(ShardingRule.class);
- when(rule.getConfiguration()).thenReturn(currentRuleConfig);
- executor.setRule(rule);
executor.checkBeforeUpdate(sqlStatement);
ShardingRuleConfiguration toBeAlteredRuleConfig =
executor.buildToBeAlteredRuleConfiguration(sqlStatement);
assertThat(toBeAlteredRuleConfig.getTables().size(), is(1));
@@ -197,4 +215,13 @@ class AlterShardingTableRuleExecutorTest {
result.put("ds_1", new MockedDataSource());
return result;
}
+
+ @SneakyThrows(ReflectiveOperationException.class)
+ @SuppressWarnings("rawtypes")
+ private DistSQLStatement getDistSQLStatement(final String sql) {
+ ShardingDistSQLParserFacade facade = new ShardingDistSQLParserFacade();
+ ParseASTNode parseASTNode = (ParseASTNode)
SQLParserFactory.newInstance(sql, facade.getLexerClass(),
facade.getParserClass()).parse();
+ SQLVisitor visitor =
facade.getVisitorClass().getDeclaredConstructor().newInstance();
+ return (DistSQLStatement) visitor.visit(parseASTNode.getRootNode());
+ }
}
diff --git
a/features/sharding/distsql/handler/src/test/java/org/apache/shardingsphere/sharding/distsql/update/CreateShardingTableRuleExecutorTest.java
b/features/sharding/distsql/handler/src/test/java/org/apache/shardingsphere/sharding/distsql/update/CreateShardingTableRuleExecutorTest.java
index 4479ae23d63..2bba05b577f 100644
---
a/features/sharding/distsql/handler/src/test/java/org/apache/shardingsphere/sharding/distsql/update/CreateShardingTableRuleExecutorTest.java
+++
b/features/sharding/distsql/handler/src/test/java/org/apache/shardingsphere/sharding/distsql/update/CreateShardingTableRuleExecutorTest.java
@@ -41,8 +41,10 @@ import
org.apache.shardingsphere.sharding.distsql.segment.table.AbstractTableRul
import
org.apache.shardingsphere.sharding.distsql.segment.table.AutoTableRuleSegment;
import
org.apache.shardingsphere.sharding.distsql.segment.table.TableRuleSegment;
import
org.apache.shardingsphere.sharding.distsql.statement.CreateShardingTableRuleStatement;
+import
org.apache.shardingsphere.sharding.exception.metadata.DuplicateShardingActualDataNodeException;
import
org.apache.shardingsphere.sharding.exception.strategy.InvalidShardingStrategyConfigurationException;
import org.apache.shardingsphere.sharding.rule.ShardingRule;
+import org.apache.shardingsphere.sharding.rule.checker.ShardingRuleChecker;
import org.apache.shardingsphere.sql.parser.api.visitor.SQLVisitor;
import org.apache.shardingsphere.sql.parser.core.ParseASTNode;
import org.apache.shardingsphere.sql.parser.core.SQLParserFactory;
@@ -92,10 +94,12 @@ class CreateShardingTableRuleExecutorTest {
@Test
void assertBuildToBeCreatedRuleConfiguration() {
- CreateShardingTableRuleStatement sqlStatement = new
CreateShardingTableRuleStatement(false,
Arrays.asList(createCompleteAutoTableRule(), createCompleteTableRule()));
ShardingRule rule = mock(ShardingRule.class);
when(rule.getConfiguration()).thenReturn(currentRuleConfig);
+ ShardingRuleChecker checker = new ShardingRuleChecker(rule);
+ when(rule.getShardingRuleChecker()).thenReturn(checker);
executor.setRule(rule);
+ CreateShardingTableRuleStatement sqlStatement = new
CreateShardingTableRuleStatement(false,
Arrays.asList(createCompleteAutoTableRule(), createCompleteTableRule()));
executor.checkBeforeUpdate(sqlStatement);
ShardingRuleConfiguration actual =
executor.buildToBeCreatedRuleConfiguration(sqlStatement);
assertThat(actual.getTables().size(), is(1));
@@ -185,15 +189,30 @@ class CreateShardingTableRuleExecutorTest {
assertThrows(InvalidShardingStrategyConfigurationException.class, ()
-> executor.checkBeforeUpdate(distSQLStatement));
}
+ @Test
+ void assertCheckWithDuplicateDataNodes() {
+ String sql = "CREATE SHARDING TABLE RULE t_order("
+ + "DATANODES('ds_${0..1}.t_order'),"
+ +
"DATABASE_STRATEGY(TYPE='standard',SHARDING_COLUMN=user_id,SHARDING_ALGORITHM(TYPE(NAME='inline',PROPERTIES('algorithm-expression'='ds_${user_id
% 2}'))))"
+ + "), t_order_item("
+ + "DATANODES('ds_${0..1}.t_order'),"
+ +
"DATABASE_STRATEGY(TYPE='standard',SHARDING_COLUMN=user_id,SHARDING_ALGORITHM(TYPE(NAME='inline',PROPERTIES('algorithm-expression'='ds_${user_id
% 2}'))))"
+ + ");";
+ CreateShardingTableRuleStatement sqlStatement =
(CreateShardingTableRuleStatement) getDistSQLStatement(sql);
+ assertThrows(DuplicateShardingActualDataNodeException.class, () ->
executor.checkBeforeUpdate(sqlStatement));
+ }
+
@Test
void assertUpdateWithIfNotExistsStatement() {
+ ShardingRule rule = mock(ShardingRule.class);
+ when(rule.getConfiguration()).thenReturn(currentRuleConfig);
+ ShardingRuleChecker checker = new ShardingRuleChecker(rule);
+ when(rule.getShardingRuleChecker()).thenReturn(checker);
+ executor.setRule(rule);
Collection<AbstractTableRuleSegment> segments = new LinkedList<>();
segments.add(createCompleteAutoTableRule());
segments.add(createCompleteTableRule());
CreateShardingTableRuleStatement statementWithIfNotExists = new
CreateShardingTableRuleStatement(true, segments);
- ShardingRule rule = mock(ShardingRule.class);
- when(rule.getConfiguration()).thenReturn(currentRuleConfig);
- executor.setRule(rule);
executor.checkBeforeUpdate(statementWithIfNotExists);
ShardingRuleConfiguration actual =
executor.buildToBeCreatedRuleConfiguration(statementWithIfNotExists);
assertThat(actual.getTables().size(), is(1));