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 <[email protected]>
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;
+    }
 }

Reply via email to