This is an automated email from the ASF dual-hosted git repository.
terrymanu 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 4f69cf38146 Match mask table names case-insensitively in DistSQL
executors (#39361)
4f69cf38146 is described below
commit 4f69cf38146cd4c5a9da259c0afb4a0d4c3a6f2e
Author: Eunbin Son <[email protected]>
AuthorDate: Tue Sep 8 18:52:38 2026 +0900
Match mask table names case-insensitively in DistSQL executors (#39361)
* Match mask table names case-insensitively in DistSQL executors
* Remove original case-variant mask table item on ALTER
buildToBeDroppedRuleConfiguration returned an empty table collection, so
altering an existing t_order as T_ORDER persisted a second item while
MaskTableChangedProcessor replaces tables by exact name. The durable
configuration kept both case variants and a stale algorithm reference.
Return the current table items whose names match case-insensitively but
differ in spelling, so the original item is deleted after the altered one
is persisted. Items with identical spelling stay out of the dropped
configuration to avoid removing the newly persisted item.
Add a regression test that runs the executor output through
MaskTableChangedProcessor and asserts one remaining table with the new
algorithm.
* Reject case-colliding mask table names within one ALTER
The grammar accepts multiple definitions per statement and existence
validation compares case-insensitively, so ALTER MASK RULE t_order,
T_ORDER passed while cleanup excluded both because both exact spellings
occur in the altered set. Persistence then emitted two case variants of
one logical table, and MaskRule keys its tables case-insensitively, so
runtime behavior depended on load order.
Reject targets that collide case-insensitively within one statement
before consulting the current rule.
* Skip existing mask tables case-insensitively on CREATE IF NOT EXISTS
IF NOT EXISTS bypasses duplicate detection and the build method converted
every supplied rule, so creating T_ORDER for an existing t_order added a
second case variant instead of being a no-op.
Filter segments whose table name already exists case-insensitively before
conversion, which also drops the algorithms generated for them.
---
RELEASE-NOTES.md | 1 +
.../handler/update/AlterMaskRuleExecutor.java | 28 +++++++--
.../handler/update/CreateMaskRuleExecutor.java | 25 ++++++--
.../handler/update/AlterMaskRuleExecutorTest.java | 66 +++++++++++++++++++---
.../handler/update/CreateMaskRuleExecutorTest.java | 35 ++++++++++--
5 files changed, 134 insertions(+), 21 deletions(-)
diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md
index d954facd5ec..9d27775493f 100644
--- a/RELEASE-NOTES.md
+++ b/RELEASE-NOTES.md
@@ -42,6 +42,7 @@
1. Metadata: Fix wrong logic table metadata when config same actual table name
in different storage unit -
[#39157](https://github.com/apache/shardingsphere/pull/39157)
1. DistSQL: Fix case-sensitive storage unit matching in `SHOW RULES USED
STORAGE UNIT` - [#38848](https://github.com/apache/shardingsphere/pull/38848)
1. DistSQL: Use case-insensitive table name matching in broadcast create and
drop executors - [#39200](https://github.com/apache/shardingsphere/pull/39200)
+1. DistSQL: Match mask table names case-insensitively in create and alter
executors - [#39361](https://github.com/apache/shardingsphere/pull/39361)
1. JDBC: Fix stale generated values leaking into prepared statement
executeBatch calls without pending batches -
[#38160](https://github.com/apache/shardingsphere/pull/38160)
1. JDBC: Fix MySQL-compatible typed string conversion for
`ResultSet#getObject(index, Class<T>)` -
[#38444](https://github.com/apache/shardingsphere/pull/38444)
1. JDBC: Fix statement close invalidating live result sets of other statements
on the same connection -
[#39503](https://github.com/apache/shardingsphere/pull/39503)
diff --git
a/features/mask/distsql/handler/src/main/java/org/apache/shardingsphere/mask/distsql/handler/update/AlterMaskRuleExecutor.java
b/features/mask/distsql/handler/src/main/java/org/apache/shardingsphere/mask/distsql/handler/update/AlterMaskRuleExecutor.java
index 99f97a4b979..de485c3fb0f 100644
---
a/features/mask/distsql/handler/src/main/java/org/apache/shardingsphere/mask/distsql/handler/update/AlterMaskRuleExecutor.java
+++
b/features/mask/distsql/handler/src/main/java/org/apache/shardingsphere/mask/distsql/handler/update/AlterMaskRuleExecutor.java
@@ -17,11 +17,13 @@
package org.apache.shardingsphere.mask.distsql.handler.update;
+import com.cedarsoftware.util.CaseInsensitiveSet;
import lombok.Setter;
import
org.apache.shardingsphere.distsql.handler.engine.update.rdl.rule.spi.database.type.DatabaseRuleAlterExecutor;
import
org.apache.shardingsphere.distsql.handler.required.DistSQLExecutorCurrentRuleRequired;
import
org.apache.shardingsphere.infra.algorithm.core.config.AlgorithmConfiguration;
import org.apache.shardingsphere.infra.exception.ShardingSpherePreconditions;
+import
org.apache.shardingsphere.infra.exception.kernel.metadata.rule.DuplicateRuleException;
import
org.apache.shardingsphere.infra.exception.kernel.metadata.rule.MissingRequiredRuleException;
import
org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
import org.apache.shardingsphere.mask.config.MaskRuleConfiguration;
@@ -33,8 +35,8 @@ import
org.apache.shardingsphere.mask.distsql.statement.AlterMaskRuleStatement;
import org.apache.shardingsphere.mask.rule.MaskRule;
import java.util.Collection;
-import java.util.Collections;
import java.util.HashMap;
+import java.util.LinkedList;
import java.util.Map;
import java.util.stream.Collectors;
@@ -51,11 +53,23 @@ public final class AlterMaskRuleExecutor implements
DatabaseRuleAlterExecutor<Al
@Override
public void checkBeforeUpdate(final AlterMaskRuleStatement sqlStatement) {
+ checkDuplicatedRuleNames(sqlStatement);
checkToBeAlteredRules(sqlStatement);
}
+ private void checkDuplicatedRuleNames(final AlterMaskRuleStatement
sqlStatement) {
+ Collection<String> uniqueTableNames = new CaseInsensitiveSet<>();
+ Collection<String> duplicatedTableNames = new LinkedList<>();
+ for (String each : getToBeAlteredMaskTableNames(sqlStatement)) {
+ if (!uniqueTableNames.add(each)) {
+ duplicatedTableNames.add(each);
+ }
+ }
+ ShardingSpherePreconditions.checkMustEmpty(duplicatedTableNames, () ->
new DuplicateRuleException("mask", database.getName(), duplicatedTableNames));
+ }
+
private void checkToBeAlteredRules(final AlterMaskRuleStatement
sqlStatement) {
- Collection<String> currentMaskTableNames =
rule.getConfiguration().getTables().stream().map(MaskTableRuleConfiguration::getName).collect(Collectors.toList());
+ Collection<String> currentMaskTableNames =
rule.getConfiguration().getTables().stream().map(MaskTableRuleConfiguration::getName).collect(Collectors.toCollection(CaseInsensitiveSet::new));
Collection<String> notExistedMaskTableNames =
getToBeAlteredMaskTableNames(sqlStatement).stream().filter(each ->
!currentMaskTableNames.contains(each)).collect(Collectors.toList());
ShardingSpherePreconditions.checkMustEmpty(notExistedMaskTableNames,
() -> new MissingRequiredRuleException("Mask", database.getName(),
notExistedMaskTableNames));
}
@@ -71,7 +85,7 @@ public final class AlterMaskRuleExecutor implements
DatabaseRuleAlterExecutor<Al
@Override
public MaskRuleConfiguration buildToBeDroppedRuleConfiguration(final
MaskRuleConfiguration toBeAlteredRuleConfig) {
- Collection<String> toBeAlteredTableNames =
toBeAlteredRuleConfig.getTables().stream().map(MaskTableRuleConfiguration::getName).collect(Collectors.toList());
+ Collection<String> toBeAlteredTableNames =
toBeAlteredRuleConfig.getTables().stream().map(MaskTableRuleConfiguration::getName).collect(Collectors.toCollection(CaseInsensitiveSet::new));
Collection<MaskColumnRuleConfiguration> columns =
rule.getConfiguration().getTables().stream().filter(each ->
!toBeAlteredTableNames.contains(each.getName()))
.flatMap(each ->
each.getColumns().stream()).collect(Collectors.toList());
columns.addAll(toBeAlteredRuleConfig.getTables().stream().flatMap(each
-> each.getColumns().stream()).collect(Collectors.toList()));
@@ -82,7 +96,13 @@ public final class AlterMaskRuleExecutor implements
DatabaseRuleAlterExecutor<Al
toBeDroppedAlgorithms.put(each,
rule.getConfiguration().getMaskAlgorithms().get(each));
}
}
- return new MaskRuleConfiguration(Collections.emptyList(),
toBeDroppedAlgorithms);
+ return new
MaskRuleConfiguration(getToBeDroppedTables(toBeAlteredRuleConfig,
toBeAlteredTableNames), toBeDroppedAlgorithms);
+ }
+
+ private Collection<MaskTableRuleConfiguration> getToBeDroppedTables(final
MaskRuleConfiguration toBeAlteredRuleConfig, final Collection<String>
toBeAlteredTableNames) {
+ Collection<String> toBeAlteredCaseSensitiveTableNames =
toBeAlteredRuleConfig.getTables().stream().map(MaskTableRuleConfiguration::getName).collect(Collectors.toSet());
+ return rule.getConfiguration().getTables().stream()
+ .filter(each -> toBeAlteredTableNames.contains(each.getName())
&&
!toBeAlteredCaseSensitiveTableNames.contains(each.getName())).collect(Collectors.toList());
}
@Override
diff --git
a/features/mask/distsql/handler/src/main/java/org/apache/shardingsphere/mask/distsql/handler/update/CreateMaskRuleExecutor.java
b/features/mask/distsql/handler/src/main/java/org/apache/shardingsphere/mask/distsql/handler/update/CreateMaskRuleExecutor.java
index d63e4f73445..7292b799f3a 100644
---
a/features/mask/distsql/handler/src/main/java/org/apache/shardingsphere/mask/distsql/handler/update/CreateMaskRuleExecutor.java
+++
b/features/mask/distsql/handler/src/main/java/org/apache/shardingsphere/mask/distsql/handler/update/CreateMaskRuleExecutor.java
@@ -17,6 +17,7 @@
package org.apache.shardingsphere.mask.distsql.handler.update;
+import com.cedarsoftware.util.CaseInsensitiveSet;
import lombok.Setter;
import
org.apache.shardingsphere.distsql.handler.engine.update.rdl.rule.spi.database.type.DatabaseRuleCreateExecutor;
import org.apache.shardingsphere.infra.exception.ShardingSpherePreconditions;
@@ -33,6 +34,7 @@ import org.apache.shardingsphere.mask.rule.MaskRule;
import org.apache.shardingsphere.mask.spi.MaskAlgorithm;
import java.util.Collection;
+import java.util.Collections;
import java.util.LinkedList;
import java.util.stream.Collectors;
@@ -58,11 +60,16 @@ public final class CreateMaskRuleExecutor implements
DatabaseRuleCreateExecutor<
}
private void checkDuplicatedRuleNames(final CreateMaskRuleStatement
sqlStatement) {
- if (null != rule) {
- Collection<String> currentRuleNames =
rule.getConfiguration().getTables().stream().map(MaskTableRuleConfiguration::getName).collect(Collectors.toList());
- Collection<String> duplicatedRuleNames =
sqlStatement.getRules().stream().map(MaskRuleSegment::getTableName).filter(currentRuleNames::contains).collect(Collectors.toList());
- ShardingSpherePreconditions.checkMustEmpty(duplicatedRuleNames, ()
-> new DuplicateRuleException("mask", database.getName(), duplicatedRuleNames));
+ Collection<String> duplicatedRuleNames =
getDuplicatedRuleNames(sqlStatement);
+ ShardingSpherePreconditions.checkMustEmpty(duplicatedRuleNames, () ->
new DuplicateRuleException("mask", database.getName(), duplicatedRuleNames));
+ }
+
+ private Collection<String> getDuplicatedRuleNames(final
CreateMaskRuleStatement sqlStatement) {
+ if (null == rule) {
+ return Collections.emptyList();
}
+ Collection<String> currentRuleNames =
rule.getConfiguration().getTables().stream().map(MaskTableRuleConfiguration::getName).collect(Collectors.toCollection(CaseInsensitiveSet::new));
+ return
sqlStatement.getRules().stream().map(MaskRuleSegment::getTableName).filter(currentRuleNames::contains).collect(Collectors.toList());
}
private void checkAlgorithms(final CreateMaskRuleStatement sqlStatement) {
@@ -73,7 +80,15 @@ public final class CreateMaskRuleExecutor implements
DatabaseRuleCreateExecutor<
@Override
public MaskRuleConfiguration buildToBeCreatedRuleConfiguration(final
CreateMaskRuleStatement sqlStatement) {
- return MaskRuleStatementConverter.convert(sqlStatement.getRules());
+ return
MaskRuleStatementConverter.convert(getToBeCreatedRuleSegments(sqlStatement));
+ }
+
+ private Collection<MaskRuleSegment> getToBeCreatedRuleSegments(final
CreateMaskRuleStatement sqlStatement) {
+ if (!ifNotExists) {
+ return sqlStatement.getRules();
+ }
+ Collection<String> duplicatedRuleNames =
getDuplicatedRuleNames(sqlStatement);
+ return sqlStatement.getRules().stream().filter(each ->
!duplicatedRuleNames.contains(each.getTableName())).collect(Collectors.toList());
}
@Override
diff --git
a/features/mask/distsql/handler/src/test/java/org/apache/shardingsphere/mask/distsql/handler/update/AlterMaskRuleExecutorTest.java
b/features/mask/distsql/handler/src/test/java/org/apache/shardingsphere/mask/distsql/handler/update/AlterMaskRuleExecutorTest.java
index 597b2a589a8..e5a96add029 100644
---
a/features/mask/distsql/handler/src/test/java/org/apache/shardingsphere/mask/distsql/handler/update/AlterMaskRuleExecutorTest.java
+++
b/features/mask/distsql/handler/src/test/java/org/apache/shardingsphere/mask/distsql/handler/update/AlterMaskRuleExecutorTest.java
@@ -20,6 +20,7 @@ package org.apache.shardingsphere.mask.distsql.handler.update;
import
org.apache.shardingsphere.distsql.handler.engine.update.rdl.rule.spi.database.DatabaseRuleDefinitionExecutor;
import org.apache.shardingsphere.distsql.segment.AlgorithmSegment;
import
org.apache.shardingsphere.infra.algorithm.core.config.AlgorithmConfiguration;
+import
org.apache.shardingsphere.infra.exception.kernel.metadata.rule.DuplicateRuleException;
import
org.apache.shardingsphere.infra.exception.kernel.metadata.rule.MissingRequiredRuleException;
import
org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
import org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader;
@@ -30,6 +31,8 @@ import
org.apache.shardingsphere.mask.distsql.segment.MaskColumnSegment;
import org.apache.shardingsphere.mask.distsql.segment.MaskRuleSegment;
import org.apache.shardingsphere.mask.distsql.statement.AlterMaskRuleStatement;
import org.apache.shardingsphere.mask.rule.MaskRule;
+import org.apache.shardingsphere.mode.spi.rule.RuleChangedItemType;
+import
org.apache.shardingsphere.mode.spi.rule.RuleItemConfigurationChangedProcessor;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
@@ -43,6 +46,7 @@ import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashMap;
+import java.util.LinkedList;
import java.util.Map;
import java.util.Properties;
import java.util.stream.Collectors;
@@ -81,6 +85,15 @@ class AlterMaskRuleExecutorTest {
assertThrows(expectedException, () ->
executor.checkBeforeUpdate(sqlStatement));
}
+ @Test
+ void assertCheckBeforeUpdateWithCaseCollidingTablesInOneStatement() {
+ executor.setRule(mock(MaskRule.class));
+ when(database.getName()).thenReturn("foo_db");
+ AlterMaskRuleStatement sqlStatement = new AlterMaskRuleStatement(
+ Arrays.asList(createRuleSegment("t_order", "order_id", "MD5"),
createRuleSegment("T_ORDER", "user_id", "MD5")));
+ assertThrows(DuplicateRuleException.class, () ->
executor.checkBeforeUpdate(sqlStatement));
+ }
+
@Test
void assertBuildToBeAlteredRuleConfiguration() {
AlterMaskRuleStatement sqlStatement = new
AlterMaskRuleStatement(Collections.singleton(createRuleSegment("t_order",
"order_id", "MD5")));
@@ -95,13 +108,7 @@ class AlterMaskRuleExecutorTest {
@Test
void assertBuildToBeDroppedRuleConfiguration() {
- Map<String, AlgorithmConfiguration> currentAlgorithms = new
LinkedHashMap<>(3, 1F);
- currentAlgorithms.put("order_mask", new AlgorithmConfiguration("MD5",
new Properties()));
- currentAlgorithms.put("user_mask", new AlgorithmConfiguration("MD5",
new Properties()));
- currentAlgorithms.put("unused_mask", new AlgorithmConfiguration("SM3",
new Properties()));
- executor.setRule(createRule(new MaskRuleConfiguration(Arrays.asList(
- new MaskTableRuleConfiguration("t_order",
Collections.singleton(new MaskColumnRuleConfiguration("order_id",
"order_mask"))),
- new MaskTableRuleConfiguration("t_user",
Collections.singleton(new MaskColumnRuleConfiguration("user_id",
"user_mask")))), currentAlgorithms)));
+
executor.setRule(createRule(createCurrentRuleConfigurationWithAlgorithms()));
MaskTableRuleConfiguration toBeAlteredTable = new
MaskTableRuleConfiguration("t_order", Collections.singleton(new
MaskColumnRuleConfiguration("order_id", "order_mask")));
MaskRuleConfiguration actual =
executor.buildToBeDroppedRuleConfiguration(new
MaskRuleConfiguration(Collections.singleton(toBeAlteredTable),
Collections.emptyMap()));
assertTrue(actual.getTables().isEmpty());
@@ -109,6 +116,37 @@ class AlterMaskRuleExecutorTest {
assertTrue(actual.getMaskAlgorithms().containsKey("unused_mask"));
}
+ @Test
+ void assertBuildToBeDroppedRuleConfigurationWithDifferentTableNameCase() {
+
executor.setRule(createRule(createCurrentRuleConfigurationWithAlgorithms()));
+ MaskTableRuleConfiguration toBeAlteredTable = new
MaskTableRuleConfiguration("T_ORDER", Collections.singleton(new
MaskColumnRuleConfiguration("order_id", "t_order_order_id_sm3")));
+ MaskRuleConfiguration actual =
executor.buildToBeDroppedRuleConfiguration(new
MaskRuleConfiguration(Collections.singleton(toBeAlteredTable),
Collections.emptyMap()));
+ assertThat(actual.getTables().size(), is(1));
+ assertThat(actual.getTables().iterator().next().getName(),
is("t_order"));
+ assertThat(actual.getMaskAlgorithms().size(), is(2));
+ assertTrue(actual.getMaskAlgorithms().containsKey("order_mask"));
+ assertTrue(actual.getMaskAlgorithms().containsKey("unused_mask"));
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test
+ void assertUpdatePathWithDifferentTableNameCase() {
+ MaskRuleConfiguration currentRuleConfig =
createCurrentRuleConfigurationWithAlgorithms();
+ executor.setRule(createRule(currentRuleConfig));
+ MaskTableRuleConfiguration toBeAlteredTable = new
MaskTableRuleConfiguration("T_ORDER", Collections.singleton(new
MaskColumnRuleConfiguration("order_id", "t_order_order_id_sm3")));
+ MaskRuleConfiguration toBeDroppedRuleConfig =
executor.buildToBeDroppedRuleConfiguration(new
MaskRuleConfiguration(Collections.singleton(toBeAlteredTable),
Collections.emptyMap()));
+ RuleItemConfigurationChangedProcessor<MaskRuleConfiguration,
MaskTableRuleConfiguration> processor = TypedSPILoader.getService(
+ RuleItemConfigurationChangedProcessor.class, new
RuleChangedItemType("mask", "tables"));
+ processor.changeRuleItemConfiguration("T_ORDER", currentRuleConfig,
toBeAlteredTable);
+ for (MaskTableRuleConfiguration each :
toBeDroppedRuleConfig.getTables()) {
+ processor.dropRuleItemConfiguration(each.getName(),
currentRuleConfig);
+ }
+ Collection<MaskTableRuleConfiguration> actual =
currentRuleConfig.getTables().stream().filter(each ->
"t_order".equalsIgnoreCase(each.getName())).collect(Collectors.toList());
+ assertThat(actual.size(), is(1));
+ assertThat(actual.iterator().next().getName(), is("T_ORDER"));
+
assertThat(actual.iterator().next().getColumns().iterator().next().getMaskAlgorithm(),
is("t_order_order_id_sm3"));
+ }
+
@Test
void assertGetRuleClass() {
assertThat(executor.getRuleClass(), is(MaskRule.class));
@@ -122,7 +160,9 @@ class AlterMaskRuleExecutorTest {
createCurrentRuleConfiguration(Collections.singleton("t_order")),
MissingRequiredRuleException.class),
Arguments.of("one table exists and one missing",
new
AlterMaskRuleStatement(Arrays.asList(createRuleSegment("t_order", "order_id",
"MD5"), createRuleSegment("t_missing", "user_id", "AES"))),
-
createCurrentRuleConfiguration(Collections.singleton("t_order")),
MissingRequiredRuleException.class));
+
createCurrentRuleConfiguration(Collections.singleton("t_order")),
MissingRequiredRuleException.class),
+ Arguments.of("existing table in different case", new
AlterMaskRuleStatement(Collections.singleton(createRuleSegment("T_ORDER",
"order_id", "MD5"))),
+
createCurrentRuleConfiguration(Collections.singleton("t_order")), null));
}
private static MaskRuleSegment createRuleSegment(final String tableName,
final String columnName, final String algorithmType) {
@@ -134,6 +174,16 @@ class AlterMaskRuleExecutorTest {
return new MaskRuleConfiguration(tableRuleConfigs,
Collections.emptyMap());
}
+ private static MaskRuleConfiguration
createCurrentRuleConfigurationWithAlgorithms() {
+ Map<String, AlgorithmConfiguration> algorithmConfigs = new
LinkedHashMap<>(3, 1F);
+ algorithmConfigs.put("order_mask", new AlgorithmConfiguration("MD5",
new Properties()));
+ algorithmConfigs.put("user_mask", new AlgorithmConfiguration("MD5",
new Properties()));
+ algorithmConfigs.put("unused_mask", new AlgorithmConfiguration("SM3",
new Properties()));
+ return new MaskRuleConfiguration(new LinkedList<>(Arrays.asList(
+ new MaskTableRuleConfiguration("t_order",
Collections.singleton(new MaskColumnRuleConfiguration("order_id",
"order_mask"))),
+ new MaskTableRuleConfiguration("t_user",
Collections.singleton(new MaskColumnRuleConfiguration("user_id",
"user_mask"))))), algorithmConfigs);
+ }
+
private MaskRule createRule(final MaskRuleConfiguration ruleConfig) {
MaskRule result = mock(MaskRule.class);
when(result.getConfiguration()).thenReturn(ruleConfig);
diff --git
a/features/mask/distsql/handler/src/test/java/org/apache/shardingsphere/mask/distsql/handler/update/CreateMaskRuleExecutorTest.java
b/features/mask/distsql/handler/src/test/java/org/apache/shardingsphere/mask/distsql/handler/update/CreateMaskRuleExecutorTest.java
index 2b4ca444c36..19799f14665 100644
---
a/features/mask/distsql/handler/src/test/java/org/apache/shardingsphere/mask/distsql/handler/update/CreateMaskRuleExecutorTest.java
+++
b/features/mask/distsql/handler/src/test/java/org/apache/shardingsphere/mask/distsql/handler/update/CreateMaskRuleExecutorTest.java
@@ -18,10 +18,12 @@
package org.apache.shardingsphere.mask.distsql.handler.update;
import
org.apache.shardingsphere.distsql.handler.engine.update.DistSQLUpdateExecuteEngine;
+import
org.apache.shardingsphere.distsql.handler.engine.update.rdl.rule.spi.database.DatabaseRuleDefinitionExecutor;
import org.apache.shardingsphere.distsql.segment.AlgorithmSegment;
import
org.apache.shardingsphere.infra.exception.kernel.metadata.rule.DuplicateRuleException;
import
org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
import org.apache.shardingsphere.infra.metadata.database.rule.RuleMetaData;
+import org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader;
import org.apache.shardingsphere.mask.config.MaskRuleConfiguration;
import org.apache.shardingsphere.mask.config.rule.MaskTableRuleConfiguration;
import org.apache.shardingsphere.mask.distsql.segment.MaskColumnSegment;
@@ -55,7 +57,16 @@ class CreateMaskRuleExecutorTest {
void assertExecuteUpdateWithDuplicateMaskRule() {
MaskRule rule = mock(MaskRule.class);
when(rule.getConfiguration()).thenReturn(getCurrentRuleConfiguration());
- assertThrows(DuplicateRuleException.class, () -> new
DistSQLUpdateExecuteEngine(createDuplicatedSQLStatement(false, "MD5"),
"foo_db", mockContextManager(rule), null).executeUpdate());
+ assertThrows(DuplicateRuleException.class,
+ () -> new
DistSQLUpdateExecuteEngine(createDuplicatedSQLStatement(false, "MD5", "t_mask",
"t_order"), "foo_db", mockContextManager(rule), null).executeUpdate());
+ }
+
+ @Test
+ void assertExecuteUpdateWithDuplicateMaskRuleInDifferentCase() {
+ MaskRule rule = mock(MaskRule.class);
+
when(rule.getConfiguration()).thenReturn(getCurrentRuleConfiguration());
+ assertThrows(DuplicateRuleException.class,
+ () -> new
DistSQLUpdateExecuteEngine(createDuplicatedSQLStatement(false, "MD5", "T_MASK",
"T_ORDER"), "foo_db", mockContextManager(rule), null).executeUpdate());
}
@Test
@@ -82,6 +93,22 @@ class CreateMaskRuleExecutorTest {
assertDoesNotThrow(() ->
metaDataManagerPersistService.alterRuleConfiguration(any(),
argThat(this::assertRuleConfiguration)));
}
+ @Test
+ void
assertBuildToBeCreatedRuleConfigurationWithIfNotExistsWhenTableNameCaseDiffers()
{
+ CreateMaskRuleExecutor executor = (CreateMaskRuleExecutor)
TypedSPILoader.getService(DatabaseRuleDefinitionExecutor.class,
CreateMaskRuleStatement.class);
+ executor.setDatabase(mock(ShardingSphereDatabase.class));
+ MaskRule rule = mock(MaskRule.class);
+
when(rule.getConfiguration()).thenReturn(getCurrentRuleConfiguration());
+ executor.setRule(rule);
+ CreateMaskRuleStatement sqlStatement =
createDuplicatedSQLStatement(true, "MD5", "T_ORDER", "t_new");
+ executor.checkBeforeUpdate(sqlStatement);
+ MaskRuleConfiguration actual =
executor.buildToBeCreatedRuleConfiguration(sqlStatement);
+ assertThat(actual.getTables().size(), is(1));
+ assertThat(actual.getTables().iterator().next().getName(),
is("t_new"));
+ assertThat(actual.getMaskAlgorithms().size(), is(1));
+
assertTrue(actual.getMaskAlgorithms().containsKey("t_new_order_id_md5"));
+ }
+
private CreateMaskRuleStatement createSQLStatement(final boolean
ifNotExists, final String algorithmType) {
MaskColumnSegment tMaskColumnSegment = new
MaskColumnSegment("user_id", new AlgorithmSegment(algorithmType, new
Properties()));
MaskColumnSegment tOrderColumnSegment = new
MaskColumnSegment("order_id", new AlgorithmSegment(algorithmType, new
Properties()));
@@ -93,11 +120,11 @@ class CreateMaskRuleExecutorTest {
return new CreateMaskRuleStatement(ifNotExists, rules);
}
- private CreateMaskRuleStatement createDuplicatedSQLStatement(final boolean
ifNotExists, final String algorithmType) {
+ private CreateMaskRuleStatement createDuplicatedSQLStatement(final boolean
ifNotExists, final String algorithmType, final String maskTableName, final
String orderTableName) {
MaskColumnSegment tMaskColumnSegment = new
MaskColumnSegment("user_id", new AlgorithmSegment(algorithmType, new
Properties()));
MaskColumnSegment tOrderColumnSegment = new
MaskColumnSegment("order_id", new AlgorithmSegment(algorithmType, new
Properties()));
- MaskRuleSegment tMaskRuleSegment = new MaskRuleSegment("t_mask",
Collections.singleton(tMaskColumnSegment));
- MaskRuleSegment tOrderRuleSegment = new MaskRuleSegment("t_order",
Collections.singleton(tOrderColumnSegment));
+ MaskRuleSegment tMaskRuleSegment = new MaskRuleSegment(maskTableName,
Collections.singleton(tMaskColumnSegment));
+ MaskRuleSegment tOrderRuleSegment = new
MaskRuleSegment(orderTableName, Collections.singleton(tOrderColumnSegment));
Collection<MaskRuleSegment> rules = new LinkedList<>();
rules.add(tMaskRuleSegment);
rules.add(tOrderRuleSegment);