You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shardingsphere.apache.org by ji...@apache.org on 2022/12/29 00:24:38 UTC
[shardingsphere] branch master updated: Add `IF NOT EXISTS` to `create encrypt rule` (#23124)
This is an automated email from the ASF dual-hosted git repository.
jianglongtao 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 bbae7b79895 Add `IF NOT EXISTS` to `create encrypt rule` (#23124)
bbae7b79895 is described below
commit bbae7b798955d62470b22d43fbd387be2b6746e8
Author: Zichao <57...@users.noreply.github.com>
AuthorDate: Thu Dec 29 13:24:30 2022 +1300
Add `IF NOT EXISTS` to `create encrypt rule` (#23124)
* Add `IF NOT EXISTS` to `create encrypt rule`
* Add `IF NOT EXISTS` to `create encrypt rule`
* Add `IF NOT EXISTS` to `create encrypt rule`
* Add `IF NOT EXISTS` to `create encrypt rule`
* Add `IF NOT EXISTS` to `create encrypt rule`
---
.../update/CreateEncryptRuleStatementUpdater.java | 42 +++++++++++++++---
.../CreateEncryptRuleStatementUpdaterTest.java | 51 +++++++++++++++++-----
.../src/main/antlr4/imports/encrypt/Keyword.g4 | 4 ++
.../main/antlr4/imports/encrypt/RDLStatement.g4 | 6 ++-
.../core/EncryptDistSQLStatementVisitor.java | 2 +-
.../statement/CreateEncryptRuleStatement.java | 9 ++--
6 files changed, 92 insertions(+), 22 deletions(-)
diff --git a/features/encrypt/distsql/handler/src/main/java/org/apache/shardingsphere/encrypt/distsql/handler/update/CreateEncryptRuleStatementUpdater.java b/features/encrypt/distsql/handler/src/main/java/org/apache/shardingsphere/encrypt/distsql/handler/update/CreateEncryptRuleStatementUpdater.java
index bfd5809db67..5134ed3acd0 100644
--- a/features/encrypt/distsql/handler/src/main/java/org/apache/shardingsphere/encrypt/distsql/handler/update/CreateEncryptRuleStatementUpdater.java
+++ b/features/encrypt/distsql/handler/src/main/java/org/apache/shardingsphere/encrypt/distsql/handler/update/CreateEncryptRuleStatementUpdater.java
@@ -17,24 +17,26 @@
package org.apache.shardingsphere.encrypt.distsql.handler.update;
+import org.apache.shardingsphere.distsql.handler.exception.algorithm.InvalidAlgorithmConfigurationException;
+import org.apache.shardingsphere.distsql.handler.exception.rule.DuplicateRuleException;
+import org.apache.shardingsphere.distsql.handler.exception.rule.InvalidRuleConfigurationException;
+import org.apache.shardingsphere.distsql.handler.exception.storageunit.EmptyStorageUnitException;
+import org.apache.shardingsphere.distsql.handler.update.RuleDefinitionCreateUpdater;
import org.apache.shardingsphere.encrypt.api.config.EncryptRuleConfiguration;
+import org.apache.shardingsphere.encrypt.api.config.rule.EncryptColumnRuleConfiguration;
import org.apache.shardingsphere.encrypt.api.config.rule.EncryptTableRuleConfiguration;
import org.apache.shardingsphere.encrypt.distsql.handler.converter.EncryptRuleStatementConverter;
import org.apache.shardingsphere.encrypt.distsql.parser.segment.EncryptColumnSegment;
import org.apache.shardingsphere.encrypt.distsql.parser.segment.EncryptRuleSegment;
import org.apache.shardingsphere.encrypt.distsql.parser.statement.CreateEncryptRuleStatement;
import org.apache.shardingsphere.encrypt.factory.EncryptAlgorithmFactory;
-import org.apache.shardingsphere.distsql.handler.exception.storageunit.EmptyStorageUnitException;
-import org.apache.shardingsphere.distsql.handler.exception.rule.DuplicateRuleException;
-import org.apache.shardingsphere.distsql.handler.exception.algorithm.InvalidAlgorithmConfigurationException;
-import org.apache.shardingsphere.distsql.handler.exception.rule.InvalidRuleConfigurationException;
-import org.apache.shardingsphere.distsql.handler.update.RuleDefinitionCreateUpdater;
import org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
import org.apache.shardingsphere.infra.util.exception.ShardingSpherePreconditions;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashSet;
+import java.util.LinkedList;
import java.util.stream.Collectors;
/**
@@ -42,9 +44,14 @@ import java.util.stream.Collectors;
*/
public final class CreateEncryptRuleStatementUpdater implements RuleDefinitionCreateUpdater<CreateEncryptRuleStatement, EncryptRuleConfiguration> {
+ private boolean ifNotExists;
+
@Override
public void checkSQLStatement(final ShardingSphereDatabase database, final CreateEncryptRuleStatement sqlStatement, final EncryptRuleConfiguration currentRuleConfig) {
- checkDuplicateRuleNames(database.getName(), sqlStatement, currentRuleConfig);
+ ifNotExists = sqlStatement.isIfNotExists();
+ if (!ifNotExists) {
+ checkDuplicateRuleNames(database.getName(), sqlStatement, currentRuleConfig);
+ }
checkDataType(sqlStatement);
checkToBeCreatedEncryptors(sqlStatement);
checkDataSources(database);
@@ -87,11 +94,34 @@ public final class CreateEncryptRuleStatementUpdater implements RuleDefinitionCr
@Override
public void updateCurrentRuleConfiguration(final EncryptRuleConfiguration currentRuleConfig, final EncryptRuleConfiguration toBeCreatedRuleConfig) {
if (null != currentRuleConfig) {
+ if (ifNotExists) {
+ removeDuplicatedRules(currentRuleConfig, toBeCreatedRuleConfig);
+ }
+ if (toBeCreatedRuleConfig.getTables().isEmpty()) {
+ return;
+ }
currentRuleConfig.getTables().addAll(toBeCreatedRuleConfig.getTables());
currentRuleConfig.getEncryptors().putAll(toBeCreatedRuleConfig.getEncryptors());
}
}
+ private void removeDuplicatedRules(final EncryptRuleConfiguration currentRuleConfig, final EncryptRuleConfiguration toBeCreatedRuleConfig) {
+ Collection<String> currentTables = new LinkedList<>();
+ Collection<String> toBeRemovedEncryptors = new LinkedList<>();
+ Collection<String> toBeRemovedTables = new LinkedList<>();
+ currentRuleConfig.getTables().forEach(each -> currentTables.add(each.getName()));
+ toBeCreatedRuleConfig.getTables().forEach(each -> {
+ if (currentTables.contains(each.getName())) {
+ toBeRemovedEncryptors.addAll(each.getColumns().stream().map(EncryptColumnRuleConfiguration::getEncryptorName).collect(Collectors.toList()));
+ toBeRemovedEncryptors.addAll(each.getColumns().stream().map(EncryptColumnRuleConfiguration::getAssistedQueryEncryptorName).collect(Collectors.toList()));
+ toBeRemovedEncryptors.addAll(each.getColumns().stream().map(EncryptColumnRuleConfiguration::getLikeQueryEncryptorName).collect(Collectors.toList()));
+ toBeRemovedTables.add(each.getName());
+ }
+ });
+ toBeCreatedRuleConfig.getTables().removeIf(each -> toBeRemovedTables.contains(each.getName()));
+ toBeCreatedRuleConfig.getEncryptors().keySet().removeIf(toBeRemovedEncryptors::contains);
+ }
+
@Override
public Class<EncryptRuleConfiguration> getRuleConfigurationClass() {
return EncryptRuleConfiguration.class;
diff --git a/features/encrypt/distsql/handler/src/test/java/org/apache/shardingsphere/encrypt/distsql/handler/update/CreateEncryptRuleStatementUpdaterTest.java b/features/encrypt/distsql/handler/src/test/java/org/apache/shardingsphere/encrypt/distsql/handler/update/CreateEncryptRuleStatementUpdaterTest.java
index 34414d358fc..1752a369ef6 100644
--- a/features/encrypt/distsql/handler/src/test/java/org/apache/shardingsphere/encrypt/distsql/handler/update/CreateEncryptRuleStatementUpdaterTest.java
+++ b/features/encrypt/distsql/handler/src/test/java/org/apache/shardingsphere/encrypt/distsql/handler/update/CreateEncryptRuleStatementUpdaterTest.java
@@ -17,15 +17,15 @@
package org.apache.shardingsphere.encrypt.distsql.handler.update;
+import org.apache.shardingsphere.distsql.handler.exception.algorithm.InvalidAlgorithmConfigurationException;
+import org.apache.shardingsphere.distsql.handler.exception.rule.DuplicateRuleException;
+import org.apache.shardingsphere.distsql.handler.exception.rule.InvalidRuleConfigurationException;
import org.apache.shardingsphere.distsql.parser.segment.AlgorithmSegment;
import org.apache.shardingsphere.encrypt.api.config.EncryptRuleConfiguration;
import org.apache.shardingsphere.encrypt.api.config.rule.EncryptTableRuleConfiguration;
import org.apache.shardingsphere.encrypt.distsql.parser.segment.EncryptColumnSegment;
import org.apache.shardingsphere.encrypt.distsql.parser.segment.EncryptRuleSegment;
import org.apache.shardingsphere.encrypt.distsql.parser.statement.CreateEncryptRuleStatement;
-import org.apache.shardingsphere.distsql.handler.exception.rule.DuplicateRuleException;
-import org.apache.shardingsphere.distsql.handler.exception.algorithm.InvalidAlgorithmConfigurationException;
-import org.apache.shardingsphere.distsql.handler.exception.rule.InvalidRuleConfigurationException;
import org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -33,9 +33,16 @@ import org.mockito.Answers;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
+import java.util.Collection;
import java.util.Collections;
+import java.util.HashMap;
+import java.util.LinkedList;
import java.util.Properties;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertTrue;
+
@RunWith(MockitoJUnitRunner.class)
public final class CreateEncryptRuleStatementUpdaterTest {
@@ -46,12 +53,12 @@ public final class CreateEncryptRuleStatementUpdaterTest {
@Test(expected = DuplicateRuleException.class)
public void assertCheckSQLStatementWithDuplicateEncryptRule() {
- updater.checkSQLStatement(database, createSQLStatement("MD5"), getCurrentRuleConfig());
+ updater.checkSQLStatement(database, createSQLStatement(false, "MD5"), getCurrentRuleConfig());
}
@Test(expected = InvalidAlgorithmConfigurationException.class)
public void assertCheckSQLStatementWithoutToBeCreatedEncryptors() {
- updater.checkSQLStatement(database, createSQLStatement("INVALID_TYPE"), null);
+ updater.checkSQLStatement(database, createSQLStatement(false, "INVALID_TYPE"), null);
}
@Test(expected = InvalidRuleConfigurationException.class)
@@ -61,20 +68,42 @@ public final class CreateEncryptRuleStatementUpdaterTest {
new AlgorithmSegment("test", new Properties()),
new AlgorithmSegment("CHAR_DIGEST_LIKE", new Properties()), null);
EncryptRuleSegment ruleSegment = new EncryptRuleSegment("t_encrypt", Collections.singleton(columnSegment), null);
- CreateEncryptRuleStatement statement = new CreateEncryptRuleStatement(Collections.singleton(ruleSegment));
+ CreateEncryptRuleStatement statement = new CreateEncryptRuleStatement(false, Collections.singleton(ruleSegment));
updater.checkSQLStatement(database, statement, null);
}
- private CreateEncryptRuleStatement createSQLStatement(final String encryptorName) {
- EncryptColumnSegment columnSegment = new EncryptColumnSegment("user_id", "user_cipher", "user_plain", "assisted_column", "like_column",
+ @Test
+ public void assertCreateEncryptRuleWithIfNotExists() {
+ EncryptRuleConfiguration currentRuleConfig = getCurrentRuleConfig();
+ CreateEncryptRuleStatement sqlStatement = createSQLStatement(true, "AES");
+ updater.checkSQLStatement(database, sqlStatement, currentRuleConfig);
+ EncryptRuleConfiguration toBeCreatedRuleConfig = updater.buildToBeCreatedRuleConfiguration(sqlStatement);
+ updater.updateCurrentRuleConfiguration(currentRuleConfig, toBeCreatedRuleConfig);
+ assertThat(currentRuleConfig.getTables().size(), is(2));
+ assertTrue(currentRuleConfig.getEncryptors().isEmpty());
+ }
+
+ private CreateEncryptRuleStatement createSQLStatement(final boolean ifNotExists, final String encryptorName) {
+ EncryptColumnSegment tEncryptColumnSegment = new EncryptColumnSegment("user_id", "user_cipher", "user_plain", "assisted_column", "like_column",
new AlgorithmSegment(encryptorName, new Properties()),
new AlgorithmSegment(encryptorName, new Properties()),
new AlgorithmSegment(encryptorName, new Properties()), null);
- EncryptRuleSegment ruleSegment = new EncryptRuleSegment("t_encrypt", Collections.singleton(columnSegment), null);
- return new CreateEncryptRuleStatement(Collections.singleton(ruleSegment));
+ EncryptColumnSegment tOrderColumnSegment = new EncryptColumnSegment("order_id", "order_cipher", "order_plain", "assisted_column", "like_column",
+ new AlgorithmSegment(encryptorName, new Properties()),
+ new AlgorithmSegment(encryptorName, new Properties()),
+ new AlgorithmSegment(encryptorName, new Properties()), null);
+ EncryptRuleSegment tEncryptRuleSegment = new EncryptRuleSegment("t_encrypt", Collections.singleton(tEncryptColumnSegment), null);
+ EncryptRuleSegment tOrderRuleSegment = new EncryptRuleSegment("t_order", Collections.singleton(tOrderColumnSegment), null);
+ Collection<EncryptRuleSegment> rules = new LinkedList<>();
+ rules.add(tEncryptRuleSegment);
+ rules.add(tOrderRuleSegment);
+ return new CreateEncryptRuleStatement(ifNotExists, rules);
}
private EncryptRuleConfiguration getCurrentRuleConfig() {
- return new EncryptRuleConfiguration(Collections.singleton(new EncryptTableRuleConfiguration("t_encrypt", Collections.emptyList(), null)), Collections.emptyMap());
+ Collection<EncryptTableRuleConfiguration> rules = new LinkedList<>();
+ rules.add(new EncryptTableRuleConfiguration("t_encrypt", Collections.emptyList(), null));
+ rules.add(new EncryptTableRuleConfiguration("t_order", Collections.emptyList(), null));
+ return new EncryptRuleConfiguration(rules, new HashMap<>());
}
}
diff --git a/features/encrypt/distsql/parser/src/main/antlr4/imports/encrypt/Keyword.g4 b/features/encrypt/distsql/parser/src/main/antlr4/imports/encrypt/Keyword.g4
index aba744a3034..1f437610b45 100644
--- a/features/encrypt/distsql/parser/src/main/antlr4/imports/encrypt/Keyword.g4
+++ b/features/encrypt/distsql/parser/src/main/antlr4/imports/encrypt/Keyword.g4
@@ -178,3 +178,7 @@ SM4
CHAR_DIGEST_LIKE
: C H A R UL_ D I G E S T UL_ L I K E
;
+
+NOT
+ : N O T
+ ;
diff --git a/features/encrypt/distsql/parser/src/main/antlr4/imports/encrypt/RDLStatement.g4 b/features/encrypt/distsql/parser/src/main/antlr4/imports/encrypt/RDLStatement.g4
index c78e2b1170d..bd3f5aa71f9 100644
--- a/features/encrypt/distsql/parser/src/main/antlr4/imports/encrypt/RDLStatement.g4
+++ b/features/encrypt/distsql/parser/src/main/antlr4/imports/encrypt/RDLStatement.g4
@@ -20,7 +20,7 @@ grammar RDLStatement;
import BaseRule;
createEncryptRule
- : CREATE ENCRYPT RULE encryptRuleDefinition (COMMA_ encryptRuleDefinition)*
+ : CREATE ENCRYPT RULE ifNotExists? encryptRuleDefinition (COMMA_ encryptRuleDefinition)*
;
alterEncryptRule
@@ -110,3 +110,7 @@ queryWithCipherColumn
ifExists
: IF EXISTS
;
+
+ifNotExists
+ : IF NOT EXISTS
+ ;
diff --git a/features/encrypt/distsql/parser/src/main/java/org/apache/shardingsphere/encrypt/distsql/parser/core/EncryptDistSQLStatementVisitor.java b/features/encrypt/distsql/parser/src/main/java/org/apache/shardingsphere/encrypt/distsql/parser/core/EncryptDistSQLStatementVisitor.java
index d5efe890bba..d8a77a9ff3b 100644
--- a/features/encrypt/distsql/parser/src/main/java/org/apache/shardingsphere/encrypt/distsql/parser/core/EncryptDistSQLStatementVisitor.java
+++ b/features/encrypt/distsql/parser/src/main/java/org/apache/shardingsphere/encrypt/distsql/parser/core/EncryptDistSQLStatementVisitor.java
@@ -56,7 +56,7 @@ public final class EncryptDistSQLStatementVisitor extends EncryptDistSQLStatemen
@Override
public ASTNode visitCreateEncryptRule(final CreateEncryptRuleContext ctx) {
- return new CreateEncryptRuleStatement(ctx.encryptRuleDefinition().stream().map(each -> (EncryptRuleSegment) visit(each)).collect(Collectors.toList()));
+ return new CreateEncryptRuleStatement(null != ctx.ifNotExists(), ctx.encryptRuleDefinition().stream().map(each -> (EncryptRuleSegment) visit(each)).collect(Collectors.toList()));
}
@Override
diff --git a/features/encrypt/distsql/statement/src/main/java/org/apache/shardingsphere/encrypt/distsql/parser/statement/CreateEncryptRuleStatement.java b/features/encrypt/distsql/statement/src/main/java/org/apache/shardingsphere/encrypt/distsql/parser/statement/CreateEncryptRuleStatement.java
index 8f98adeed80..25ab6e9df4f 100644
--- a/features/encrypt/distsql/statement/src/main/java/org/apache/shardingsphere/encrypt/distsql/parser/statement/CreateEncryptRuleStatement.java
+++ b/features/encrypt/distsql/statement/src/main/java/org/apache/shardingsphere/encrypt/distsql/parser/statement/CreateEncryptRuleStatement.java
@@ -18,18 +18,21 @@
package org.apache.shardingsphere.encrypt.distsql.parser.statement;
import lombok.Getter;
-import lombok.RequiredArgsConstructor;
-import org.apache.shardingsphere.encrypt.distsql.parser.segment.EncryptRuleSegment;
import org.apache.shardingsphere.distsql.parser.statement.rdl.create.CreateRuleStatement;
+import org.apache.shardingsphere.encrypt.distsql.parser.segment.EncryptRuleSegment;
import java.util.Collection;
/**
* Create encrypt rule statement.
*/
-@RequiredArgsConstructor
@Getter
public final class CreateEncryptRuleStatement extends CreateRuleStatement {
private final Collection<EncryptRuleSegment> rules;
+
+ public CreateEncryptRuleStatement(final boolean ifNotExists, final Collection<EncryptRuleSegment> rules) {
+ super(ifNotExists);
+ this.rules = rules;
+ }
}