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/24 10:29:03 UTC

[shardingsphere] branch master updated: Add `IF NOT EXISTS` to `register storage unit` statement (#23066)

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 baaf458f298 Add `IF NOT EXISTS` to `register storage unit` statement (#23066)
baaf458f298 is described below

commit baaf458f298cd813d0882ee5445ed023d3d4a902
Author: Zichao <57...@users.noreply.github.com>
AuthorDate: Sat Dec 24 23:28:53 2022 +1300

    Add `IF NOT EXISTS` to `register storage unit` statement (#23066)
    
    * Add `IF NOT EXISTS` to `register storage unit`
    
    * Add `IF NOT EXISTS` to `register storage unit`
---
 .../core/advice/SQLParserEngineAdviceTest.java     |  2 +-
 distsql/parser/src/main/antlr4/imports/Keyword.g4  |  4 ++++
 .../parser/src/main/antlr4/imports/RDLStatement.g4 |  6 +++++-
 .../core/kernel/KernelDistSQLStatementVisitor.java |  2 +-
 .../rdl/create/RegisterStorageUnitStatement.java   |  2 ++
 .../transaction/utils/AutoCommitUtilsTest.java     | 11 +++++-----
 .../RegisterStorageUnitBackendHandler.java         | 24 ++++++++++++++++++----
 .../RegisterStorageUnitBackendHandlerTest.java     | 11 ++++++++--
 8 files changed, 48 insertions(+), 14 deletions(-)

diff --git a/agent/plugins/metrics/core/src/test/java/org/apache/shardingsphere/agent/metrics/core/advice/SQLParserEngineAdviceTest.java b/agent/plugins/metrics/core/src/test/java/org/apache/shardingsphere/agent/metrics/core/advice/SQLParserEngineAdviceTest.java
index eec4b0f9402..da5eac73c85 100644
--- a/agent/plugins/metrics/core/src/test/java/org/apache/shardingsphere/agent/metrics/core/advice/SQLParserEngineAdviceTest.java
+++ b/agent/plugins/metrics/core/src/test/java/org/apache/shardingsphere/agent/metrics/core/advice/SQLParserEngineAdviceTest.java
@@ -92,7 +92,7 @@ public final class SQLParserEngineAdviceTest extends MetricsAdviceBaseTest {
     
     @Test
     public void assertParseRDL() {
-        assertParse(MetricIds.PARSE_DIST_SQL_RDL, new RegisterStorageUnitStatement(Collections.emptyList()));
+        assertParse(MetricIds.PARSE_DIST_SQL_RDL, new RegisterStorageUnitStatement(false, Collections.emptyList()));
     }
     
     @Test
diff --git a/distsql/parser/src/main/antlr4/imports/Keyword.g4 b/distsql/parser/src/main/antlr4/imports/Keyword.g4
index e3c89e7259c..b9e2e7a9da3 100644
--- a/distsql/parser/src/main/antlr4/imports/Keyword.g4
+++ b/distsql/parser/src/main/antlr4/imports/Keyword.g4
@@ -358,3 +358,7 @@ CENTER
 LIKE
     : L I K E
     ;
+
+NOT
+    : N O T
+    ;
diff --git a/distsql/parser/src/main/antlr4/imports/RDLStatement.g4 b/distsql/parser/src/main/antlr4/imports/RDLStatement.g4
index dc957eb5017..c520f29626d 100644
--- a/distsql/parser/src/main/antlr4/imports/RDLStatement.g4
+++ b/distsql/parser/src/main/antlr4/imports/RDLStatement.g4
@@ -20,7 +20,7 @@ grammar RDLStatement;
 import BaseRule;
 
 registerStorageUnit
-    : REGISTER STORAGE UNIT storageUnitDefinition (COMMA_ storageUnitDefinition)*
+    : REGISTER STORAGE UNIT ifNotExists? storageUnitDefinition (COMMA_ storageUnitDefinition)*
     ;
 
 alterStorageUnit
@@ -78,3 +78,7 @@ ignoreSingleTables
 ifExists
     : IF EXISTS
     ;
+
+ifNotExists
+    : IF NOT EXISTS
+    ;
diff --git a/distsql/parser/src/main/java/org/apache/shardingsphere/distsql/parser/core/kernel/KernelDistSQLStatementVisitor.java b/distsql/parser/src/main/java/org/apache/shardingsphere/distsql/parser/core/kernel/KernelDistSQLStatementVisitor.java
index d9eec33dfae..e1ab03a2086 100644
--- a/distsql/parser/src/main/java/org/apache/shardingsphere/distsql/parser/core/kernel/KernelDistSQLStatementVisitor.java
+++ b/distsql/parser/src/main/java/org/apache/shardingsphere/distsql/parser/core/kernel/KernelDistSQLStatementVisitor.java
@@ -120,7 +120,7 @@ public final class KernelDistSQLStatementVisitor extends KernelDistSQLStatementB
     
     @Override
     public ASTNode visitRegisterStorageUnit(final RegisterStorageUnitContext ctx) {
-        return new RegisterStorageUnitStatement(ctx.storageUnitDefinition().stream().map(each -> (DataSourceSegment) visit(each)).collect(Collectors.toList()));
+        return new RegisterStorageUnitStatement(null != ctx.ifNotExists(), ctx.storageUnitDefinition().stream().map(each -> (DataSourceSegment) visit(each)).collect(Collectors.toList()));
     }
     
     @Override
diff --git a/distsql/statement/src/main/java/org/apache/shardingsphere/distsql/parser/statement/rdl/create/RegisterStorageUnitStatement.java b/distsql/statement/src/main/java/org/apache/shardingsphere/distsql/parser/statement/rdl/create/RegisterStorageUnitStatement.java
index a255a7b77e8..36492c0b973 100644
--- a/distsql/statement/src/main/java/org/apache/shardingsphere/distsql/parser/statement/rdl/create/RegisterStorageUnitStatement.java
+++ b/distsql/statement/src/main/java/org/apache/shardingsphere/distsql/parser/statement/rdl/create/RegisterStorageUnitStatement.java
@@ -31,5 +31,7 @@ import java.util.Collection;
 @Getter
 public final class RegisterStorageUnitStatement extends StorageUnitDefinitionStatement {
     
+    private final boolean ifNotExists;
+    
     private final Collection<DataSourceSegment> storageUnits;
 }
diff --git a/kernel/transaction/core/src/test/java/org/apache/shardingsphere/transaction/utils/AutoCommitUtilsTest.java b/kernel/transaction/core/src/test/java/org/apache/shardingsphere/transaction/utils/AutoCommitUtilsTest.java
index b292d013884..ab5ac5b2469 100644
--- a/kernel/transaction/core/src/test/java/org/apache/shardingsphere/transaction/utils/AutoCommitUtilsTest.java
+++ b/kernel/transaction/core/src/test/java/org/apache/shardingsphere/transaction/utils/AutoCommitUtilsTest.java
@@ -17,10 +17,6 @@
 
 package org.apache.shardingsphere.transaction.utils;
 
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import java.util.LinkedList;
 import org.apache.shardingsphere.distsql.parser.statement.rdl.create.RegisterStorageUnitStatement;
 import org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.SimpleTableSegment;
 import org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.TableNameSegment;
@@ -31,6 +27,11 @@ import org.apache.shardingsphere.sql.parser.sql.dialect.statement.mysql.dml.MySQ
 import org.apache.shardingsphere.sql.parser.sql.dialect.statement.mysql.dml.MySQLSelectStatement;
 import org.junit.Test;
 
+import java.util.LinkedList;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
 public final class AutoCommitUtilsTest {
     
     @Test
@@ -49,6 +50,6 @@ public final class AutoCommitUtilsTest {
     
     @Test
     public void assertNeedOpenTransactionForOtherStatement() {
-        assertFalse(AutoCommitUtils.needOpenTransaction(new RegisterStorageUnitStatement(new LinkedList<>())));
+        assertFalse(AutoCommitUtils.needOpenTransaction(new RegisterStorageUnitStatement(false, new LinkedList<>())));
     }
 }
diff --git a/proxy/backend/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/resource/RegisterStorageUnitBackendHandler.java b/proxy/backend/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/resource/RegisterStorageUnitBackendHandler.java
index b1165c6b0c9..dcb1c4b3516 100644
--- a/proxy/backend/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/resource/RegisterStorageUnitBackendHandler.java
+++ b/proxy/backend/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/resource/RegisterStorageUnitBackendHandler.java
@@ -18,14 +18,14 @@
 package org.apache.shardingsphere.proxy.backend.handler.distsql.rdl.resource;
 
 import lombok.extern.slf4j.Slf4j;
+import org.apache.shardingsphere.distsql.handler.exception.resource.DuplicateResourceException;
+import org.apache.shardingsphere.distsql.handler.exception.resource.InvalidResourcesException;
 import org.apache.shardingsphere.distsql.handler.validate.DataSourcePropertiesValidateHandler;
 import org.apache.shardingsphere.distsql.parser.segment.DataSourceSegment;
 import org.apache.shardingsphere.distsql.parser.segment.converter.ResourceSegmentsConverter;
 import org.apache.shardingsphere.distsql.parser.statement.rdl.create.RegisterStorageUnitStatement;
 import org.apache.shardingsphere.infra.database.type.DatabaseType;
 import org.apache.shardingsphere.infra.datasource.props.DataSourceProperties;
-import org.apache.shardingsphere.distsql.handler.exception.resource.DuplicateResourceException;
-import org.apache.shardingsphere.distsql.handler.exception.resource.InvalidResourcesException;
 import org.apache.shardingsphere.infra.util.exception.ShardingSpherePreconditions;
 import org.apache.shardingsphere.infra.util.exception.external.server.ShardingSphereServerException;
 import org.apache.shardingsphere.proxy.backend.context.ProxyContext;
@@ -42,8 +42,10 @@ import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 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;
 
 /**
@@ -66,6 +68,18 @@ public final class RegisterStorageUnitBackendHandler extends DatabaseRequiredBac
     public ResponseHeader execute(final String databaseName, final RegisterStorageUnitStatement sqlStatement) {
         checkSQLStatement(databaseName, sqlStatement);
         Map<String, DataSourceProperties> dataSourcePropsMap = ResourceSegmentsConverter.convert(databaseType, sqlStatement.getStorageUnits());
+        if (sqlStatement.isIfNotExists()) {
+            Set<String> currentStorageUnits = ProxyContext.getInstance().getContextManager().getDataSourceMap(databaseName).keySet();
+            Iterator<String> iterator = dataSourcePropsMap.keySet().iterator();
+            while (iterator.hasNext()) {
+                if (currentStorageUnits.contains(iterator.next())) {
+                    iterator.remove();
+                }
+            }
+        }
+        if (dataSourcePropsMap.isEmpty()) {
+            return new UpdateResponseHeader(sqlStatement);
+        }
         validateHandler.validate(dataSourcePropsMap);
         try {
             ProxyContext.getInstance().getContextManager().getInstanceContext().getModeContextManager().registerStorageUnits(databaseName, dataSourcePropsMap);
@@ -79,8 +93,10 @@ public final class RegisterStorageUnitBackendHandler extends DatabaseRequiredBac
     @Override
     public void checkSQLStatement(final String databaseName, final RegisterStorageUnitStatement sqlStatement) {
         Collection<String> dataSourceNames = new ArrayList<>(sqlStatement.getStorageUnits().size());
-        checkDuplicatedDataSourceNames(databaseName, dataSourceNames, sqlStatement);
-        checkDuplicatedDataSourceNameWithReadwriteSplittingRule(databaseName, dataSourceNames);
+        if (!sqlStatement.isIfNotExists()) {
+            checkDuplicatedDataSourceNames(databaseName, dataSourceNames, sqlStatement);
+            checkDuplicatedDataSourceNameWithReadwriteSplittingRule(databaseName, dataSourceNames);
+        }
     }
     
     private void checkDuplicatedDataSourceNames(final String databaseName, final Collection<String> dataSourceNames, final RegisterStorageUnitStatement sqlStatement) {
diff --git a/proxy/backend/src/test/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/resource/RegisterStorageUnitBackendHandlerTest.java b/proxy/backend/src/test/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/resource/RegisterStorageUnitBackendHandlerTest.java
index ffad5ec1647..588cf2e0abe 100644
--- a/proxy/backend/src/test/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/resource/RegisterStorageUnitBackendHandlerTest.java
+++ b/proxy/backend/src/test/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/resource/RegisterStorageUnitBackendHandlerTest.java
@@ -145,18 +145,25 @@ public final class RegisterStorageUnitBackendHandlerTest extends ProxyContextRes
         registerStorageUnitBackendHandler.execute("test_db", createRegisterStorageUnitStatement());
     }
     
+    @Test
+    public void assertCheckStatementWithIfNotExists() {
+        RegisterStorageUnitStatement registerStorageUnitStatementWithIfNotExists = new RegisterStorageUnitStatement(true, Collections.singleton(
+                new HostnameAndPortBasedDataSourceSegment("ds_0", "127.0.0.1", "3306", "db_1", "root", "", new Properties())));
+        registerStorageUnitBackendHandler.checkSQLStatement("test_db", registerStorageUnitStatementWithIfNotExists);
+    }
+    
     private ReadwriteSplittingRuleConfiguration createReadwriteSplittingRuleConfiguration(final String ruleName) {
         return new ReadwriteSplittingRuleConfiguration(Collections.singleton(new ReadwriteSplittingDataSourceRuleConfiguration(ruleName, null, null, null)), Collections.emptyMap());
     }
     
     private RegisterStorageUnitStatement createRegisterStorageUnitStatement() {
-        return new RegisterStorageUnitStatement(Collections.singleton(new URLBasedDataSourceSegment("ds_0", "jdbc:mysql://127.0.0.1:3306/test0", "root", "", new Properties())));
+        return new RegisterStorageUnitStatement(false, Collections.singleton(new URLBasedDataSourceSegment("ds_0", "jdbc:mysql://127.0.0.1:3306/test0", "root", "", new Properties())));
     }
     
     private RegisterStorageUnitStatement createRegisterStorageUnitStatementWithDuplicateStorageUnitNames() {
         Collection<DataSourceSegment> result = new LinkedList<>();
         result.add(new HostnameAndPortBasedDataSourceSegment("ds_0", "127.0.0.1", "3306", "ds_0", "root", "", new Properties()));
         result.add(new URLBasedDataSourceSegment("ds_0", "jdbc:mysql://127.0.0.1:3306/ds_1", "root", "", new Properties()));
-        return new RegisterStorageUnitStatement(result);
+        return new RegisterStorageUnitStatement(false, result);
     }
 }