This is an automated email from the ASF dual-hosted git repository.

panjuan 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 b5b9416  Add `ALTER RESOURCE` syntax for DistSQL. (#12349)
b5b9416 is described below

commit b5b941634383dd066fb7b8e73f92d653af6b7a17
Author: Raigor <[email protected]>
AuthorDate: Sun Sep 12 16:46:07 2021 +0800

    Add `ALTER RESOURCE` syntax for DistSQL. (#12349)
    
    * Add DistSQL syntax: Alter Resource.
    
    * Update DistSQL document.
---
 .../dist-sql/syntax/rdl/rdl-resource.cn.md         | 16 ++++
 .../dist-sql/syntax/rdl/rdl-resource.en.md         | 16 ++++
 .../src/main/antlr4/imports/Keyword.g4             |  4 +
 .../src/main/antlr4/imports/RDLStatement.g4        |  4 +
 .../parser/autogen/CommonDistSQLStatement.g4       |  1 +
 .../core/common/CommonDistSQLStatementVisitor.java |  7 ++
 .../rdl/alter/AlterResourceStatement.java}         | 27 ++++---
 .../text/distsql/rdl/RDLBackendHandlerFactory.java |  5 ++
 .../rdl/resource/AddResourceBackendHandler.java    |  4 +-
 ...ndler.java => AlterResourceBackendHandler.java} | 68 ++++++++++------
 .../distsql/DistSQLBackendHandlerFactoryTest.java  | 29 +++++++
 .../resource/AddResourceBackendHandlerTest.java    | 28 ++++++-
 ...t.java => AlterResourceBackendHandlerTest.java} | 62 ++++++++++----
 ...nverter.java => ResourceSegmentsConverter.java} | 16 ++--
 ...est.java => ResourceSegmentsConverterTest.java} |  5 +-
 .../statement/distsql/rdl/RDLStatementAssert.java  |  5 ++
 .../rdl/alter/AlterResourceStatementAssert.java    | 72 +++++++++++++++++
 .../jaxb/cases/domain/SQLParserTestCases.java      |  5 ++
 .../rdl/alter/AlterResourceStatementTestCase.java  | 94 +++++-----------------
 .../src/main/resources/case/rdl/alter.xml          | 46 +++++++++++
 .../src/main/resources/sql/supported/rdl/alter.xml |  9 +++
 21 files changed, 380 insertions(+), 143 deletions(-)

diff --git 
a/docs/document/content/features/dist-sql/syntax/rdl/rdl-resource.cn.md 
b/docs/document/content/features/dist-sql/syntax/rdl/rdl-resource.cn.md
index 0c826ab..4fb8e63 100644
--- a/docs/document/content/features/dist-sql/syntax/rdl/rdl-resource.cn.md
+++ b/docs/document/content/features/dist-sql/syntax/rdl/rdl-resource.cn.md
@@ -8,6 +8,8 @@ weight = 1
 ```sql
 ADD RESOURCE dataSource [, dataSource] ...
 
+ALTER RESOURCE dataSource [, dataSource] ...
+
 dataSource:
     simpleSource | urlSource
 
@@ -28,6 +30,7 @@ DROP RESOURCE dataSourceName [, dataSourceName] ...
 - 重复的 `dataSourceName` 不允许被添加
 - 在同一 `dataSource` 的定义中,`simpleSource` 和 `urlSource` 语法不可混用
 - `poolProperty` 用于自定义连接池参数,`key` 必须和连接池参数名一致,`value` 支持 int 和 String 类型
+- `ALTER RESOURCE` 修改资源时会发生连接池的切换,这个操作可能对进行中的业务造成影响,请谨慎使用
 - `DROP RESOURCE` 只会删除逻辑资源,不会删除真实的数据源
 - 被规则引用的资源将无法被删除
 
@@ -58,5 +61,18 @@ ADD RESOURCE resource_0 (
     PROPERTIES("maximumPoolSize"=10,"idleTimeout"="30000")
 );
 
+ALTER RESOURCE resource_0 (
+    HOST=127.0.0.1,
+    PORT=3309,
+    DB=db0,
+    USER=root,
+    PASSWORD=root
+),resource_1 (
+    URL="jdbc:mysql://127.0.0.1:3309/db1?serverTimezone=UTC&useSSL=false",
+    USER=root,
+    PASSWORD=root,
+    PROPERTIES("maximumPoolSize"=10,"idleTimeout"="30000")
+)
+
 DROP RESOURCE resource_0, resource_1, resource_2, resource_3;
 ```
diff --git 
a/docs/document/content/features/dist-sql/syntax/rdl/rdl-resource.en.md 
b/docs/document/content/features/dist-sql/syntax/rdl/rdl-resource.en.md
index cddc7e6..10b72d8 100644
--- a/docs/document/content/features/dist-sql/syntax/rdl/rdl-resource.en.md
+++ b/docs/document/content/features/dist-sql/syntax/rdl/rdl-resource.en.md
@@ -8,6 +8,8 @@ weight = 1
 ```sql
 ADD RESOURCE dataSource [, dataSource] ...
 
+ALTER RESOURCE dataSource [, dataSource] ...
+
 dataSource:
     simpleSource | urlSource
 
@@ -28,6 +30,7 @@ DROP RESOURCE dataSourceName [, dataSourceName] ...
 - Duplicate `dataSourceName` is not allowed to be added
 - In the definition of a `dataSource`, the syntax of `simpleSource` and 
`urlSource` cannot be mixed
 - `poolProperty` is used to customize connection pool properties, `key` must 
be the same as the connection pool property name, `value` supports int and 
String types
+- `ALTER RESOURCE` will switch the connection pool. This operation may affect 
the ongoing business, please use it with caution
 - `DROP RESOURCE` will only delete logical resources, not real data sources
 - Resources referenced by rules cannot be deleted
 
@@ -58,5 +61,18 @@ ADD RESOURCE resource_0 (
     PROPERTIES("maximumPoolSize"=10,"idleTimeout"="30000")
 );
 
+ALTER RESOURCE resource_0 (
+    HOST=127.0.0.1,
+    PORT=3309,
+    DB=db0,
+    USER=root,
+    PASSWORD=root
+),resource_1 (
+    URL="jdbc:mysql://127.0.0.1:3309/db1?serverTimezone=UTC&useSSL=false",
+    USER=root,
+    PASSWORD=root,
+    PROPERTIES("maximumPoolSize"=10,"idleTimeout"="30000")
+)
+
 DROP RESOURCE resource_0, resource_1, resource_2, resource_3;
 ```
diff --git 
a/shardingsphere-distsql-parser/shardingsphere-distsql-parser-engine/src/main/antlr4/imports/Keyword.g4
 
b/shardingsphere-distsql-parser/shardingsphere-distsql-parser-engine/src/main/antlr4/imports/Keyword.g4
index d9ba2a1..3473f71 100644
--- 
a/shardingsphere-distsql-parser/shardingsphere-distsql-parser-engine/src/main/antlr4/imports/Keyword.g4
+++ 
b/shardingsphere-distsql-parser/shardingsphere-distsql-parser-engine/src/main/antlr4/imports/Keyword.g4
@@ -27,6 +27,10 @@ ADD
     : A D D
     ;
 
+ALTER
+    : A L T E R
+    ;
+
 CLEAR
     : C L E A R
     ;
diff --git 
a/shardingsphere-distsql-parser/shardingsphere-distsql-parser-engine/src/main/antlr4/imports/RDLStatement.g4
 
b/shardingsphere-distsql-parser/shardingsphere-distsql-parser-engine/src/main/antlr4/imports/RDLStatement.g4
index e71b952..9a24a7e 100644
--- 
a/shardingsphere-distsql-parser/shardingsphere-distsql-parser-engine/src/main/antlr4/imports/RDLStatement.g4
+++ 
b/shardingsphere-distsql-parser/shardingsphere-distsql-parser-engine/src/main/antlr4/imports/RDLStatement.g4
@@ -23,6 +23,10 @@ addResource
     : ADD RESOURCE dataSource (COMMA dataSource)*
     ;
 
+alterResource
+    : ALTER RESOURCE dataSource (COMMA dataSource)*
+    ;
+
 dropResource
     : DROP RESOURCE IDENTIFIER (COMMA IDENTIFIER)*
     ;
diff --git 
a/shardingsphere-distsql-parser/shardingsphere-distsql-parser-engine/src/main/antlr4/org/apache/shardingsphere/distsql/parser/autogen/CommonDistSQLStatement.g4
 
b/shardingsphere-distsql-parser/shardingsphere-distsql-parser-engine/src/main/antlr4/org/apache/shardingsphere/distsql/parser/autogen/CommonDistSQLStatement.g4
index f514dec..4598f99 100644
--- 
a/shardingsphere-distsql-parser/shardingsphere-distsql-parser-engine/src/main/antlr4/org/apache/shardingsphere/distsql/parser/autogen/CommonDistSQLStatement.g4
+++ 
b/shardingsphere-distsql-parser/shardingsphere-distsql-parser-engine/src/main/antlr4/org/apache/shardingsphere/distsql/parser/autogen/CommonDistSQLStatement.g4
@@ -21,6 +21,7 @@ import Symbol, RALStatement, RDLStatement, RQLStatement;
 
 execute
     : (addResource
+    | alterResource
     | dropResource
     | showResources
     | setVariable
diff --git 
a/shardingsphere-distsql-parser/shardingsphere-distsql-parser-engine/src/main/java/org/apache/shardingsphere/distsql/parser/core/common/CommonDistSQLStatementVisitor.java
 
b/shardingsphere-distsql-parser/shardingsphere-distsql-parser-engine/src/main/java/org/apache/shardingsphere/distsql/parser/core/common/CommonDistSQLStatementVisitor.java
index d579dd9..fb6bb72 100644
--- 
a/shardingsphere-distsql-parser/shardingsphere-distsql-parser-engine/src/main/java/org/apache/shardingsphere/distsql/parser/core/common/CommonDistSQLStatementVisitor.java
+++ 
b/shardingsphere-distsql-parser/shardingsphere-distsql-parser-engine/src/main/java/org/apache/shardingsphere/distsql/parser/core/common/CommonDistSQLStatementVisitor.java
@@ -20,6 +20,7 @@ package org.apache.shardingsphere.distsql.parser.core.common;
 import org.antlr.v4.runtime.tree.ParseTree;
 import 
org.apache.shardingsphere.distsql.parser.autogen.CommonDistSQLStatementBaseVisitor;
 import 
org.apache.shardingsphere.distsql.parser.autogen.CommonDistSQLStatementParser.AddResourceContext;
+import 
org.apache.shardingsphere.distsql.parser.autogen.CommonDistSQLStatementParser.AlterResourceContext;
 import 
org.apache.shardingsphere.distsql.parser.autogen.CommonDistSQLStatementParser.ClearHintContext;
 import 
org.apache.shardingsphere.distsql.parser.autogen.CommonDistSQLStatementParser.DataSourceContext;
 import 
org.apache.shardingsphere.distsql.parser.autogen.CommonDistSQLStatementParser.DropResourceContext;
@@ -33,6 +34,7 @@ import 
org.apache.shardingsphere.distsql.parser.segment.DataSourceSegment;
 import 
org.apache.shardingsphere.distsql.parser.statement.ral.common.hint.ClearHintStatement;
 import 
org.apache.shardingsphere.distsql.parser.statement.ral.common.variable.SetVariableStatement;
 import 
org.apache.shardingsphere.distsql.parser.statement.ral.common.variable.ShowVariableStatement;
+import 
org.apache.shardingsphere.distsql.parser.statement.rdl.alter.AlterResourceStatement;
 import 
org.apache.shardingsphere.distsql.parser.statement.rdl.create.AddResourceStatement;
 import 
org.apache.shardingsphere.distsql.parser.statement.rdl.drop.DropResourceStatement;
 import 
org.apache.shardingsphere.distsql.parser.statement.rql.show.ShowResourcesStatement;
@@ -55,6 +57,11 @@ public final class CommonDistSQLStatementVisitor extends 
CommonDistSQLStatementB
     }
     
     @Override
+    public ASTNode visitAlterResource(final AlterResourceContext ctx) {
+        return new AlterResourceStatement(ctx.dataSource().stream().map(each 
-> (DataSourceSegment) visit(each)).collect(Collectors.toList()));
+    }
+    
+    @Override
     public ASTNode visitDataSource(final DataSourceContext ctx) {
         String url = null;
         String hostName = null;
diff --git 
a/shardingsphere-distsql-parser/shardingsphere-distsql-parser-engine/src/main/antlr4/org/apache/shardingsphere/distsql/parser/autogen/CommonDistSQLStatement.g4
 
b/shardingsphere-distsql-parser/shardingsphere-distsql-parser-statement/src/main/java/org/apache/shardingsphere/distsql/parser/statement/rdl/alter/AlterResourceStatement.java
similarity index 59%
copy from 
shardingsphere-distsql-parser/shardingsphere-distsql-parser-engine/src/main/antlr4/org/apache/shardingsphere/distsql/parser/autogen/CommonDistSQLStatement.g4
copy to 
shardingsphere-distsql-parser/shardingsphere-distsql-parser-statement/src/main/java/org/apache/shardingsphere/distsql/parser/statement/rdl/alter/AlterResourceStatement.java
index f514dec..924376c 100644
--- 
a/shardingsphere-distsql-parser/shardingsphere-distsql-parser-engine/src/main/antlr4/org/apache/shardingsphere/distsql/parser/autogen/CommonDistSQLStatement.g4
+++ 
b/shardingsphere-distsql-parser/shardingsphere-distsql-parser-statement/src/main/java/org/apache/shardingsphere/distsql/parser/statement/rdl/alter/AlterResourceStatement.java
@@ -15,16 +15,21 @@
  * limitations under the License.
  */
 
-grammar CommonDistSQLStatement;
+package org.apache.shardingsphere.distsql.parser.statement.rdl.alter;
 
-import Symbol, RALStatement, RDLStatement, RQLStatement;
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import org.apache.shardingsphere.distsql.parser.segment.DataSourceSegment;
+import 
org.apache.shardingsphere.distsql.parser.statement.rdl.ResourceDefinitionStatement;
 
-execute
-    : (addResource
-    | dropResource
-    | showResources
-    | setVariable
-    | showVariable
-    | clearHint
-    ) SEMI?
-    ;
+import java.util.Collection;
+
+/**
+ * Alter resource statement.
+ */
+@RequiredArgsConstructor
+@Getter
+public final class AlterResourceStatement extends ResourceDefinitionStatement {
+    
+    private final Collection<DataSourceSegment> dataSources;
+}
diff --git 
a/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/text/distsql/rdl/RDLBackendHandlerFactory.java
 
b/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/text/distsql/rdl/RDLBackendHandlerFactory.java
index c77b4bc..963fa29 100644
--- 
a/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/text/distsql/rdl/RDLBackendHandlerFactory.java
+++ 
b/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/text/distsql/rdl/RDLBackendHandlerFactory.java
@@ -21,12 +21,14 @@ import lombok.AccessLevel;
 import lombok.NoArgsConstructor;
 import org.apache.shardingsphere.distsql.parser.statement.rdl.RDLStatement;
 import 
org.apache.shardingsphere.distsql.parser.statement.rdl.RuleDefinitionStatement;
+import 
org.apache.shardingsphere.distsql.parser.statement.rdl.alter.AlterResourceStatement;
 import 
org.apache.shardingsphere.distsql.parser.statement.rdl.create.AddResourceStatement;
 import 
org.apache.shardingsphere.distsql.parser.statement.rdl.drop.DropResourceStatement;
 import org.apache.shardingsphere.infra.database.type.DatabaseType;
 import 
org.apache.shardingsphere.proxy.backend.communication.jdbc.connection.BackendConnection;
 import org.apache.shardingsphere.proxy.backend.text.TextProtocolBackendHandler;
 import 
org.apache.shardingsphere.proxy.backend.text.distsql.rdl.resource.AddResourceBackendHandler;
+import 
org.apache.shardingsphere.proxy.backend.text.distsql.rdl.resource.AlterResourceBackendHandler;
 import 
org.apache.shardingsphere.proxy.backend.text.distsql.rdl.resource.DropResourceBackendHandler;
 import 
org.apache.shardingsphere.proxy.backend.text.distsql.rdl.rule.RuleDefinitionBackendHandler;
 
@@ -55,6 +57,9 @@ public final class RDLBackendHandlerFactory {
         if (sqlStatement instanceof AddResourceStatement) {
             return new AddResourceBackendHandler(databaseType, 
(AddResourceStatement) sqlStatement, backendConnection);
         }
+        if (sqlStatement instanceof AlterResourceStatement) {
+            return new AlterResourceBackendHandler(databaseType, 
(AlterResourceStatement) sqlStatement, backendConnection);
+        }
         if (sqlStatement instanceof DropResourceStatement) {
             return new DropResourceBackendHandler((DropResourceStatement) 
sqlStatement, backendConnection);
         }
diff --git 
a/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/text/distsql/rdl/resource/AddResourceBackendHandler.java
 
b/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/text/distsql/rdl/resource/AddResourceBackendHandler.java
index 778a6e4..b5316e4 100644
--- 
a/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/text/distsql/rdl/resource/AddResourceBackendHandler.java
+++ 
b/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/text/distsql/rdl/resource/AddResourceBackendHandler.java
@@ -31,7 +31,7 @@ import 
org.apache.shardingsphere.proxy.backend.response.header.ResponseHeader;
 import 
org.apache.shardingsphere.proxy.backend.response.header.update.UpdateResponseHeader;
 import 
org.apache.shardingsphere.proxy.backend.text.SchemaRequiredBackendHandler;
 import 
org.apache.shardingsphere.proxy.config.util.DataSourceParameterConverter;
-import 
org.apache.shardingsphere.proxy.converter.AddResourcesStatementConverter;
+import org.apache.shardingsphere.proxy.converter.ResourceSegmentsConverter;
 
 import java.util.ArrayList;
 import java.util.Collection;
@@ -61,7 +61,7 @@ public final class AddResourceBackendHandler extends 
SchemaRequiredBackendHandle
     public ResponseHeader execute(final String schemaName, final 
AddResourceStatement sqlStatement) throws DistSQLException {
         check(schemaName, sqlStatement);
         Map<String, DataSourceConfiguration> dataSourceConfigs = 
DataSourceParameterConverter.getDataSourceConfigurationMap(
-                
DataSourceParameterConverter.getDataSourceParameterMapFromYamlConfiguration(AddResourcesStatementConverter.convert(databaseType,
 sqlStatement)));
+                
DataSourceParameterConverter.getDataSourceParameterMapFromYamlConfiguration(ResourceSegmentsConverter.convert(databaseType,
 sqlStatement.getDataSources())));
         Collection<String> invalidDataSourceNames = 
dataSourceConfigs.entrySet()
                 .stream().filter(entry -> 
!dataSourceValidator.validate(entry.getValue())).map(Entry::getKey).collect(Collectors.toList());
         if (!invalidDataSourceNames.isEmpty()) {
diff --git 
a/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/text/distsql/rdl/resource/AddResourceBackendHandler.java
 
b/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/text/distsql/rdl/resource/AlterResourceBackendHandler.java
similarity index 53%
copy from 
shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/text/distsql/rdl/resource/AddResourceBackendHandler.java
copy to 
shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/text/distsql/rdl/resource/AlterResourceBackendHandler.java
index 778a6e4..eef6ec9 100644
--- 
a/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/text/distsql/rdl/resource/AddResourceBackendHandler.java
+++ 
b/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/text/distsql/rdl/resource/AlterResourceBackendHandler.java
@@ -18,72 +18,90 @@
 package org.apache.shardingsphere.proxy.backend.text.distsql.rdl.resource;
 
 import org.apache.shardingsphere.distsql.parser.segment.DataSourceSegment;
-import 
org.apache.shardingsphere.distsql.parser.statement.rdl.create.AddResourceStatement;
+import 
org.apache.shardingsphere.distsql.parser.statement.rdl.alter.AlterResourceStatement;
 import 
org.apache.shardingsphere.infra.config.datasource.DataSourceConfiguration;
 import org.apache.shardingsphere.infra.config.datasource.DataSourceValidator;
 import org.apache.shardingsphere.infra.database.type.DatabaseType;
 import org.apache.shardingsphere.infra.distsql.exception.DistSQLException;
 import 
org.apache.shardingsphere.infra.distsql.exception.resource.DuplicateResourceException;
 import 
org.apache.shardingsphere.infra.distsql.exception.resource.InvalidResourceException;
+import 
org.apache.shardingsphere.infra.distsql.exception.resource.RequiredResourceMissedException;
+import 
org.apache.shardingsphere.infra.distsql.exception.resource.ResourceInUsedException;
 import 
org.apache.shardingsphere.proxy.backend.communication.jdbc.connection.BackendConnection;
 import org.apache.shardingsphere.proxy.backend.context.ProxyContext;
 import org.apache.shardingsphere.proxy.backend.response.header.ResponseHeader;
 import 
org.apache.shardingsphere.proxy.backend.response.header.update.UpdateResponseHeader;
 import 
org.apache.shardingsphere.proxy.backend.text.SchemaRequiredBackendHandler;
 import 
org.apache.shardingsphere.proxy.config.util.DataSourceParameterConverter;
-import 
org.apache.shardingsphere.proxy.converter.AddResourcesStatementConverter;
+import org.apache.shardingsphere.proxy.converter.ResourceSegmentsConverter;
 
-import java.util.ArrayList;
+import javax.sql.DataSource;
 import java.util.Collection;
-import java.util.HashSet;
-import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
-import java.util.Set;
 import java.util.stream.Collectors;
 
 /**
- * Add resource backend handler.
+ * Alter resource backend handler.
  */
-public final class AddResourceBackendHandler extends 
SchemaRequiredBackendHandler<AddResourceStatement> {
+public final class AlterResourceBackendHandler extends 
SchemaRequiredBackendHandler<AlterResourceStatement> {
     
     private final DatabaseType databaseType;
     
     private final DataSourceValidator dataSourceValidator;
     
-    public AddResourceBackendHandler(final DatabaseType databaseType, final 
AddResourceStatement sqlStatement, final BackendConnection backendConnection) {
+    public AlterResourceBackendHandler(final DatabaseType databaseType, final 
AlterResourceStatement sqlStatement, final BackendConnection backendConnection) 
{
         super(sqlStatement, backendConnection);
         this.databaseType = databaseType;
         dataSourceValidator = new DataSourceValidator();
     }
     
     @Override
-    public ResponseHeader execute(final String schemaName, final 
AddResourceStatement sqlStatement) throws DistSQLException {
+    public ResponseHeader execute(final String schemaName, final 
AlterResourceStatement sqlStatement) throws DistSQLException {
         check(schemaName, sqlStatement);
         Map<String, DataSourceConfiguration> dataSourceConfigs = 
DataSourceParameterConverter.getDataSourceConfigurationMap(
-                
DataSourceParameterConverter.getDataSourceParameterMapFromYamlConfiguration(AddResourcesStatementConverter.convert(databaseType,
 sqlStatement)));
+                
DataSourceParameterConverter.getDataSourceParameterMapFromYamlConfiguration(ResourceSegmentsConverter.convert(databaseType,
 sqlStatement.getDataSources())));
+        validate(dataSourceConfigs);
+        // TODO update meta data context in memory
+        ProxyContext.getInstance().getContextManager()
+                .getMetaDataContexts().getPersistService().ifPresent(optional 
-> optional.getDataSourceService().append(schemaName, dataSourceConfigs));
+        return new UpdateResponseHeader(sqlStatement);
+    }
+    
+    private void check(final String schemaName, final AlterResourceStatement 
sqlStatement) throws DuplicateResourceException, 
RequiredResourceMissedException, ResourceInUsedException {
+        Collection<String> toBeAlteredResourceNames = 
getToBeAlteredResourceNames(sqlStatement);
+        checkToBeAlteredDuplicateResourceNames(toBeAlteredResourceNames);
+        checkResourceNameExisted(schemaName, toBeAlteredResourceNames);
+    }
+    
+    private void validate(final Map<String, DataSourceConfiguration> 
dataSourceConfigs) throws InvalidResourceException {
         Collection<String> invalidDataSourceNames = 
dataSourceConfigs.entrySet()
                 .stream().filter(entry -> 
!dataSourceValidator.validate(entry.getValue())).map(Entry::getKey).collect(Collectors.toList());
         if (!invalidDataSourceNames.isEmpty()) {
             throw new InvalidResourceException(invalidDataSourceNames);
         }
-        // TODO update meta data context in memory
-        ProxyContext.getInstance().getContextManager()
-                .getMetaDataContexts().getPersistService().ifPresent(optional 
-> optional.getDataSourceService().append(schemaName, dataSourceConfigs));
-        return new UpdateResponseHeader(sqlStatement);
     }
     
-    private void check(final String schemaName, final AddResourceStatement 
sqlStatement) throws DuplicateResourceException {
-        List<String> dataSourceNames = new 
ArrayList<>(sqlStatement.getDataSources().size());
-        Set<String> duplicateDataSourceNames = new 
HashSet<>(sqlStatement.getDataSources().size(), 1);
-        for (DataSourceSegment each : sqlStatement.getDataSources()) {
-            if (dataSourceNames.contains(each.getName()) || 
ProxyContext.getInstance().getMetaData(schemaName).getResource().getDataSources().containsKey(each.getName()))
 {
-                duplicateDataSourceNames.add(each.getName());
-            }
-            dataSourceNames.add(each.getName());
+    private Collection<String> getToBeAlteredResourceNames(final 
AlterResourceStatement sqlStatement) {
+        return 
sqlStatement.getDataSources().stream().map(DataSourceSegment::getName).collect(Collectors.toList());
+    }
+    
+    private void checkToBeAlteredDuplicateResourceNames(final 
Collection<String> resourceNames) throws DuplicateResourceException {
+        Collection<String> duplicateResourceNames = 
getDuplicateResourceNames(resourceNames);
+        if (!duplicateResourceNames.isEmpty()) {
+            throw new DuplicateResourceException(duplicateResourceNames);
         }
-        if (!duplicateDataSourceNames.isEmpty()) {
-            throw new DuplicateResourceException(duplicateDataSourceNames);
+    }
+    
+    private Collection<String> getDuplicateResourceNames(final 
Collection<String> resourceNames) {
+        return resourceNames.stream().filter(each -> 
resourceNames.stream().filter(origin -> each.equals(origin)).count() > 
1).collect(Collectors.toList());
+    }
+    
+    private void checkResourceNameExisted(final String schemaName, final 
Collection<String> resourceNames) throws RequiredResourceMissedException {
+        Map<String, DataSource> resources = 
ProxyContext.getInstance().getMetaData(schemaName).getResource().getDataSources();
+        Collection<String> notExistedResourceNames = 
resourceNames.stream().filter(each -> 
!resources.containsKey(each)).collect(Collectors.toList());
+        if (!notExistedResourceNames.isEmpty()) {
+            throw new RequiredResourceMissedException(schemaName, 
notExistedResourceNames);
         }
     }
 }
diff --git 
a/shardingsphere-proxy/shardingsphere-proxy-backend/src/test/java/org/apache/shardingsphere/proxy/backend/text/distsql/DistSQLBackendHandlerFactoryTest.java
 
b/shardingsphere-proxy/shardingsphere-proxy-backend/src/test/java/org/apache/shardingsphere/proxy/backend/text/distsql/DistSQLBackendHandlerFactoryTest.java
index 7e6a779..5c4a45a 100644
--- 
a/shardingsphere-proxy/shardingsphere-proxy-backend/src/test/java/org/apache/shardingsphere/proxy/backend/text/distsql/DistSQLBackendHandlerFactoryTest.java
+++ 
b/shardingsphere-proxy/shardingsphere-proxy-backend/src/test/java/org/apache/shardingsphere/proxy/backend/text/distsql/DistSQLBackendHandlerFactoryTest.java
@@ -18,6 +18,7 @@
 package org.apache.shardingsphere.proxy.backend.text.distsql;
 
 import 
org.apache.shardingsphere.distsql.parser.statement.rdl.RuleDefinitionStatement;
+import 
org.apache.shardingsphere.distsql.parser.statement.rdl.alter.AlterResourceStatement;
 import 
org.apache.shardingsphere.distsql.parser.statement.rdl.create.AddResourceStatement;
 import 
org.apache.shardingsphere.distsql.parser.statement.rdl.drop.DropResourceStatement;
 import 
org.apache.shardingsphere.distsql.parser.statement.rql.show.ShowResourcesStatement;
@@ -112,6 +113,34 @@ public final class DistSQLBackendHandlerFactoryTest {
     }
     
     @Test
+    public void assertExecuteAddResourceContext() throws SQLException {
+        BackendConnection connection = mock(BackendConnection.class);
+        when(connection.getSchemaName()).thenReturn("schema");
+        try {
+            RDLBackendHandlerFactory.newInstance(new MySQLDatabaseType(), 
mock(AddResourceStatement.class), connection);
+        } catch (final SQLException ex) {
+            assertThat(ex.getMessage(), is("No Registry center to execute 
`AddResourceStatement` SQL"));
+        }
+        setContextManager(true);
+        ResponseHeader response = RDLBackendHandlerFactory.newInstance(new 
MySQLDatabaseType(), mock(AddResourceStatement.class), connection).execute();
+        assertThat(response, instanceOf(UpdateResponseHeader.class));
+    }
+    
+    @Test
+    public void assertExecuteAlterResourceContext() throws SQLException {
+        BackendConnection connection = mock(BackendConnection.class);
+        when(connection.getSchemaName()).thenReturn("schema");
+        try {
+            RDLBackendHandlerFactory.newInstance(new MySQLDatabaseType(), 
mock(AlterResourceStatement.class), connection);
+        } catch (final SQLException ex) {
+            assertThat(ex.getMessage(), is("No Registry center to execute 
`AlterResourceStatement` SQL"));
+        }
+        setContextManager(true);
+        ResponseHeader response = RDLBackendHandlerFactory.newInstance(new 
MySQLDatabaseType(), mock(AlterResourceStatement.class), connection).execute();
+        assertThat(response, instanceOf(UpdateResponseHeader.class));
+    }
+    
+    @Test
     public void assertExecuteShadowRuleContext() throws SQLException {
         BackendConnection connection = mock(BackendConnection.class);
         when(connection.getSchemaName()).thenReturn("schema");
diff --git 
a/shardingsphere-proxy/shardingsphere-proxy-backend/src/test/java/org/apache/shardingsphere/proxy/backend/text/distsql/rdl/resource/AddResourceBackendHandlerTest.java
 
b/shardingsphere-proxy/shardingsphere-proxy-backend/src/test/java/org/apache/shardingsphere/proxy/backend/text/distsql/rdl/resource/AddResourceBackendHandlerTest.java
index 934e677..4ad14b6 100644
--- 
a/shardingsphere-proxy/shardingsphere-proxy-backend/src/test/java/org/apache/shardingsphere/proxy/backend/text/distsql/rdl/resource/AddResourceBackendHandlerTest.java
+++ 
b/shardingsphere-proxy/shardingsphere-proxy-backend/src/test/java/org/apache/shardingsphere/proxy/backend/text/distsql/rdl/resource/AddResourceBackendHandlerTest.java
@@ -21,6 +21,7 @@ import 
org.apache.shardingsphere.distsql.parser.segment.DataSourceSegment;
 import 
org.apache.shardingsphere.distsql.parser.statement.rdl.create.AddResourceStatement;
 import 
org.apache.shardingsphere.infra.config.datasource.DataSourceConfiguration;
 import org.apache.shardingsphere.infra.config.datasource.DataSourceValidator;
+import 
org.apache.shardingsphere.infra.distsql.exception.resource.DuplicateResourceException;
 import org.apache.shardingsphere.mode.manager.ContextManager;
 import org.apache.shardingsphere.mode.metadata.MetaDataContexts;
 import org.apache.shardingsphere.infra.database.type.dialect.MySQLDatabaseType;
@@ -40,6 +41,8 @@ import org.mockito.junit.MockitoJUnitRunner;
 
 import java.lang.reflect.Field;
 import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
 import java.util.Properties;
 
 import static org.junit.Assert.assertTrue;
@@ -84,16 +87,35 @@ public final class AddResourceBackendHandlerTest {
         ContextManager contextManager = mock(ContextManager.class, 
RETURNS_DEEP_STUBS);
         
when(contextManager.getMetaDataContexts()).thenReturn(metaDataContexts);
         ProxyContext.getInstance().init(contextManager);
-        
when(metaDataContexts.getAllSchemaNames()).thenReturn(Collections.singleton("test"));
-        when(metaDataContexts.getMetaData("test")).thenReturn(metaData);
+        
when(metaDataContexts.getAllSchemaNames()).thenReturn(Collections.singleton("test_schema"));
+        when(metaDataContexts.getMetaData("test_schema")).thenReturn(metaData);
         when(metaData.getResource()).thenReturn(resource);
         when(resource.getDataSources()).thenReturn(Collections.emptyMap());
         
when(dataSourceValidator.validate(any(DataSourceConfiguration.class))).thenReturn(true);
-        ResponseHeader responseHeader = 
addResourceBackendHandler.execute("test", createAddResourceStatement());
+        ResponseHeader responseHeader = 
addResourceBackendHandler.execute("test_schema", createAddResourceStatement());
         assertTrue(responseHeader instanceof UpdateResponseHeader);
     }
     
+    @Test(expected = DuplicateResourceException.class)
+    public void assertExecuteWithDuplicateResourceNames() throws 
DistSQLException {
+        ContextManager contextManager = mock(ContextManager.class, 
RETURNS_DEEP_STUBS);
+        
when(contextManager.getMetaDataContexts()).thenReturn(metaDataContexts);
+        ProxyContext.getInstance().init(contextManager);
+        
when(metaDataContexts.getAllSchemaNames()).thenReturn(Collections.singleton("test_schema"));
+        when(metaDataContexts.getMetaData("test_schema")).thenReturn(metaData);
+        when(metaData.getResource()).thenReturn(resource);
+        when(resource.getDataSources()).thenReturn(Collections.emptyMap());
+        addResourceBackendHandler.execute("test_schema", 
createAlterResourceStatementWithDuplicateResourceNames());
+    }
+    
     private AddResourceStatement createAddResourceStatement() {
         return new AddResourceStatement(Collections.singleton(new 
DataSourceSegment("ds_0", "jdbc:mysql://127.0.0.1:3306/test0", null, null, 
null, "root", "", new Properties())));
     }
+    
+    private AddResourceStatement 
createAlterResourceStatementWithDuplicateResourceNames() {
+        List<DataSourceSegment> result = new LinkedList<>();
+        result.add(new DataSourceSegment("ds_0", 
"jdbc:mysql://127.0.0.1:3306/ds_0", null, null, null, "root", "", new 
Properties()));
+        result.add(new DataSourceSegment("ds_0", 
"jdbc:mysql://127.0.0.1:3306/ds_1", null, null, null, "root", "", new 
Properties()));
+        return new AddResourceStatement(result);
+    }
 }
diff --git 
a/shardingsphere-proxy/shardingsphere-proxy-backend/src/test/java/org/apache/shardingsphere/proxy/backend/text/distsql/rdl/resource/AddResourceBackendHandlerTest.java
 
b/shardingsphere-proxy/shardingsphere-proxy-backend/src/test/java/org/apache/shardingsphere/proxy/backend/text/distsql/rdl/resource/AlterResourceBackendHandlerTest.java
similarity index 52%
copy from 
shardingsphere-proxy/shardingsphere-proxy-backend/src/test/java/org/apache/shardingsphere/proxy/backend/text/distsql/rdl/resource/AddResourceBackendHandlerTest.java
copy to 
shardingsphere-proxy/shardingsphere-proxy-backend/src/test/java/org/apache/shardingsphere/proxy/backend/text/distsql/rdl/resource/AlterResourceBackendHandlerTest.java
index 934e677..b3dcd81 100644
--- 
a/shardingsphere-proxy/shardingsphere-proxy-backend/src/test/java/org/apache/shardingsphere/proxy/backend/text/distsql/rdl/resource/AddResourceBackendHandlerTest.java
+++ 
b/shardingsphere-proxy/shardingsphere-proxy-backend/src/test/java/org/apache/shardingsphere/proxy/backend/text/distsql/rdl/resource/AlterResourceBackendHandlerTest.java
@@ -18,15 +18,17 @@
 package org.apache.shardingsphere.proxy.backend.text.distsql.rdl.resource;
 
 import org.apache.shardingsphere.distsql.parser.segment.DataSourceSegment;
-import 
org.apache.shardingsphere.distsql.parser.statement.rdl.create.AddResourceStatement;
+import 
org.apache.shardingsphere.distsql.parser.statement.rdl.alter.AlterResourceStatement;
 import 
org.apache.shardingsphere.infra.config.datasource.DataSourceConfiguration;
 import org.apache.shardingsphere.infra.config.datasource.DataSourceValidator;
-import org.apache.shardingsphere.mode.manager.ContextManager;
-import org.apache.shardingsphere.mode.metadata.MetaDataContexts;
 import org.apache.shardingsphere.infra.database.type.dialect.MySQLDatabaseType;
 import org.apache.shardingsphere.infra.distsql.exception.DistSQLException;
+import 
org.apache.shardingsphere.infra.distsql.exception.resource.DuplicateResourceException;
+import 
org.apache.shardingsphere.infra.distsql.exception.resource.RequiredResourceMissedException;
 import org.apache.shardingsphere.infra.metadata.ShardingSphereMetaData;
 import 
org.apache.shardingsphere.infra.metadata.resource.ShardingSphereResource;
+import org.apache.shardingsphere.mode.manager.ContextManager;
+import org.apache.shardingsphere.mode.metadata.MetaDataContexts;
 import 
org.apache.shardingsphere.proxy.backend.communication.jdbc.connection.BackendConnection;
 import org.apache.shardingsphere.proxy.backend.context.ProxyContext;
 import org.apache.shardingsphere.proxy.backend.response.header.ResponseHeader;
@@ -38,8 +40,11 @@ import org.mockito.Answers;
 import org.mockito.Mock;
 import org.mockito.junit.MockitoJUnitRunner;
 
+import javax.sql.DataSource;
 import java.lang.reflect.Field;
 import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
 import java.util.Properties;
 
 import static org.junit.Assert.assertTrue;
@@ -49,13 +54,13 @@ import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
 @RunWith(MockitoJUnitRunner.class)
-public final class AddResourceBackendHandlerTest {
+public final class AlterResourceBackendHandlerTest {
     
     @Mock
     private DataSourceValidator dataSourceValidator;
     
     @Mock
-    private AddResourceStatement addResourceStatement;
+    private AlterResourceStatement alterResourceStatement;
     
     @Mock
     private BackendConnection backendConnection;
@@ -69,14 +74,17 @@ public final class AddResourceBackendHandlerTest {
     @Mock
     private ShardingSphereResource resource;
     
-    private AddResourceBackendHandler addResourceBackendHandler;
+    @Mock
+    private DataSource dataSource;
+    
+    private AlterResourceBackendHandler alterResourceBackendHandler;
     
     @Before
     public void setUp() throws Exception {
-        addResourceBackendHandler = new AddResourceBackendHandler(new 
MySQLDatabaseType(), addResourceStatement, backendConnection);
-        Field field = 
addResourceBackendHandler.getClass().getDeclaredField("dataSourceValidator");
+        alterResourceBackendHandler = new AlterResourceBackendHandler(new 
MySQLDatabaseType(), alterResourceStatement, backendConnection);
+        Field field = 
alterResourceBackendHandler.getClass().getDeclaredField("dataSourceValidator");
         field.setAccessible(true);
-        field.set(addResourceBackendHandler, dataSourceValidator);
+        field.set(alterResourceBackendHandler, dataSourceValidator);
     }
     
     @Test
@@ -84,16 +92,40 @@ public final class AddResourceBackendHandlerTest {
         ContextManager contextManager = mock(ContextManager.class, 
RETURNS_DEEP_STUBS);
         
when(contextManager.getMetaDataContexts()).thenReturn(metaDataContexts);
         ProxyContext.getInstance().init(contextManager);
-        
when(metaDataContexts.getAllSchemaNames()).thenReturn(Collections.singleton("test"));
-        when(metaDataContexts.getMetaData("test")).thenReturn(metaData);
+        
when(metaDataContexts.getAllSchemaNames()).thenReturn(Collections.singleton("test_schema"));
+        when(metaDataContexts.getMetaData("test_schema")).thenReturn(metaData);
         when(metaData.getResource()).thenReturn(resource);
-        when(resource.getDataSources()).thenReturn(Collections.emptyMap());
+        
when(resource.getDataSources()).thenReturn(Collections.singletonMap("ds_0", 
dataSource));
         
when(dataSourceValidator.validate(any(DataSourceConfiguration.class))).thenReturn(true);
-        ResponseHeader responseHeader = 
addResourceBackendHandler.execute("test", createAddResourceStatement());
+        ResponseHeader responseHeader = 
alterResourceBackendHandler.execute("test_schema", 
createAlterResourceStatement("ds_0"));
         assertTrue(responseHeader instanceof UpdateResponseHeader);
     }
     
-    private AddResourceStatement createAddResourceStatement() {
-        return new AddResourceStatement(Collections.singleton(new 
DataSourceSegment("ds_0", "jdbc:mysql://127.0.0.1:3306/test0", null, null, 
null, "root", "", new Properties())));
+    @Test(expected = DuplicateResourceException.class)
+    public void assertExecuteWithDuplicateResourceNames() throws 
DistSQLException {
+        alterResourceBackendHandler.execute("test_schema", 
createAlterResourceStatementWithDuplicateResourceNames());
+    }
+    
+    @Test(expected = RequiredResourceMissedException.class)
+    public void assertExecuteWithNotExistedResourceNames() throws 
DistSQLException {
+        ContextManager contextManager = mock(ContextManager.class, 
RETURNS_DEEP_STUBS);
+        
when(contextManager.getMetaDataContexts()).thenReturn(metaDataContexts);
+        ProxyContext.getInstance().init(contextManager);
+        
when(metaDataContexts.getAllSchemaNames()).thenReturn(Collections.singleton("test_schema"));
+        when(metaDataContexts.getMetaData("test_schema")).thenReturn(metaData);
+        when(metaData.getResource()).thenReturn(resource);
+        
when(resource.getDataSources()).thenReturn(Collections.singletonMap("ds_0", 
dataSource));
+        alterResourceBackendHandler.execute("test_schema", 
createAlterResourceStatement("not_existed"));
+    }
+    
+    private AlterResourceStatement createAlterResourceStatement(final String 
resourceName) {
+        return new AlterResourceStatement(Collections.singleton(new 
DataSourceSegment(resourceName, "jdbc:mysql://127.0.0.1:3306/ds_0", null, null, 
null, "root", "", new Properties())));
+    }
+    
+    private AlterResourceStatement 
createAlterResourceStatementWithDuplicateResourceNames() {
+        List<DataSourceSegment> result = new LinkedList<>();
+        result.add(new DataSourceSegment("ds_0", 
"jdbc:mysql://127.0.0.1:3306/ds_0", null, null, null, "root", "", new 
Properties()));
+        result.add(new DataSourceSegment("ds_0", 
"jdbc:mysql://127.0.0.1:3306/ds_1", null, null, null, "root", "", new 
Properties()));
+        return new AlterResourceStatement(result);
     }
 }
diff --git 
a/shardingsphere-proxy/shardingsphere-proxy-common/src/main/java/org/apache/shardingsphere/proxy/converter/AddResourcesStatementConverter.java
 
b/shardingsphere-proxy/shardingsphere-proxy-common/src/main/java/org/apache/shardingsphere/proxy/converter/ResourceSegmentsConverter.java
similarity index 85%
rename from 
shardingsphere-proxy/shardingsphere-proxy-common/src/main/java/org/apache/shardingsphere/proxy/converter/AddResourcesStatementConverter.java
rename to 
shardingsphere-proxy/shardingsphere-proxy-common/src/main/java/org/apache/shardingsphere/proxy/converter/ResourceSegmentsConverter.java
index bba66d5..11d53e7 100644
--- 
a/shardingsphere-proxy/shardingsphere-proxy-common/src/main/java/org/apache/shardingsphere/proxy/converter/AddResourcesStatementConverter.java
+++ 
b/shardingsphere-proxy/shardingsphere-proxy-common/src/main/java/org/apache/shardingsphere/proxy/converter/ResourceSegmentsConverter.java
@@ -20,30 +20,30 @@ package org.apache.shardingsphere.proxy.converter;
 import lombok.AccessLevel;
 import lombok.NoArgsConstructor;
 import org.apache.shardingsphere.distsql.parser.segment.DataSourceSegment;
-import 
org.apache.shardingsphere.distsql.parser.statement.rdl.create.AddResourceStatement;
 import org.apache.shardingsphere.infra.config.datasource.DataSourceParameter;
 import org.apache.shardingsphere.infra.database.type.DatabaseType;
 import org.apache.shardingsphere.proxy.config.yaml.YamlDataSourceParameter;
 
+import java.util.Collection;
 import java.util.LinkedHashMap;
 import java.util.Map;
 
 /**
- * Add resource statement converter.
+ * Resource segments converter.
  */
 @NoArgsConstructor(access = AccessLevel.PRIVATE)
-public final class AddResourcesStatementConverter {
+public final class ResourceSegmentsConverter {
     
     /**
-     * Convert add resource statement to YAML data source parameter map.
+     * Convert resource segments to YAML data source parameter map.
      *
      * @param databaseType database type
-     * @param sqlStatement add resource statement
+     * @param resources data source segments
      * @return YAML data source parameter map
      */
-    public static Map<String, YamlDataSourceParameter> convert(final 
DatabaseType databaseType, final AddResourceStatement sqlStatement) {
-        Map<String, YamlDataSourceParameter> result = new 
LinkedHashMap<>(sqlStatement.getDataSources().size(), 1);
-        for (DataSourceSegment each : sqlStatement.getDataSources()) {
+    public static Map<String, YamlDataSourceParameter> convert(final 
DatabaseType databaseType, final Collection<DataSourceSegment> resources) {
+        Map<String, YamlDataSourceParameter> result = new 
LinkedHashMap<>(resources.size(), 1);
+        for (DataSourceSegment each : resources) {
             DataSourceParameter parameter = new DataSourceParameter();
             YamlDataSourceParameter dataSource = new YamlDataSourceParameter();
             dataSource.setUrl(getURL(databaseType, each));
diff --git 
a/shardingsphere-proxy/shardingsphere-proxy-common/src/test/java/org/apache/shardingsphere/proxy/converter/AddResourcesStatementConverterTest.java
 
b/shardingsphere-proxy/shardingsphere-proxy-common/src/test/java/org/apache/shardingsphere/proxy/converter/ResourceSegmentsConverterTest.java
similarity index 87%
rename from 
shardingsphere-proxy/shardingsphere-proxy-common/src/test/java/org/apache/shardingsphere/proxy/converter/AddResourcesStatementConverterTest.java
rename to 
shardingsphere-proxy/shardingsphere-proxy-common/src/test/java/org/apache/shardingsphere/proxy/converter/ResourceSegmentsConverterTest.java
index 5451c0c..9f423cd 100644
--- 
a/shardingsphere-proxy/shardingsphere-proxy-common/src/test/java/org/apache/shardingsphere/proxy/converter/AddResourcesStatementConverterTest.java
+++ 
b/shardingsphere-proxy/shardingsphere-proxy-common/src/test/java/org/apache/shardingsphere/proxy/converter/ResourceSegmentsConverterTest.java
@@ -18,7 +18,6 @@
 package org.apache.shardingsphere.proxy.converter;
 
 import org.apache.shardingsphere.distsql.parser.segment.DataSourceSegment;
-import 
org.apache.shardingsphere.distsql.parser.statement.rdl.create.AddResourceStatement;
 import org.apache.shardingsphere.infra.database.type.dialect.MySQLDatabaseType;
 import org.apache.shardingsphere.proxy.config.yaml.YamlDataSourceParameter;
 import org.junit.Test;
@@ -33,11 +32,11 @@ import static org.hamcrest.CoreMatchers.is;
 import static org.junit.Assert.assertThat;
 import static org.junit.Assert.assertTrue;
 
-public final class AddResourcesStatementConverterTest {
+public final class ResourceSegmentsConverterTest {
     
     @Test
     public void assertConvert() {
-        Map<String, YamlDataSourceParameter> actual = 
AddResourcesStatementConverter.convert(new MySQLDatabaseType(), new 
AddResourceStatement(createDataSourceSegments()));
+        Map<String, YamlDataSourceParameter> actual = 
ResourceSegmentsConverter.convert(new MySQLDatabaseType(), 
createDataSourceSegments());
         assertThat(actual.size(), is(2));
         assertTrue(actual.keySet().containsAll(Arrays.asList("ds0", "ds1")));
         assertThat(actual.values().iterator().next().getUsername(), 
is("root0"));
diff --git 
a/shardingsphere-test/shardingsphere-parser-test/src/main/java/org/apache/shardingsphere/test/sql/parser/parameterized/asserts/statement/distsql/rdl/RDLStatementAssert.java
 
b/shardingsphere-test/shardingsphere-parser-test/src/main/java/org/apache/shardingsphere/test/sql/parser/parameterized/asserts/statement/distsql/rdl/RDLStatementAssert.java
index 6b1476c..76c9e32 100644
--- 
a/shardingsphere-test/shardingsphere-parser-test/src/main/java/org/apache/shardingsphere/test/sql/parser/parameterized/asserts/statement/distsql/rdl/RDLStatementAssert.java
+++ 
b/shardingsphere-test/shardingsphere-parser-test/src/main/java/org/apache/shardingsphere/test/sql/parser/parameterized/asserts/statement/distsql/rdl/RDLStatementAssert.java
@@ -21,6 +21,7 @@ import lombok.AccessLevel;
 import lombok.NoArgsConstructor;
 import 
org.apache.shardingsphere.dbdiscovery.distsql.parser.statement.AlterDatabaseDiscoveryRuleStatement;
 import org.apache.shardingsphere.distsql.parser.statement.rdl.RDLStatement;
+import 
org.apache.shardingsphere.distsql.parser.statement.rdl.alter.AlterResourceStatement;
 import 
org.apache.shardingsphere.distsql.parser.statement.rdl.alter.AlterRuleStatement;
 import 
org.apache.shardingsphere.distsql.parser.statement.rdl.create.AddResourceStatement;
 import 
org.apache.shardingsphere.distsql.parser.statement.rdl.create.CreateRuleStatement;
@@ -32,6 +33,7 @@ import 
org.apache.shardingsphere.sharding.distsql.parser.statement.AlterSharding
 import 
org.apache.shardingsphere.sharding.distsql.parser.statement.AlterShardingBroadcastTableRulesStatement;
 import 
org.apache.shardingsphere.sharding.distsql.parser.statement.AlterShardingTableRuleStatement;
 import 
org.apache.shardingsphere.test.sql.parser.parameterized.asserts.SQLCaseAssertContext;
+import 
org.apache.shardingsphere.test.sql.parser.parameterized.asserts.statement.distsql.rdl.alter.AlterResourceStatementAssert;
 import 
org.apache.shardingsphere.test.sql.parser.parameterized.asserts.statement.distsql.rdl.alter.AlterRuleStatementAssert;
 import 
org.apache.shardingsphere.test.sql.parser.parameterized.asserts.statement.distsql.rdl.alter.impl.AlterDatabaseDiscoveryRuleStatementAssert;
 import 
org.apache.shardingsphere.test.sql.parser.parameterized.asserts.statement.distsql.rdl.alter.impl.AlterEncryptRuleStatementAssert;
@@ -47,6 +49,7 @@ import 
org.apache.shardingsphere.test.sql.parser.parameterized.jaxb.cases.domain
 import 
org.apache.shardingsphere.test.sql.parser.parameterized.jaxb.cases.domain.statement.distsql.rdl.alter.AlterDataBaseDiscoveryRuleStatementTestCase;
 import 
org.apache.shardingsphere.test.sql.parser.parameterized.jaxb.cases.domain.statement.distsql.rdl.alter.AlterEncryptRuleStatementTestCase;
 import 
org.apache.shardingsphere.test.sql.parser.parameterized.jaxb.cases.domain.statement.distsql.rdl.alter.AlterReadWriteSplittingRuleStatementTestCase;
+import 
org.apache.shardingsphere.test.sql.parser.parameterized.jaxb.cases.domain.statement.distsql.rdl.alter.AlterResourceStatementTestCase;
 import 
org.apache.shardingsphere.test.sql.parser.parameterized.jaxb.cases.domain.statement.distsql.rdl.alter.AlterShardingBindingTableRulesStatementTestCase;
 import 
org.apache.shardingsphere.test.sql.parser.parameterized.jaxb.cases.domain.statement.distsql.rdl.alter.AlterShardingBroadcastTableRulesStatementTestCase;
 import 
org.apache.shardingsphere.test.sql.parser.parameterized.jaxb.cases.domain.statement.distsql.rdl.alter.AlterShardingTableRuleStatementTestCase;
@@ -83,6 +86,8 @@ public final class RDLStatementAssert {
             CreateRuleStatementAssert.assertIs(assertContext, 
(CreateRuleStatement) actual, expected);
         } else if (actual instanceof AddResourceStatement) {
             AddResourceStatementAssert.assertIs(assertContext, 
(AddResourceStatement) actual, (AddResourceStatementTestCase) expected);
+        } else if (actual instanceof AlterResourceStatement) {
+            AlterResourceStatementAssert.assertIs(assertContext, 
(AlterResourceStatement) actual, (AlterResourceStatementTestCase) expected);
         } else if (actual instanceof AlterRuleStatement) {
             AlterRuleStatementAssert.assertIs(assertContext, 
(AlterRuleStatement) actual, expected);
         } else if (actual instanceof DropResourceStatement) {
diff --git 
a/shardingsphere-test/shardingsphere-parser-test/src/main/java/org/apache/shardingsphere/test/sql/parser/parameterized/asserts/statement/distsql/rdl/alter/AlterResourceStatementAssert.java
 
b/shardingsphere-test/shardingsphere-parser-test/src/main/java/org/apache/shardingsphere/test/sql/parser/parameterized/asserts/statement/distsql/rdl/alter/AlterResourceStatementAssert.java
new file mode 100644
index 0000000..1cbc7db
--- /dev/null
+++ 
b/shardingsphere-test/shardingsphere-parser-test/src/main/java/org/apache/shardingsphere/test/sql/parser/parameterized/asserts/statement/distsql/rdl/alter/AlterResourceStatementAssert.java
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package 
org.apache.shardingsphere.test.sql.parser.parameterized.asserts.statement.distsql.rdl.alter;
+
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+import org.apache.shardingsphere.distsql.parser.segment.DataSourceSegment;
+import 
org.apache.shardingsphere.distsql.parser.statement.rdl.alter.AlterResourceStatement;
+import 
org.apache.shardingsphere.test.sql.parser.parameterized.asserts.SQLCaseAssertContext;
+import 
org.apache.shardingsphere.test.sql.parser.parameterized.asserts.segment.distsql.DataSourceAssert;
+import 
org.apache.shardingsphere.test.sql.parser.parameterized.jaxb.cases.domain.segment.impl.distsql.ExpectedDataSource;
+import 
org.apache.shardingsphere.test.sql.parser.parameterized.jaxb.cases.domain.statement.distsql.rdl.alter.AlterResourceStatementTestCase;
+
+import java.util.Collection;
+import java.util.List;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertThat;
+
+/**
+ * Alter Resource statement assert.
+ */
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public final class AlterResourceStatementAssert {
+    
+    /**
+     * Assert alter resource statement is correct with expected parser result.
+     *
+     * @param assertContext assert context
+     * @param actual actual add resource statement
+     * @param expected expected add resource statement test case
+     */
+    public static void assertIs(final SQLCaseAssertContext assertContext, 
final AlterResourceStatement actual, final AlterResourceStatementTestCase 
expected) {
+        if (null == expected) {
+            assertNull(assertContext.getText("Actual statement should not 
exist."), actual);
+        } else {
+            assertNotNull(assertContext.getText("Actual statement should 
exist."), actual);
+            assertDataSources(assertContext, actual.getDataSources(), 
expected.getDataSources());
+        }
+    }
+    
+    private static void assertDataSources(final SQLCaseAssertContext 
assertContext, final Collection<DataSourceSegment> actual, final 
List<ExpectedDataSource> expected) {
+        if (null == expected) {
+            assertNull(assertContext.getText("Actual datasource should not 
exist."), actual);
+        } else {
+            assertNotNull(assertContext.getText("Actual datasource should 
exist."), actual);
+            assertThat(assertContext.getText(String.format("Actual datasource 
size should be %s , but it was %s", expected.size(), actual.size())), 
actual.size(), is(expected.size()));
+            int count = 0;
+            for (DataSourceSegment actualDataSource : actual) {
+                DataSourceAssert.assertIs(assertContext, actualDataSource, 
expected.get(count));
+                count++;
+            }
+        }
+    }
+}
diff --git 
a/shardingsphere-test/shardingsphere-parser-test/src/main/java/org/apache/shardingsphere/test/sql/parser/parameterized/jaxb/cases/domain/SQLParserTestCases.java
 
b/shardingsphere-test/shardingsphere-parser-test/src/main/java/org/apache/shardingsphere/test/sql/parser/parameterized/jaxb/cases/domain/SQLParserTestCases.java
index ef6e828..0453566 100644
--- 
a/shardingsphere-test/shardingsphere-parser-test/src/main/java/org/apache/shardingsphere/test/sql/parser/parameterized/jaxb/cases/domain/SQLParserTestCases.java
+++ 
b/shardingsphere-test/shardingsphere-parser-test/src/main/java/org/apache/shardingsphere/test/sql/parser/parameterized/jaxb/cases/domain/SQLParserTestCases.java
@@ -102,6 +102,7 @@ import 
org.apache.shardingsphere.test.sql.parser.parameterized.jaxb.cases.domain
 import 
org.apache.shardingsphere.test.sql.parser.parameterized.jaxb.cases.domain.statement.distsql.rdl.alter.AlterDataBaseDiscoveryRuleStatementTestCase;
 import 
org.apache.shardingsphere.test.sql.parser.parameterized.jaxb.cases.domain.statement.distsql.rdl.alter.AlterEncryptRuleStatementTestCase;
 import 
org.apache.shardingsphere.test.sql.parser.parameterized.jaxb.cases.domain.statement.distsql.rdl.alter.AlterReadWriteSplittingRuleStatementTestCase;
+import 
org.apache.shardingsphere.test.sql.parser.parameterized.jaxb.cases.domain.statement.distsql.rdl.alter.AlterResourceStatementTestCase;
 import 
org.apache.shardingsphere.test.sql.parser.parameterized.jaxb.cases.domain.statement.distsql.rdl.alter.AlterShardingBindingTableRulesStatementTestCase;
 import 
org.apache.shardingsphere.test.sql.parser.parameterized.jaxb.cases.domain.statement.distsql.rdl.alter.AlterShardingBroadcastTableRulesStatementTestCase;
 import 
org.apache.shardingsphere.test.sql.parser.parameterized.jaxb.cases.domain.statement.distsql.rdl.alter.AlterShardingTableRuleStatementTestCase;
@@ -401,6 +402,9 @@ public final class SQLParserTestCases {
     @XmlElement(name = "add-resource")
     private final List<AddResourceStatementTestCase> addResourceTestCase = new 
LinkedList<>();
     
+    @XmlElement(name = "alter-resource")
+    private final List<AlterResourceStatementTestCase> alterResourceTestCase = 
new LinkedList<>();
+    
     @XmlElement(name = "alter-database-discovery-rule")
     private final List<AlterDataBaseDiscoveryRuleStatementTestCase> 
alterDataBaseDiscoveryRuleTestCase = new LinkedList<>();
     
@@ -612,6 +616,7 @@ public final class SQLParserTestCases {
         putAll(purgeTestCase, result);
         putAll(renameTestCase, result);
         putAll(addResourceTestCase, result);
+        putAll(alterResourceTestCase, result);
         putAll(alterDataBaseDiscoveryRuleTestCase, result);
         putAll(alterEncryptRuleTestCase, result);
         putAll(alterReadWriteSplittingRuleTestCase, result);
diff --git 
a/shardingsphere-distsql-parser/shardingsphere-distsql-parser-engine/src/main/antlr4/imports/Keyword.g4
 
b/shardingsphere-test/shardingsphere-parser-test/src/main/java/org/apache/shardingsphere/test/sql/parser/parameterized/jaxb/cases/domain/statement/distsql/rdl/alter/AlterResourceStatementTestCase.java
similarity index 51%
copy from 
shardingsphere-distsql-parser/shardingsphere-distsql-parser-engine/src/main/antlr4/imports/Keyword.g4
copy to 
shardingsphere-test/shardingsphere-parser-test/src/main/java/org/apache/shardingsphere/test/sql/parser/parameterized/jaxb/cases/domain/statement/distsql/rdl/alter/AlterResourceStatementTestCase.java
index d9ba2a1..b959063 100644
--- 
a/shardingsphere-distsql-parser/shardingsphere-distsql-parser-engine/src/main/antlr4/imports/Keyword.g4
+++ 
b/shardingsphere-test/shardingsphere-parser-test/src/main/java/org/apache/shardingsphere/test/sql/parser/parameterized/jaxb/cases/domain/statement/distsql/rdl/alter/AlterResourceStatementTestCase.java
@@ -15,82 +15,24 @@
  * limitations under the License.
  */
 
-lexer grammar Keyword;
+package 
org.apache.shardingsphere.test.sql.parser.parameterized.jaxb.cases.domain.statement.distsql.rdl.alter;
 
-import Alphabet;
+import lombok.Getter;
+import lombok.Setter;
+import 
org.apache.shardingsphere.test.sql.parser.parameterized.jaxb.cases.domain.segment.impl.distsql.ExpectedDataSource;
+import 
org.apache.shardingsphere.test.sql.parser.parameterized.jaxb.cases.domain.statement.SQLParserTestCase;
 
-WS
-    : [ \t\r\n] + ->skip
-    ;
+import javax.xml.bind.annotation.XmlElement;
+import java.util.LinkedList;
+import java.util.List;
 
-ADD
-    : A D D
-    ;
-
-CLEAR
-    : C L E A R
-    ;
-
-DROP
-    : D R O P
-    ;
-
-SET
-    : S E T
-    ;
-
-SHOW
-    : S H O W
-    ;
-
-RESOURCE
-    : R E S O U R C E
-    ;
-
-RESOURCES
-    : R E S O U R C E S
-    ;
-
-FROM
-    : F R O M
-    ;
-
-URL
-    : U R L
-    ;
-
-HOST
-    : H O S T
-    ;
-
-PORT
-    : P O R T
-    ;
-
-DB
-    : D B
-    ;
-
-USER
-    : U S E R
-    ;
-
-PASSWORD
-    : P A S S W O R D
-    ;
-
-NAME
-    : N A M E
-    ;
-
-PROPERTIES
-    : P R O P E R T I E S
-    ;
-
-VARIABLE
-    : V A R I A B L E
-    ;
-
-HINT
-    : H I N T
-    ;
+/**
+ * Alter resource statement test case.
+ */
+@Getter
+@Setter
+public final class AlterResourceStatementTestCase extends SQLParserTestCase {
+    
+    @XmlElement(name = "data-source")
+    private final List<ExpectedDataSource> dataSources = new LinkedList<>();
+}
diff --git 
a/shardingsphere-test/shardingsphere-parser-test/src/main/resources/case/rdl/alter.xml
 
b/shardingsphere-test/shardingsphere-parser-test/src/main/resources/case/rdl/alter.xml
index 93d12f5..f430a63 100644
--- 
a/shardingsphere-test/shardingsphere-parser-test/src/main/resources/case/rdl/alter.xml
+++ 
b/shardingsphere-test/shardingsphere-parser-test/src/main/resources/case/rdl/alter.xml
@@ -17,6 +17,52 @@
   -->
 
 <sql-parser-test-cases>
+    <alter-resource 
sql-case-id="alter-resource-simple-single-without-password">
+        <data-source name="ds_0" host-name="127.0.0.1" port="3306" db="test0" 
user="ROOT" password=""/>
+    </alter-resource>
+
+    <alter-resource sql-case-id="alter-resource-simple-single-with-password">
+        <data-source name="ds_0" host-name="127.0.0.1" port="3306" db="test0" 
user="ROOT" password="123456"/>
+    </alter-resource>
+
+    <alter-resource sql-case-id="alter-resource-simple-multiple">
+        <data-source name="ds_0" host-name="127.0.0.1" port="3306" db="test0" 
user="ROOT" password="123456"/>
+        <data-source name="ds_1" host-name="127.0.0.1" port="3306" db="test1" 
user="ROOT" password="123456"/>
+    </alter-resource>
+
+    <alter-resource sql-case-id="alter-resource-url-single-without-password">
+        <data-source name="ds_0" url="jdbc:mysql://127.0.0.1:3306/test0" 
user="ROOT" password=""/>
+    </alter-resource>
+
+    <alter-resource sql-case-id="alter-resource-url-single-with-password">
+        <data-source name="ds_0" url="jdbc:mysql://127.0.0.1:3306/test0" 
user="ROOT" password="123456"/>
+    </alter-resource>
+
+    <alter-resource sql-case-id="alter-resource-url-multiple">
+        <data-source name="ds_0" url="jdbc:mysql://127.0.0.1:3306/test0" 
user="ROOT" password="123456"/>
+        <data-source name="ds_1" url="jdbc:mysql://127.0.0.1:3306/test1" 
user="ROOT" password="123456"/>
+    </alter-resource>
+
+    <alter-resource sql-case-id="alter-resource-single-with-properties">
+        <data-source name="ds_0" host-name="127.0.0.1" port="3306" db="test0" 
user="ROOT" password="123456">
+            <properties>
+                <property key="maxPoolSize" value="30"/>
+            </properties>
+        </data-source>
+    </alter-resource>
+
+    <alter-resource 
sql-case-id="alter-resource-url-single-with-empty-properties">
+        <data-source name="ds_0" url="jdbc:mysql://127.0.0.1:3306/test0" 
user="ROOT" password=""/>
+    </alter-resource>
+
+    <alter-resource sql-case-id="alter-resource-url-single-with-properties">
+        <data-source name="ds_0" url="jdbc:mysql://127.0.0.1:3306/test0" 
user="ROOT" password="123456">
+            <properties>
+                <property key="maxPoolSize" value="30"/>
+            </properties>
+        </data-source>
+    </alter-resource>
+    
     <alter-sharding-table-rule sql-case-id="alter-sharding-table-rule">
         <rule name="t_order" table-strategy-column="order_id" 
key-generate-strategy-column="another_id">
             <data-source>ms_group_0</data-source>
diff --git 
a/shardingsphere-test/shardingsphere-parser-test/src/main/resources/sql/supported/rdl/alter.xml
 
b/shardingsphere-test/shardingsphere-parser-test/src/main/resources/sql/supported/rdl/alter.xml
index 40198f0..3f93d32 100644
--- 
a/shardingsphere-test/shardingsphere-parser-test/src/main/resources/sql/supported/rdl/alter.xml
+++ 
b/shardingsphere-test/shardingsphere-parser-test/src/main/resources/sql/supported/rdl/alter.xml
@@ -17,6 +17,15 @@
   -->
 
 <sql-cases>
+    <distsql-case id="alter-resource-simple-single-without-password" 
value="ALTER RESOURCE ds_0(HOST=127.0.0.1,PORT=3306,DB=test0,USER=ROOT);" />
+    <distsql-case id="alter-resource-simple-single-with-password" value="ALTER 
RESOURCE ds_0(HOST=127.0.0.1,PORT=3306,DB=test0,USER=ROOT,PASSWORD=123456);" />
+    <distsql-case id="alter-resource-simple-multiple" value="ALTER RESOURCE 
ds_0(HOST=127.0.0.1,PORT=3306,DB=test0,USER=ROOT,PASSWORD=123456), 
ds_1(HOST=127.0.0.1,PORT=3306,DB=test1,USER=ROOT,PASSWORD=123456);" />
+    <distsql-case id="alter-resource-url-single-without-password" value="ALTER 
RESOURCE ds_0(URL='jdbc:mysql://127.0.0.1:3306/test0',USER=ROOT);" />
+    <distsql-case id="alter-resource-url-single-with-password" value="ALTER 
RESOURCE 
ds_0(URL='jdbc:mysql://127.0.0.1:3306/test0',USER=ROOT,PASSWORD=123456);" />
+    <distsql-case id="alter-resource-url-multiple" value="ALTER RESOURCE 
ds_0(URL='jdbc:mysql://127.0.0.1:3306/test0',USER=ROOT,PASSWORD=123456), 
ds_1(URL='jdbc:mysql://127.0.0.1:3306/test1',USER=ROOT,PASSWORD=123456);" />
+    <distsql-case id="alter-resource-single-with-properties" value="ALTER 
RESOURCE 
ds_0(HOST=127.0.0.1,PORT=3306,DB=test0,USER=ROOT,PASSWORD=123456,PROPERTIES('maxPoolSize'=30));"
 />
+    <distsql-case id="alter-resource-url-single-with-empty-properties" 
value="ALTER RESOURCE 
ds_0(URL='jdbc:mysql://127.0.0.1:3306/test0',USER=ROOT,PROPERTIES())" />
+    <distsql-case id="alter-resource-url-single-with-properties" value="ALTER 
RESOURCE 
ds_0(URL='jdbc:mysql://127.0.0.1:3306/test0',USER=ROOT,PASSWORD=123456,PROPERTIES('maxPoolSize'=30))"
 />
     <distsql-case id="alter-sharding-table-rule" value="ALTER SHARDING TABLE 
RULE t_order (RESOURCES(ms_group_0,ms_group_1), SHARDING_COLUMN=order_id, 
TYPE(NAME=hash_mod,PROPERTIES('sharding-count'=4)),GENERATED_KEY(COLUMN=another_id,TYPE(NAME=snowflake,PROPERTIES('worker-id'=123))))"
 />
     <distsql-case id="alter-sharding-table-rule-with-inline-expression" 
value="ALTER SHARDING TABLE RULE t_order (RESOURCES('ms_group_${0..1}'), 
SHARDING_COLUMN=order_id, 
TYPE(NAME=hash_mod,PROPERTIES('sharding-count'=4)),GENERATED_KEY(COLUMN=another_id,TYPE(NAME=snowflake,PROPERTIES('worker-id'=123))))"
 />
     <distsql-case id="alter-sharding-binding-table-rules" value="ALTER 
SHARDING BINDING TABLE RULES ((t_order,t_order_item), (t_1,t_2))" />

Reply via email to