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 82b5f7c  For #11100, change 'add reource' syntax and  allow custom 
properties for connection pool. (#11185)
82b5f7c is described below

commit 82b5f7cfcb9538197f2c59c935e75f65513738ca
Author: Raigor <[email protected]>
AuthorDate: Thu Jul 8 16:05:03 2021 +0800

    For #11100, change 'add reource' syntax and  allow custom properties for 
connection pool. (#11185)
    
    * For #11100, add URL item to `add resoutce` syntax.
    
    * delete unused parameter `databaseType`
    
    * optimize setter logic for connection pool and jdbc param.
    
    * add default value for 'useSSL' and 'serverTimezone', add test case.
    
    * fix ci.
    
    * fix checktStyle.
    
    * allow SIMPLE or URL configuration for `Add Resource`.
    
    * fix style and add test cases.
    
    * fix merge conflicts.
    
    * replace 'indexOf' to 'URI.getQuery' to find url properties.
    
    * replace 'URI.getQuery' to 'regular' to find jdbc url properties.
    
    * optimize parser & add tast cases.
---
 .../src/main/antlr4/imports/Keyword.g4             |   4 +
 .../src/main/antlr4/imports/RDLStatement.g4        |  22 +++-
 .../resource/ResourceDistSQLStatementVisitor.java  |  26 +++--
 .../api/DistSQLStatementParserEngineTest.java      |  93 ++++++++++++++---
 .../distsql/parser/segment/DataSourceSegment.java  |   2 +
 .../config/datasource/DataSourceConfiguration.java |  19 +++-
 .../config/datasource/DataSourceParameter.java     |   4 +
 .../infra/config/DataSourceConfigurationTest.java  |  24 +++++
 .../jdbc/connection/ConnectionUrlParser.java       |  86 +++++++++++++++
 .../decorator/HikariJDBCParameterDecorator.java    |  38 ++++---
 .../jdbc/connection/ConnectionUrlParserTest.java   | 115 +++++++++++++++++++++
 .../HikariJDBCParameterDecoratorTest.java          |  26 +++++
 .../resource/AddResourceBackendHandlerTest.java    |   2 +-
 .../config/util/DataSourceParameterConverter.java  |   7 ++
 .../proxy/config/yaml/YamlDataSourceParameter.java |   4 +
 .../converter/AddResourcesStatementConverter.java  |   4 +
 .../util/DataSourceParameterConverterTest.java     |  17 ++-
 .../AddResourcesStatementConverterTest.java        |   8 +-
 .../asserts/segment/distsql/DataSourceAssert.java  |   2 +
 .../segment/impl/distsql/ExpectedDataSource.java   |   3 +
 .../src/main/resources/case/rdl/create.xml         |  19 +++-
 .../main/resources/sql/supported/rdl/create.xml    |   9 +-
 22 files changed, 480 insertions(+), 54 deletions(-)

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 f009912..fabe60b 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
@@ -47,6 +47,10 @@ FROM
     : F R O M
     ;
 
+URL
+    : U R L
+    ;
+
 HOST
     : H O S T
     ;
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 28f607f..e71b952 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
@@ -28,13 +28,21 @@ dropResource
     ;
 
 dataSource
-    : dataSourceName LP HOST EQ hostName COMMA PORT EQ port COMMA DB EQ dbName 
COMMA USER EQ user (COMMA PASSWORD EQ password)? (COMMA PROPERTIES LP 
connectionProperties? RP)? RP
+    : dataSourceName LP (simpleSource | urlSource) COMMA USER EQ user (COMMA 
PASSWORD EQ password)? (COMMA PROPERTIES LP poolProperties? RP)? RP
     ;
 
 dataSourceName
     : IDENTIFIER
     ;
 
+simpleSource
+    : HOST EQ hostName COMMA PORT EQ port COMMA DB EQ dbName
+    ;
+
+urlSource
+    : URL EQ url
+    ;
+
 hostName
     : IDENTIFIER | ip
     ;
@@ -51,6 +59,10 @@ dbName
     : IDENTIFIER
     ;
 
+url
+    : (IDENTIFIER | STRING)
+    ;
+
 user
     : IDENTIFIER | NUMBER
     ;
@@ -59,10 +71,10 @@ password
     : IDENTIFIER | INT | STRING
     ;
 
-connectionProperties
-    : connectionProperty (COMMA connectionProperty)*
+poolProperties
+    : poolProperty (COMMA poolProperty)*
     ;
 
-connectionProperty
-    : key=IDENTIFIER EQ value=IDENTIFIER
+poolProperty
+    : key=(IDENTIFIER | STRING) EQ value=(INT | IDENTIFIER | STRING)
     ;
diff --git 
a/shardingsphere-distsql-parser/shardingsphere-distsql-parser-engine/src/main/java/org/apache/shardingsphere/distsql/parser/core/resource/ResourceDistSQLStatementVisitor.java
 
b/shardingsphere-distsql-parser/shardingsphere-distsql-parser-engine/src/main/java/org/apache/shardingsphere/distsql/parser/core/resource/ResourceDistSQLStatementVisitor.java
index 60f54e1..a1db4a5 100644
--- 
a/shardingsphere-distsql-parser/shardingsphere-distsql-parser-engine/src/main/java/org/apache/shardingsphere/distsql/parser/core/resource/ResourceDistSQLStatementVisitor.java
+++ 
b/shardingsphere-distsql-parser/shardingsphere-distsql-parser-engine/src/main/java/org/apache/shardingsphere/distsql/parser/core/resource/ResourceDistSQLStatementVisitor.java
@@ -24,8 +24,8 @@ import 
org.apache.shardingsphere.distsql.parser.autogen.ResourceStatementParser.
 import 
org.apache.shardingsphere.distsql.parser.autogen.ResourceStatementParser.DropResourceContext;
 import 
org.apache.shardingsphere.distsql.parser.autogen.ResourceStatementParser.SchemaNameContext;
 import 
org.apache.shardingsphere.distsql.parser.autogen.ResourceStatementParser.ShowResourcesContext;
-import 
org.apache.shardingsphere.distsql.parser.autogen.ResourceStatementParser.ConnectionPropertiesContext;
-import 
org.apache.shardingsphere.distsql.parser.autogen.ResourceStatementParser.ConnectionPropertyContext;
+import 
org.apache.shardingsphere.distsql.parser.autogen.ResourceStatementParser.PoolPropertiesContext;
+import 
org.apache.shardingsphere.distsql.parser.autogen.ResourceStatementParser.PoolPropertyContext;
 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.drop.DropResourceStatement;
@@ -50,14 +50,26 @@ public final class ResourceDistSQLStatementVisitor extends 
ResourceStatementBase
     
     @Override
     public ASTNode visitDataSource(final DataSourceContext ctx) {
-        return new DataSourceSegment(
-                ctx.dataSourceName().getText(), ctx.hostName().getText(), 
ctx.port().getText(), ctx.dbName().getText(), ctx.user().getText(), null == 
ctx.password() ? "" : ctx.password().getText(),
-                null == ctx.connectionProperties() ? new Properties() : 
getConnectionProperties(ctx.connectionProperties()));
+        String url = null;
+        String hostName = null;
+        String port = null;
+        String dbName = null;
+        if (null != ctx.urlSource()) {
+            url = new 
IdentifierValue(ctx.urlSource().url().getText()).getValue();
+        }
+        if (null != ctx.simpleSource()) {
+            hostName = ctx.simpleSource().hostName().getText();
+            port = ctx.simpleSource().port().getText();
+            dbName = ctx.simpleSource().dbName().getText();
+        }
+        return new DataSourceSegment(ctx.dataSourceName().getText(), url, 
hostName, port, dbName,
+                ctx.user().getText(), null == ctx.password() ? "" : 
ctx.password().getText(),
+                null == ctx.poolProperties() ? new Properties() : 
getPoolProperties(ctx.poolProperties()));
     }
     
-    private Properties getConnectionProperties(final 
ConnectionPropertiesContext ctx) {
+    private Properties getPoolProperties(final PoolPropertiesContext ctx) {
         Properties result = new Properties();
-        for (ConnectionPropertyContext each : ctx.connectionProperty()) {
+        for (PoolPropertyContext each : ctx.poolProperty()) {
             result.setProperty(new 
IdentifierValue(each.key.getText()).getValue(), new 
IdentifierValue(each.value.getText()).getValue());
         }
         return result;
diff --git 
a/shardingsphere-distsql-parser/shardingsphere-distsql-parser-engine/src/test/java/org/apache/shardingsphere/distsql/parser/api/DistSQLStatementParserEngineTest.java
 
b/shardingsphere-distsql-parser/shardingsphere-distsql-parser-engine/src/test/java/org/apache/shardingsphere/distsql/parser/api/DistSQLStatementParserEngineTest.java
index 41d51dc..3774cc7 100644
--- 
a/shardingsphere-distsql-parser/shardingsphere-distsql-parser-engine/src/test/java/org/apache/shardingsphere/distsql/parser/api/DistSQLStatementParserEngineTest.java
+++ 
b/shardingsphere-distsql-parser/shardingsphere-distsql-parser-engine/src/test/java/org/apache/shardingsphere/distsql/parser/api/DistSQLStatementParserEngineTest.java
@@ -41,10 +41,19 @@ public final class DistSQLStatementParserEngineTest {
     private static final String ADD_RESOURCE_MULTIPLE = "ADD 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);";
     
-    private static final String ADD_RESOURCE_SINGLE_WITH_EMPTY_PROPERTIES = 
"ADD RESOURCE ds_0(HOST=127.0.0.1,PORT=3306,DB=test0,USER=ROOT,PROPERTIES());";
+    private static final String ADD_RESOURCE_SINGLE_WITH_PROPERTIES = "ADD 
RESOURCE 
ds_0(HOST=127.0.0.1,PORT=3306,DB=test0,USER=ROOT,PASSWORD=123456,PROPERTIES(\"maxPoolSize\"=30));";
     
-    private static final String ADD_RESOURCE_SINGLE_WITH_PROPERTIES = "ADD 
RESOURCE 
ds_0(HOST=127.0.0.1,PORT=3306,DB=test0,USER=ROOT,PASSWORD=123456,PROPERTIES(" 
-            + "\"useSSL\"=\"false\",\"serverTimezone\"=\"UTC\"));";
+    private static final String ADD_RESOURCE_SINGLE_WITHOUT_PASSWORD_BY_URL = 
"ADD RESOURCE ds_0(URL=\"jdbc:mysql://127.0.0.1:3306/test0\",USER=ROOT);";
+    
+    private static final String ADD_RESOURCE_SINGLE_WITH_PASSWORD_BY_URL = 
"ADD RESOURCE 
ds_0(URL=\"jdbc:mysql://127.0.0.1:3306/test0\",USER=ROOT,PASSWORD=123456);";
+    
+    private static final String ADD_RESOURCE_MULTIPLE_BY_URL = "ADD 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);";
+    
+    private static final String 
ADD_RESOURCE_SINGLE_WITH_EMPTY_PROPERTIES_BY_URL = "ADD RESOURCE 
ds_0(URL=\"jdbc:mysql://127.0.0.1:3306/test0\",USER=ROOT,PROPERTIES());";
+    
+    private static final String ADD_RESOURCE_SINGLE_WITH_PROPERTIES_BY_URL = 
"ADD RESOURCE 
ds_0(URL=\"jdbc:mysql://127.0.0.1:3306/test0\",USER=ROOT,PASSWORD=123456,PROPERTIES("
 
+            + "\"maxPoolSize\"=30));";
     
     private static final String DROP_RESOURCE = "DROP RESOURCE ds_0,ds_1";
     
@@ -100,6 +109,63 @@ public final class DistSQLStatementParserEngineTest {
     }
     
     @Test
+    public void assertParseAddSingleResourceWithProperties() {
+        SQLStatement sqlStatement = 
engine.parse(ADD_RESOURCE_SINGLE_WITH_PROPERTIES);
+        assertTrue(sqlStatement instanceof AddResourceStatement);
+        assertThat(((AddResourceStatement) 
sqlStatement).getDataSources().size(), is(1));
+        DataSourceSegment dataSourceSegment = ((AddResourceStatement) 
sqlStatement).getDataSources().iterator().next();
+        assertThat(dataSourceSegment.getName(), is("ds_0"));
+        assertThat(dataSourceSegment.getHostName(), is("127.0.0.1"));
+        assertThat(dataSourceSegment.getPort(), is("3306"));
+        assertThat(dataSourceSegment.getDb(), is("test0"));
+        assertThat(dataSourceSegment.getUser(), is("ROOT"));
+        assertThat(dataSourceSegment.getPassword(), is("123456"));
+        assertThat(dataSourceSegment.getProperties().size(), is(1));
+        
assertThat(dataSourceSegment.getProperties().getProperty("maxPoolSize"), 
is("30"));
+    }
+    
+    @Test
+    public void assertParseAddSingleResourceWithoutPasswordByUrl() {
+        SQLStatement sqlStatement = 
engine.parse(ADD_RESOURCE_SINGLE_WITHOUT_PASSWORD_BY_URL);
+        assertTrue(sqlStatement instanceof AddResourceStatement);
+        assertThat(((AddResourceStatement) 
sqlStatement).getDataSources().size(), is(1));
+        DataSourceSegment dataSourceSegment = ((AddResourceStatement) 
sqlStatement).getDataSources().iterator().next();
+        assertThat(dataSourceSegment.getName(), is("ds_0"));
+        assertThat(dataSourceSegment.getUrl(), 
is("jdbc:mysql://127.0.0.1:3306/test0"));
+        assertThat(dataSourceSegment.getUser(), is("ROOT"));
+    }
+    
+    @Test
+    public void assertParseAddSingleResourceWithPasswordByUrl() {
+        SQLStatement sqlStatement = 
engine.parse(ADD_RESOURCE_SINGLE_WITH_PASSWORD_BY_URL);
+        assertTrue(sqlStatement instanceof AddResourceStatement);
+        assertThat(((AddResourceStatement) 
sqlStatement).getDataSources().size(), is(1));
+        DataSourceSegment dataSourceSegment = ((AddResourceStatement) 
sqlStatement).getDataSources().iterator().next();
+        assertThat(dataSourceSegment.getName(), is("ds_0"));
+        assertThat(dataSourceSegment.getUrl(), 
is("jdbc:mysql://127.0.0.1:3306/test0"));
+        assertThat(dataSourceSegment.getUser(), is("ROOT"));
+        assertThat(dataSourceSegment.getPassword(), is("123456"));
+    }
+    
+    @Test
+    public void assertParseAddMultipleResourcesByUrl() {
+        SQLStatement sqlStatement = engine.parse(ADD_RESOURCE_MULTIPLE_BY_URL);
+        assertTrue(sqlStatement instanceof AddResourceStatement);
+        assertThat(((AddResourceStatement) 
sqlStatement).getDataSources().size(), is(2));
+        List<DataSourceSegment> dataSourceSegments = new 
ArrayList<>(((AddResourceStatement) sqlStatement).getDataSources());
+        DataSourceSegment dataSourceSegment = dataSourceSegments.get(0);
+        assertThat(dataSourceSegment.getName(), is("ds_0"));
+        assertThat(dataSourceSegment.getUrl(), 
is("jdbc:mysql://127.0.0.1:3306/test0"));
+        assertThat(dataSourceSegment.getUser(), is("ROOT"));
+        assertThat(dataSourceSegment.getPassword(), is("123456"));
+        dataSourceSegment = dataSourceSegments.get(1);
+        assertThat(dataSourceSegment.getName(), is("ds_1"));
+        assertThat(dataSourceSegment.getUrl(), 
is("jdbc:mysql://127.0.0.1:3306/test1"));
+        assertThat(dataSourceSegment.getUser(), is("ROOT"));
+        assertThat(dataSourceSegment.getPassword(), is("123456"));
+    }
+    
+    @Test
     public void assertParseDropResource() {
         SQLStatement sqlStatement = engine.parse(DROP_RESOURCE);
         assertTrue(sqlStatement instanceof DropResourceStatement);
@@ -108,33 +174,28 @@ public final class DistSQLStatementParserEngineTest {
     }
     
     @Test
-    public void assertParseAddSingleResourceWithEmptyProperties() {
-        SQLStatement sqlStatement = 
engine.parse(ADD_RESOURCE_SINGLE_WITH_EMPTY_PROPERTIES);
+    public void assertParseAddSingleResourceWithEmptyPropertiesByUrl() {
+        SQLStatement sqlStatement = 
engine.parse(ADD_RESOURCE_SINGLE_WITH_EMPTY_PROPERTIES_BY_URL);
         assertTrue(sqlStatement instanceof AddResourceStatement);
         assertThat(((AddResourceStatement) 
sqlStatement).getDataSources().size(), is(1));
         DataSourceSegment dataSourceSegment = ((AddResourceStatement) 
sqlStatement).getDataSources().iterator().next();
         assertThat(dataSourceSegment.getName(), is("ds_0"));
-        assertThat(dataSourceSegment.getHostName(), is("127.0.0.1"));
-        assertThat(dataSourceSegment.getPort(), is("3306"));
-        assertThat(dataSourceSegment.getDb(), is("test0"));
+        assertThat(dataSourceSegment.getUrl(), 
is("jdbc:mysql://127.0.0.1:3306/test0"));
         assertThat(dataSourceSegment.getUser(), is("ROOT"));
         assertThat(dataSourceSegment.getProperties().size(), is(0));
     }
     
     @Test
-    public void assertParseAddSingleResourceWithProperties() {
-        SQLStatement sqlStatement = 
engine.parse(ADD_RESOURCE_SINGLE_WITH_PROPERTIES);
+    public void assertParseAddSingleResourceWithPropertiesByUrl() {
+        SQLStatement sqlStatement = 
engine.parse(ADD_RESOURCE_SINGLE_WITH_PROPERTIES_BY_URL);
         assertTrue(sqlStatement instanceof AddResourceStatement);
         assertThat(((AddResourceStatement) 
sqlStatement).getDataSources().size(), is(1));
         DataSourceSegment dataSourceSegment = ((AddResourceStatement) 
sqlStatement).getDataSources().iterator().next();
         assertThat(dataSourceSegment.getName(), is("ds_0"));
-        assertThat(dataSourceSegment.getHostName(), is("127.0.0.1"));
-        assertThat(dataSourceSegment.getPort(), is("3306"));
-        assertThat(dataSourceSegment.getDb(), is("test0"));
+        assertThat(dataSourceSegment.getUrl(), 
is("jdbc:mysql://127.0.0.1:3306/test0"));
         assertThat(dataSourceSegment.getUser(), is("ROOT"));
         assertThat(dataSourceSegment.getPassword(), is("123456"));
-        assertThat(dataSourceSegment.getProperties().size(), is(2));
-        assertThat(dataSourceSegment.getProperties().getProperty("useSSL"), 
is("false"));
-        
assertThat(dataSourceSegment.getProperties().getProperty("serverTimezone"), 
is("UTC"));
+        assertThat(dataSourceSegment.getProperties().size(), is(1));
+        
assertThat(dataSourceSegment.getProperties().getProperty("maxPoolSize"), 
is("30"));
     }
 }
diff --git 
a/shardingsphere-distsql-parser/shardingsphere-distsql-parser-statement/src/main/java/org/apache/shardingsphere/distsql/parser/segment/DataSourceSegment.java
 
b/shardingsphere-distsql-parser/shardingsphere-distsql-parser-statement/src/main/java/org/apache/shardingsphere/distsql/parser/segment/DataSourceSegment.java
index 6166c49..ae80450 100644
--- 
a/shardingsphere-distsql-parser/shardingsphere-distsql-parser-statement/src/main/java/org/apache/shardingsphere/distsql/parser/segment/DataSourceSegment.java
+++ 
b/shardingsphere-distsql-parser/shardingsphere-distsql-parser-statement/src/main/java/org/apache/shardingsphere/distsql/parser/segment/DataSourceSegment.java
@@ -32,6 +32,8 @@ public final class DataSourceSegment implements ASTNode {
     
     private final String name;
     
+    private final String url;
+    
     private final String hostName;
     
     private final String port;
diff --git 
a/shardingsphere-infra/shardingsphere-infra-common/src/main/java/org/apache/shardingsphere/infra/config/datasource/DataSourceConfiguration.java
 
b/shardingsphere-infra/shardingsphere-infra-common/src/main/java/org/apache/shardingsphere/infra/config/datasource/DataSourceConfiguration.java
index e89c479..64899b3 100644
--- 
a/shardingsphere-infra/shardingsphere-infra-common/src/main/java/org/apache/shardingsphere/infra/config/datasource/DataSourceConfiguration.java
+++ 
b/shardingsphere-infra/shardingsphere-infra-common/src/main/java/org/apache/shardingsphere/infra/config/datasource/DataSourceConfiguration.java
@@ -28,6 +28,7 @@ import 
org.apache.shardingsphere.infra.config.exception.ShardingSphereConfigurat
 import org.apache.shardingsphere.infra.spi.ShardingSphereServiceLoader;
 
 import javax.sql.DataSource;
+import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.util.Arrays;
 import java.util.Collection;
@@ -116,8 +117,7 @@ public final class DataSourceConfiguration {
             try {
                 Optional<Method> setterMethod = findSetterMethod(methods, 
entry.getKey());
                 if (setterMethod.isPresent() && null != entry.getValue()) {
-                    setterMethod.get().invoke(result, 
setterMethod.get().getParameterTypes()[0] == String.class
-                            ? String.valueOf(entry.getValue()) : 
entry.getValue());
+                    setDataSourceField(setterMethod.get(), result, 
entry.getValue());
                 }
             } catch (final IllegalArgumentException ex) {
                 throw new ShardingSphereConfigurationException("Incorrect 
configuration item: the property %s of the dataSource, because %s", 
entry.getKey(), ex.getMessage());
@@ -127,6 +127,21 @@ public final class DataSourceConfiguration {
         return decorator.isPresent() ? decorator.get().decorate(result) : 
result;
     }
     
+    private void setDataSourceField(final Method method, final DataSource 
target, final Object value) throws InvocationTargetException, 
IllegalAccessException {
+        Class<?> paramType = method.getParameterTypes()[0];
+        if (paramType == int.class) {
+            method.invoke(target, Integer.parseInt(value.toString()));
+        } else if (paramType == long.class) {
+            method.invoke(target, Long.parseLong(value.toString()));
+        } else if (paramType == boolean.class || paramType == Boolean.class) {
+            method.invoke(target, Boolean.parseBoolean(value.toString()));
+        } else if (paramType == String.class) {
+            method.invoke(target, value.toString());
+        } else {
+            method.invoke(target, value);
+        }
+    }
+    
     @SuppressWarnings("rawtypes")
     private Optional<JDBCParameterDecorator> findJDBCParameterDecorator(final 
DataSource dataSource) {
         return 
ShardingSphereServiceLoader.getSingletonServiceInstances(JDBCParameterDecorator.class).stream().filter(each
 -> each.getType() == dataSource.getClass()).findFirst();
diff --git 
a/shardingsphere-infra/shardingsphere-infra-common/src/main/java/org/apache/shardingsphere/infra/config/datasource/DataSourceParameter.java
 
b/shardingsphere-infra/shardingsphere-infra-common/src/main/java/org/apache/shardingsphere/infra/config/datasource/DataSourceParameter.java
index bc73d33..04447ca 100644
--- 
a/shardingsphere-infra/shardingsphere-infra-common/src/main/java/org/apache/shardingsphere/infra/config/datasource/DataSourceParameter.java
+++ 
b/shardingsphere-infra/shardingsphere-infra-common/src/main/java/org/apache/shardingsphere/infra/config/datasource/DataSourceParameter.java
@@ -21,6 +21,8 @@ import lombok.EqualsAndHashCode;
 import lombok.Getter;
 import lombok.Setter;
 
+import java.util.Properties;
+
 /**
  * Data source parameters.
  */
@@ -48,4 +50,6 @@ public final class DataSourceParameter {
     private long maintenanceIntervalMilliseconds = 30 * 1000L;
     
     private boolean readOnly;
+    
+    private Properties customPoolProps;
 }
diff --git 
a/shardingsphere-infra/shardingsphere-infra-common/src/test/java/org/apache/shardingsphere/infra/config/DataSourceConfigurationTest.java
 
b/shardingsphere-infra/shardingsphere-infra-common/src/test/java/org/apache/shardingsphere/infra/config/DataSourceConfigurationTest.java
index 93b9b7c..1efac4e 100644
--- 
a/shardingsphere-infra/shardingsphere-infra-common/src/test/java/org/apache/shardingsphere/infra/config/DataSourceConfigurationTest.java
+++ 
b/shardingsphere-infra/shardingsphere-infra-common/src/test/java/org/apache/shardingsphere/infra/config/DataSourceConfigurationTest.java
@@ -29,6 +29,7 @@ import java.util.Arrays;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Properties;
 
 import static org.hamcrest.CoreMatchers.hasItem;
 import static org.hamcrest.CoreMatchers.instanceOf;
@@ -188,4 +189,27 @@ public final class DataSourceConfigurationTest {
         assertThat(actualConnectionInitSql, hasItem("set names utf8mb4;"));
         assertThat(actualConnectionInitSql, hasItem("set names utf8;"));
     }
+    
+    @Test
+    public void assertCreateDataSourceWithCustomPoolProps() {
+        Map<String, Object> props = new HashMap<>(16, 1);
+        props.put("driverClassName", "org.h2.Driver");
+        props.put("jdbcUrl", 
"jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;DATABASE_TO_UPPER=false;MODE=MySQL");
+        props.put("username", "root");
+        props.put("password", "root");
+        props.put("loginTimeout", "5000");
+        Properties customPoolProps = new Properties();
+        customPoolProps.setProperty("maximumPoolSize", "30");
+        customPoolProps.setProperty("idleTimeout", "30000");
+        DataSourceConfiguration dataSourceConfig = new 
DataSourceConfiguration(HikariDataSource.class.getName());
+        dataSourceConfig.getProps().putAll(props);
+        dataSourceConfig.getProps().putAll(new HashMap(customPoolProps));
+        HikariDataSource actual = (HikariDataSource) 
dataSourceConfig.createDataSource();
+        assertThat(actual.getDriverClassName(), is("org.h2.Driver"));
+        assertThat(actual.getJdbcUrl(), 
is("jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;DATABASE_TO_UPPER=false;MODE=MySQL"));
+        assertThat(actual.getUsername(), is("root"));
+        assertThat(actual.getPassword(), is("root"));
+        assertThat(actual.getMaximumPoolSize(), is(30));
+        assertThat(actual.getIdleTimeout(), is(30000L));
+    }
 }
diff --git 
a/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/communication/jdbc/connection/ConnectionUrlParser.java
 
b/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/communication/jdbc/connection/ConnectionUrlParser.java
new file mode 100644
index 0000000..8e7b88f
--- /dev/null
+++ 
b/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/communication/jdbc/connection/ConnectionUrlParser.java
@@ -0,0 +1,86 @@
+/*
+ * 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.proxy.backend.communication.jdbc.connection;
+
+import com.google.common.base.Splitter;
+import com.google.common.base.Strings;
+import lombok.Getter;
+import 
org.apache.shardingsphere.infra.config.exception.ShardingSphereConfigurationException;
+
+import java.util.Collections;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * JDBC connection url parser.
+ */
+@Getter
+public final class ConnectionUrlParser {
+    
+    private static final String KEY_SCHEME = "scheme";
+    
+    private static final String KEY_AUTHORITY = "authority";
+    
+    private static final String KEY_PATH = "path";
+    
+    private static final String KEY_QUERY = "query";
+    
+    private static final Pattern CONNECTION_URL_PATTERN = Pattern.compile(
+            // scheme
+            "(?<scheme>[\\w\\+:%]+)\\s*"
+                    // authority
+                    + "(?://(?<authority>[^/?#]*))?\\s*"
+                    // path
+                    + "(?:/(?!\\s*/)(?<path>[^?#]*))?"
+                    // query
+                    + "(?:\\?(?!\\s*\\?)(?<query>[^#]*))?");
+    
+    private final Matcher matcher;
+    
+    private final String scheme;
+    
+    private final String authority;
+    
+    private final String path;
+    
+    private final String query;
+    
+    public ConnectionUrlParser(final String jdbcUrl) {
+        matcher = CONNECTION_URL_PATTERN.matcher(jdbcUrl);
+        if (!matcher.matches()) {
+            throw new ShardingSphereConfigurationException("Incorrect JDBC url 
format: %s", jdbcUrl);
+        }
+        scheme = matcher.group(KEY_SCHEME);
+        authority = matcher.group(KEY_AUTHORITY);
+        path = matcher.group(KEY_PATH);
+        query = matcher.group(KEY_QUERY);
+    }
+    
+    /**
+     * Get properties map of JDBC url.
+     *
+     * @return properties map
+     */
+    public Map<String, String> getQueryMap() {
+        if (!Strings.isNullOrEmpty(query)) {
+            return Splitter.on("&").withKeyValueSeparator("=").split(query);
+        }
+        return Collections.emptyMap();
+    }
+}
diff --git 
a/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/communication/jdbc/datasource/decorator/HikariJDBCParameterDecorator.java
 
b/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/communication/jdbc/datasource/decorator/HikariJDBCParameterDecorator.java
index b1dc698..6c51081 100644
--- 
a/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/communication/jdbc/datasource/decorator/HikariJDBCParameterDecorator.java
+++ 
b/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/communication/jdbc/datasource/decorator/HikariJDBCParameterDecorator.java
@@ -17,8 +17,12 @@
 
 package 
org.apache.shardingsphere.proxy.backend.communication.jdbc.datasource.decorator;
 
+import com.zaxxer.hikari.HikariConfig;
 import com.zaxxer.hikari.HikariDataSource;
 import 
org.apache.shardingsphere.infra.config.datasource.JDBCParameterDecorator;
+import 
org.apache.shardingsphere.proxy.backend.communication.jdbc.connection.ConnectionUrlParser;
+
+import java.util.Map;
 
 /**
  * JDBC parameter decorator for HikariCP.
@@ -27,23 +31,33 @@ public final class HikariJDBCParameterDecorator implements 
JDBCParameterDecorato
     
     @Override
     public HikariDataSource decorate(final HikariDataSource dataSource) {
-        dataSource.getDataSourceProperties().setProperty("useServerPrepStmts", 
Boolean.TRUE.toString());
-        dataSource.getDataSourceProperties().setProperty("cachePrepStmts", 
Boolean.TRUE.toString());
-        dataSource.getDataSourceProperties().setProperty("prepStmtCacheSize", 
"200000");
-        
dataSource.getDataSourceProperties().setProperty("prepStmtCacheSqlLimit", 
"2048");
-        
dataSource.getDataSourceProperties().setProperty("useLocalSessionState", 
Boolean.TRUE.toString());
-        
dataSource.getDataSourceProperties().setProperty("rewriteBatchedStatements", 
Boolean.TRUE.toString());
-        
dataSource.getDataSourceProperties().setProperty("cacheResultSetMetadata", 
Boolean.FALSE.toString());
-        
dataSource.getDataSourceProperties().setProperty("cacheServerConfiguration", 
Boolean.TRUE.toString());
-        
dataSource.getDataSourceProperties().setProperty("elideSetAutoCommits", 
Boolean.TRUE.toString());
-        dataSource.getDataSourceProperties().setProperty("maintainTimeStats", 
Boolean.FALSE.toString());
-        
dataSource.getDataSourceProperties().setProperty("netTimeoutForStreamingResults",
 "0");
-        dataSource.getDataSourceProperties().setProperty("tinyInt1isBit", 
Boolean.FALSE.toString());
+        Map<String, String> urlProps = new 
ConnectionUrlParser(dataSource.getJdbcUrl()).getQueryMap();
+        addJDBCProperty(dataSource, urlProps, "useServerPrepStmts", 
Boolean.TRUE.toString());
+        addJDBCProperty(dataSource, urlProps, "useServerPrepStmts", 
Boolean.TRUE.toString());
+        addJDBCProperty(dataSource, urlProps, "cachePrepStmts", 
Boolean.TRUE.toString());
+        addJDBCProperty(dataSource, urlProps, "prepStmtCacheSize", "200000");
+        addJDBCProperty(dataSource, urlProps, "prepStmtCacheSqlLimit", "2048");
+        addJDBCProperty(dataSource, urlProps, "useLocalSessionState", 
Boolean.TRUE.toString());
+        addJDBCProperty(dataSource, urlProps, "rewriteBatchedStatements", 
Boolean.TRUE.toString());
+        addJDBCProperty(dataSource, urlProps, "cacheResultSetMetadata", 
Boolean.FALSE.toString());
+        addJDBCProperty(dataSource, urlProps, "cacheServerConfiguration", 
Boolean.TRUE.toString());
+        addJDBCProperty(dataSource, urlProps, "elideSetAutoCommits", 
Boolean.TRUE.toString());
+        addJDBCProperty(dataSource, urlProps, "maintainTimeStats", 
Boolean.FALSE.toString());
+        addJDBCProperty(dataSource, urlProps, "netTimeoutForStreamingResults", 
"0");
+        addJDBCProperty(dataSource, urlProps, "tinyInt1isBit", 
Boolean.FALSE.toString());
+        addJDBCProperty(dataSource, urlProps, "useSSL", 
Boolean.FALSE.toString());
+        addJDBCProperty(dataSource, urlProps, "serverTimezone", "UTC");
         HikariDataSource result = new HikariDataSource(dataSource);
         dataSource.close();
         return result;
     }
     
+    private void addJDBCProperty(final HikariConfig config, final Map<String, 
String> urlProps, final String key, final String value) {
+        if (urlProps.isEmpty() || !urlProps.containsKey(key)) {
+            config.addDataSourceProperty(key, value);
+        }
+    }
+    
     @Override
     public Class<HikariDataSource> getType() {
         return HikariDataSource.class;
diff --git 
a/shardingsphere-proxy/shardingsphere-proxy-backend/src/test/java/org/apache/shardingsphere/proxy/backend/communication/jdbc/connection/ConnectionUrlParserTest.java
 
b/shardingsphere-proxy/shardingsphere-proxy-backend/src/test/java/org/apache/shardingsphere/proxy/backend/communication/jdbc/connection/ConnectionUrlParserTest.java
new file mode 100644
index 0000000..c8f7c1b
--- /dev/null
+++ 
b/shardingsphere-proxy/shardingsphere-proxy-backend/src/test/java/org/apache/shardingsphere/proxy/backend/communication/jdbc/connection/ConnectionUrlParserTest.java
@@ -0,0 +1,115 @@
+/*
+ * 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.proxy.backend.communication.jdbc.connection;
+
+import lombok.extern.slf4j.Slf4j;
+import 
org.apache.shardingsphere.infra.config.exception.ShardingSphereConfigurationException;
+import org.junit.Test;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+
+@Slf4j
+public final class ConnectionUrlParserTest {
+    
+    private static final String MYSQL_CONNECTION_WITHOUT_PROPS = 
"jdbc:mysql://127.0.0.1:3306/demo_ds";
+    
+    private static final String MYSQL_CONNECTION_WITH_PROPS = 
"jdbc:mysql://127.0.0.1:3306/demo_ds?serverTimezone=UTC&useSSL=false";
+    
+    private static final String MYSQL_CONNECTION_WITH_REPLICATION = 
"jdbc:mysql:replication://master_ip:3306,slave_1_ip:3306,slave_2_ip:3306/demo_ds?useUnicode=true";
+    
+    private static final String POSTGRESQL_CONNECTION_WITH_PROPS = 
"jdbc:postgresql://127.0.0.1:5432/demo_ds?serverTimezone=UTC&useSSL=false";
+    
+    private static final String MICROSOFT_SQLSERVER_CONNECTION_WITHOUT_PROPS = 
"jdbc:microsoft:sqlserver://127.0.0.1:3306/demo_ds";
+    
+    private static final String MOCK_CONNECTION_WITHOUT_PROPS = 
"mock:jdbc://127.0.0.1:3306/demo_ds";
+    
+    private static final String INCORRECT_MYSQL_CONNECTION = 
"jdbc:mysql://127.0.0.1:3306//demo_ds";
+    
+    @Test
+    public void assertParseMySQLWithoutProps() {
+        ConnectionUrlParser connectionUrlParser = new 
ConnectionUrlParser(MYSQL_CONNECTION_WITHOUT_PROPS);
+        assertThat(connectionUrlParser.getScheme(), is("jdbc:mysql:"));
+        assertThat(connectionUrlParser.getAuthority(), is("127.0.0.1:3306"));
+        assertThat(connectionUrlParser.getPath(), is("demo_ds"));
+        assertNull(connectionUrlParser.getQuery());
+        assertTrue(connectionUrlParser.getQueryMap().isEmpty());
+    }
+    
+    @Test
+    public void assertParseMySQLWithProps() {
+        ConnectionUrlParser connectionUrlParser = new 
ConnectionUrlParser(MYSQL_CONNECTION_WITH_PROPS);
+        assertThat(connectionUrlParser.getScheme(), is("jdbc:mysql:"));
+        assertThat(connectionUrlParser.getAuthority(), is("127.0.0.1:3306"));
+        assertThat(connectionUrlParser.getPath(), is("demo_ds"));
+        assertThat(connectionUrlParser.getQuery(), 
is("serverTimezone=UTC&useSSL=false"));
+        assertThat(connectionUrlParser.getQueryMap().size(), is(2));
+        assertThat(connectionUrlParser.getQueryMap().get("serverTimezone"), 
is("UTC"));
+        assertThat(connectionUrlParser.getQueryMap().get("useSSL"), 
is("false"));
+    }
+    
+    @Test
+    public void assertParseMySQLWithReplication() {
+        ConnectionUrlParser connectionUrlParser = new 
ConnectionUrlParser(MYSQL_CONNECTION_WITH_REPLICATION);
+        assertThat(connectionUrlParser.getScheme(), 
is("jdbc:mysql:replication:"));
+        assertThat(connectionUrlParser.getAuthority(), 
is("master_ip:3306,slave_1_ip:3306,slave_2_ip:3306"));
+        assertThat(connectionUrlParser.getPath(), is("demo_ds"));
+        assertThat(connectionUrlParser.getQuery(), is("useUnicode=true"));
+        assertThat(connectionUrlParser.getQueryMap().size(), is(1));
+        assertThat(connectionUrlParser.getQueryMap().get("useUnicode"), 
is("true"));
+    }
+    
+    @Test
+    public void assertParsePostgreSQLWithProps() {
+        ConnectionUrlParser connectionUrlParser = new 
ConnectionUrlParser(POSTGRESQL_CONNECTION_WITH_PROPS);
+        assertThat(connectionUrlParser.getScheme(), is("jdbc:postgresql:"));
+        assertThat(connectionUrlParser.getAuthority(), is("127.0.0.1:5432"));
+        assertThat(connectionUrlParser.getPath(), is("demo_ds"));
+        assertThat(connectionUrlParser.getQuery(), 
is("serverTimezone=UTC&useSSL=false"));
+        assertThat(connectionUrlParser.getQueryMap().size(), is(2));
+        assertThat(connectionUrlParser.getQueryMap().get("serverTimezone"), 
is("UTC"));
+        assertThat(connectionUrlParser.getQueryMap().get("useSSL"), 
is("false"));
+    }
+    
+    @Test
+    public void assertParseMicrosoftSQLServerWithoutProps() {
+        ConnectionUrlParser connectionUrlParser = new 
ConnectionUrlParser(MICROSOFT_SQLSERVER_CONNECTION_WITHOUT_PROPS);
+        assertThat(connectionUrlParser.getScheme(), 
is("jdbc:microsoft:sqlserver:"));
+        assertThat(connectionUrlParser.getAuthority(), is("127.0.0.1:3306"));
+        assertThat(connectionUrlParser.getPath(), is("demo_ds"));
+        assertNull(connectionUrlParser.getQuery());
+        assertTrue(connectionUrlParser.getQueryMap().isEmpty());
+    }
+    
+    @Test
+    public void assertParseMockSQLWithoutProps() {
+        ConnectionUrlParser connectionUrlParser = new 
ConnectionUrlParser(MOCK_CONNECTION_WITHOUT_PROPS);
+        assertThat(connectionUrlParser.getScheme(), is("mock:jdbc:"));
+        assertThat(connectionUrlParser.getAuthority(), is("127.0.0.1:3306"));
+        assertThat(connectionUrlParser.getPath(), is("demo_ds"));
+        assertNull(connectionUrlParser.getQuery());
+        assertTrue(connectionUrlParser.getQueryMap().isEmpty());
+    }
+    
+    @Test(expected = ShardingSphereConfigurationException.class)
+    public void assertParseIncorrectURL() {
+        new ConnectionUrlParser(INCORRECT_MYSQL_CONNECTION);
+    }
+}
diff --git 
a/shardingsphere-proxy/shardingsphere-proxy-backend/src/test/java/org/apache/shardingsphere/proxy/backend/communication/jdbc/datasource/decorator/HikariJDBCParameterDecoratorTest.java
 
b/shardingsphere-proxy/shardingsphere-proxy-backend/src/test/java/org/apache/shardingsphere/proxy/backend/communication/jdbc/datasource/decorator/HikariJDBCParameterDecoratorTest.java
index 5a6ce20..50a4d93 100644
--- 
a/shardingsphere-proxy/shardingsphere-proxy-backend/src/test/java/org/apache/shardingsphere/proxy/backend/communication/jdbc/datasource/decorator/HikariJDBCParameterDecoratorTest.java
+++ 
b/shardingsphere-proxy/shardingsphere-proxy-backend/src/test/java/org/apache/shardingsphere/proxy/backend/communication/jdbc/datasource/decorator/HikariJDBCParameterDecoratorTest.java
@@ -25,6 +25,7 @@ import java.util.Properties;
 import static org.hamcrest.CoreMatchers.is;
 import static org.junit.Assert.assertSame;
 import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertNull;
 
 public final class HikariJDBCParameterDecoratorTest {
     
@@ -52,5 +53,30 @@ public final class HikariJDBCParameterDecoratorTest {
         assertThat(props.getProperty("maintainTimeStats"), 
is(Boolean.FALSE.toString()));
         assertThat(props.getProperty("netTimeoutForStreamingResults"), 
is("0"));
         assertThat(props.getProperty("tinyInt1isBit"), 
is(Boolean.FALSE.toString()));
+        assertThat(props.getProperty("useSSL"), is(Boolean.FALSE.toString()));
+        assertThat(props.getProperty("serverTimezone"), is("UTC"));
+    }
+    
+    @Test
+    public void assertDecoratedHikariDataSourceWithExistedParam() {
+        HikariDataSource dataSource = new HikariDataSource();
+        
dataSource.setDriverClassName("org.apache.shardingsphere.test.mock.MockedDriver");
+        
dataSource.setJdbcUrl("mock:jdbc://127.0.0.1:3306/test0?tinyInt1isBit=true&useSSL=false");
+        HikariDataSource actual = new 
HikariJDBCParameterDecorator().decorate(dataSource);
+        Properties props = actual.getDataSourceProperties();
+        assertThat(props.getProperty("useServerPrepStmts"), 
is(Boolean.TRUE.toString()));
+        assertThat(props.getProperty("cachePrepStmts"), 
is(Boolean.TRUE.toString()));
+        assertThat(props.getProperty("prepStmtCacheSize"), is("200000"));
+        assertThat(props.getProperty("prepStmtCacheSqlLimit"), is("2048"));
+        assertThat(props.getProperty("useLocalSessionState"), 
is(Boolean.TRUE.toString()));
+        assertThat(props.getProperty("rewriteBatchedStatements"), 
is(Boolean.TRUE.toString()));
+        assertThat(props.getProperty("cacheResultSetMetadata"), 
is(Boolean.FALSE.toString()));
+        assertThat(props.getProperty("cacheServerConfiguration"), 
is(Boolean.TRUE.toString()));
+        assertThat(props.getProperty("elideSetAutoCommits"), 
is(Boolean.TRUE.toString()));
+        assertThat(props.getProperty("maintainTimeStats"), 
is(Boolean.FALSE.toString()));
+        assertThat(props.getProperty("netTimeoutForStreamingResults"), 
is("0"));
+        assertNull(props.getProperty("tinyInt1isBit"));
+        assertNull(props.getProperty("useSSL"));
+        assertThat(props.getProperty("serverTimezone"), is("UTC"));
     }
 }
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 016ebf6..70896e4 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
@@ -94,6 +94,6 @@ public final class AddResourceBackendHandlerTest {
     }
     
     private AddResourceStatement createAddResourceStatement() {
-        return new AddResourceStatement(Collections.singleton(new 
DataSourceSegment("ds_0", "127.0.0.1", "test0", "3306", "root", "", new 
Properties())));
+        return new AddResourceStatement(Collections.singleton(new 
DataSourceSegment("ds_0", "jdbc:mysql://127.0.0.1:3306/test0", null, null, 
null, "root", "", new Properties())));
     }
 }
diff --git 
a/shardingsphere-proxy/shardingsphere-proxy-common/src/main/java/org/apache/shardingsphere/proxy/config/util/DataSourceParameterConverter.java
 
b/shardingsphere-proxy/shardingsphere-proxy-common/src/main/java/org/apache/shardingsphere/proxy/config/util/DataSourceParameterConverter.java
index ec3be57..d76230b 100644
--- 
a/shardingsphere-proxy/shardingsphere-proxy-common/src/main/java/org/apache/shardingsphere/proxy/config/util/DataSourceParameterConverter.java
+++ 
b/shardingsphere-proxy/shardingsphere-proxy-common/src/main/java/org/apache/shardingsphere/proxy/config/util/DataSourceParameterConverter.java
@@ -25,6 +25,7 @@ import 
org.apache.shardingsphere.infra.config.datasource.DataSourceParameter;
 import org.apache.shardingsphere.proxy.config.yaml.YamlDataSourceParameter;
 
 import java.lang.reflect.Field;
+import java.util.HashMap;
 import java.util.LinkedHashMap;
 import java.util.Map;
 import java.util.Map.Entry;
@@ -85,6 +86,9 @@ public final class DataSourceParameterConverter {
         result.setPassword(yamlDataSourceParameter.getPassword());
         result.setReadOnly(yamlDataSourceParameter.isReadOnly());
         result.setUrl(yamlDataSourceParameter.getUrl());
+        if (null != yamlDataSourceParameter.getCustomPoolProps()) {
+            
result.setCustomPoolProps(yamlDataSourceParameter.getCustomPoolProps());
+        }
         return result;
     }
     
@@ -119,6 +123,9 @@ public final class DataSourceParameterConverter {
         result.getProps().put("minPoolSize", 
dataSourceParameter.getMinPoolSize());
         result.getProps().put("maintenanceIntervalMilliseconds", 
dataSourceParameter.getMaintenanceIntervalMilliseconds());
         result.getProps().put("readOnly", dataSourceParameter.isReadOnly());
+        if (null != dataSourceParameter.getCustomPoolProps()) {
+            result.getProps().putAll(new 
HashMap(dataSourceParameter.getCustomPoolProps()));
+        }
         return result;
     }
 }
diff --git 
a/shardingsphere-proxy/shardingsphere-proxy-common/src/main/java/org/apache/shardingsphere/proxy/config/yaml/YamlDataSourceParameter.java
 
b/shardingsphere-proxy/shardingsphere-proxy-common/src/main/java/org/apache/shardingsphere/proxy/config/yaml/YamlDataSourceParameter.java
index 8afdf94..ea159cf 100644
--- 
a/shardingsphere-proxy/shardingsphere-proxy-common/src/main/java/org/apache/shardingsphere/proxy/config/yaml/YamlDataSourceParameter.java
+++ 
b/shardingsphere-proxy/shardingsphere-proxy-common/src/main/java/org/apache/shardingsphere/proxy/config/yaml/YamlDataSourceParameter.java
@@ -22,6 +22,8 @@ import lombok.Getter;
 import lombok.Setter;
 import org.apache.shardingsphere.infra.yaml.config.YamlConfiguration;
 
+import java.util.Properties;
+
 /**
  * Data source parameters for YAML.
  */
@@ -49,4 +51,6 @@ public final class YamlDataSourceParameter implements 
YamlConfiguration {
     private long maintenanceIntervalMilliseconds;
     
     private boolean readOnly;
+    
+    private Properties customPoolProps;
 }
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/AddResourcesStatementConverter.java
index d736b43..ba0f95b 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/AddResourcesStatementConverter.java
@@ -54,12 +54,16 @@ public final class AddResourcesStatementConverter {
             
dataSource.setConnectionTimeoutMilliseconds(parameter.getConnectionTimeoutMilliseconds());
             
dataSource.setIdleTimeoutMilliseconds(parameter.getIdleTimeoutMilliseconds());
             
dataSource.setMaintenanceIntervalMilliseconds(parameter.getMaintenanceIntervalMilliseconds());
+            dataSource.setCustomPoolProps(each.getProperties());
             result.put(each.getName(), dataSource);
         }
         return result;
     }
     
     private static String getURL(final DatabaseType databaseType, final 
DataSourceSegment dataSourceSegment) {
+        if (null != dataSourceSegment.getUrl()) {
+            return dataSourceSegment.getUrl();
+        }
         return String.format("%s//%s:%s/%s", 
databaseType.getJdbcUrlPrefixes().iterator().next(), 
dataSourceSegment.getHostName(), dataSourceSegment.getPort(), 
dataSourceSegment.getDb());
     }
 }
diff --git 
a/shardingsphere-proxy/shardingsphere-proxy-common/src/test/java/org/apache/shardingsphere/proxy/config/util/DataSourceParameterConverterTest.java
 
b/shardingsphere-proxy/shardingsphere-proxy-common/src/test/java/org/apache/shardingsphere/proxy/config/util/DataSourceParameterConverterTest.java
index 128e01b..f6d967e 100644
--- 
a/shardingsphere-proxy/shardingsphere-proxy-common/src/test/java/org/apache/shardingsphere/proxy/config/util/DataSourceParameterConverterTest.java
+++ 
b/shardingsphere-proxy/shardingsphere-proxy-common/src/test/java/org/apache/shardingsphere/proxy/config/util/DataSourceParameterConverterTest.java
@@ -25,6 +25,7 @@ import org.junit.Test;
 
 import java.util.HashMap;
 import java.util.Map;
+import java.util.Properties;
 
 import static org.hamcrest.CoreMatchers.is;
 import static org.junit.Assert.assertThat;
@@ -80,14 +81,16 @@ public final class DataSourceParameterConverterTest {
     
     @Test
     public void assertGetDataSourceParameterMapFromYamlConfiguration() {
-        Map<String, YamlDataSourceParameter> yamlDataSourceParameterMap = new 
HashMap<>();
         YamlDataSourceParameter yamlDataSourceParameter0 = new 
YamlDataSourceParameter();
         yamlDataSourceParameter0.setUrl("jdbc:mysql://localhost:3306/t_order");
+        yamlDataSourceParameter0.setCustomPoolProps(getCustomPoolProps());
         setYamlDataSourceParameterPropertyWithoutUrl(yamlDataSourceParameter0);
-        yamlDataSourceParameterMap.put("ds_0", yamlDataSourceParameter0);
         YamlDataSourceParameter yamlDataSourceParameter1 = new 
YamlDataSourceParameter();
         
yamlDataSourceParameter1.setUrl("jdbc:mysql://localhost:3306/t_order_item");
+        yamlDataSourceParameter1.setCustomPoolProps(getCustomPoolProps());
         setYamlDataSourceParameterPropertyWithoutUrl(yamlDataSourceParameter1);
+        Map<String, YamlDataSourceParameter> yamlDataSourceParameterMap = new 
HashMap<>();
+        yamlDataSourceParameterMap.put("ds_0", yamlDataSourceParameter0);
         yamlDataSourceParameterMap.put("ds_1", yamlDataSourceParameter1);
         Map<String, DataSourceParameter> actualDataSourceParameterMap = 
DataSourceParameterConverter.getDataSourceParameterMapFromYamlConfiguration(yamlDataSourceParameterMap);
         assertThat(actualDataSourceParameterMap.size(), is(2));
@@ -117,5 +120,15 @@ public final class DataSourceParameterConverterTest {
         assertThat(dataSourceParameter.getMaintenanceIntervalMilliseconds(), 
is(30 * 1000L));
         assertThat(dataSourceParameter.getUsername(), is("root"));
         assertThat(dataSourceParameter.getPassword(), is("root"));
+        assertThat(dataSourceParameter.getCustomPoolProps().size(), is(2));
+        
assertThat(dataSourceParameter.getCustomPoolProps().get("maxPoolSize"), is(30));
+        
assertThat(dataSourceParameter.getCustomPoolProps().get("idleTimeoutMilliseconds"),
 is("30000"));
+    }
+    
+    private Properties getCustomPoolProps() {
+        Properties result = new Properties();
+        result.put("maxPoolSize", 30);
+        result.put("idleTimeoutMilliseconds", "30000");
+        return result;
     }
 }
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/AddResourcesStatementConverterTest.java
index 0d36e39..5451c0c 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/AddResourcesStatementConverterTest.java
@@ -41,13 +41,15 @@ public final class AddResourcesStatementConverterTest {
         assertThat(actual.size(), is(2));
         assertTrue(actual.keySet().containsAll(Arrays.asList("ds0", "ds1")));
         assertThat(actual.values().iterator().next().getUsername(), 
is("root0"));
+        
assertThat(actual.values().iterator().next().getCustomPoolProps().getProperty("maxPoolSize"),
 is("30"));
     }
     
     private Collection<DataSourceSegment> createDataSourceSegments() {
         Collection<DataSourceSegment> result = new LinkedList<>();
-        for (int i = 0; i < 2; i++) {
-            result.add(new DataSourceSegment(String.format("ds%s", i), 
"127.0.0.1", "3306", String.format("demo_ds_%s", i), String.format("root%s", 
i), String.format("root%s", i), new Properties()));
-        }
+        Properties customPoolProps = new Properties();
+        customPoolProps.setProperty("maxPoolSize", "30");
+        result.add(new DataSourceSegment("ds0", null, "127.0.0.1", "3306", 
"demo_ds_0", "root0", "root0", customPoolProps));
+        result.add(new DataSourceSegment("ds1", 
"jdbc:mysql://127.0.0.1:3306/demo_ds_1?useSSL=false", null, null, null, 
"root1", "root1", customPoolProps));
         return result;
     }
 }
diff --git 
a/shardingsphere-test/shardingsphere-parser-test/src/main/java/org/apache/shardingsphere/test/sql/parser/parameterized/asserts/segment/distsql/DataSourceAssert.java
 
b/shardingsphere-test/shardingsphere-parser-test/src/main/java/org/apache/shardingsphere/test/sql/parser/parameterized/asserts/segment/distsql/DataSourceAssert.java
index e16c4ba..7f65c71 100644
--- 
a/shardingsphere-test/shardingsphere-parser-test/src/main/java/org/apache/shardingsphere/test/sql/parser/parameterized/asserts/segment/distsql/DataSourceAssert.java
+++ 
b/shardingsphere-test/shardingsphere-parser-test/src/main/java/org/apache/shardingsphere/test/sql/parser/parameterized/asserts/segment/distsql/DataSourceAssert.java
@@ -49,6 +49,8 @@ public final class DataSourceAssert {
             assertThat(assertContext.getText(String.format("`%s`'s datasource 
segment assertion error: ",
                     actual.getClass().getSimpleName())), actual.getName(), 
CoreMatchers.is(expected.getName()));
             assertThat(assertContext.getText(String.format("`%s`'s datasource 
segment assertion error: ",
+                    actual.getClass().getSimpleName())), actual.getUrl(), 
CoreMatchers.is(expected.getUrl()));
+            assertThat(assertContext.getText(String.format("`%s`'s datasource 
segment assertion error: ",
                     actual.getClass().getSimpleName())), actual.getHostName(), 
CoreMatchers.is(expected.getHostName()));
             assertThat(assertContext.getText(String.format("`%s`'s datasource 
segment assertion error: ",
                     actual.getClass().getSimpleName())), actual.getPort(), 
CoreMatchers.is(expected.getPort()));
diff --git 
a/shardingsphere-test/shardingsphere-parser-test/src/main/java/org/apache/shardingsphere/test/sql/parser/parameterized/jaxb/cases/domain/segment/impl/distsql/ExpectedDataSource.java
 
b/shardingsphere-test/shardingsphere-parser-test/src/main/java/org/apache/shardingsphere/test/sql/parser/parameterized/jaxb/cases/domain/segment/impl/distsql/ExpectedDataSource.java
index 324822c..7f9e32f 100644
--- 
a/shardingsphere-test/shardingsphere-parser-test/src/main/java/org/apache/shardingsphere/test/sql/parser/parameterized/jaxb/cases/domain/segment/impl/distsql/ExpectedDataSource.java
+++ 
b/shardingsphere-test/shardingsphere-parser-test/src/main/java/org/apache/shardingsphere/test/sql/parser/parameterized/jaxb/cases/domain/segment/impl/distsql/ExpectedDataSource.java
@@ -30,6 +30,9 @@ import javax.xml.bind.annotation.XmlAttribute;
 @Setter
 public final class ExpectedDataSource extends 
AbstractExpectedIdentifierSQLSegment {
     
+    @XmlAttribute
+    private String url;
+    
     @XmlAttribute(name = "host-name")
     private String hostName;
     
diff --git 
a/shardingsphere-test/shardingsphere-parser-test/src/main/resources/case/rdl/create.xml
 
b/shardingsphere-test/shardingsphere-parser-test/src/main/resources/case/rdl/create.xml
index 121021a..7fe38c4 100644
--- 
a/shardingsphere-test/shardingsphere-parser-test/src/main/resources/case/rdl/create.xml
+++ 
b/shardingsphere-test/shardingsphere-parser-test/src/main/resources/case/rdl/create.xml
@@ -17,19 +17,32 @@
   -->
 
 <sql-parser-test-cases>
-    <add-resource sql-case-id="add-resource-single-without-password">
+    <add-resource sql-case-id="add-resource-simple-single-without-password">
         <data-source name="ds_0" host-name="127.0.0.1" port="3306" db="test0" 
user="ROOT" password=""/>
     </add-resource>
     
-    <add-resource sql-case-id="add-resource-single-with-password">
+    <add-resource sql-case-id="add-resource-simple-single-with-password">
         <data-source name="ds_0" host-name="127.0.0.1" port="3306" db="test0" 
user="ROOT" password="123456"/>
     </add-resource>
     
-    <add-resource sql-case-id="add-resource-multiple">
+    <add-resource sql-case-id="add-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"/>
     </add-resource>
     
+    <add-resource sql-case-id="add-resource-url-single-without-password">
+        <data-source name="ds_0" url="jdbc:mysql://127.0.0.1:3306/test0" 
user="ROOT" password=""/>
+    </add-resource>
+    
+    <add-resource sql-case-id="add-resource-url-single-with-password">
+        <data-source name="ds_0" url="jdbc:mysql://127.0.0.1:3306/test0" 
user="ROOT" password="123456"/>
+    </add-resource>
+    
+    <add-resource sql-case-id="add-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"/>
+    </add-resource>
+    
     <create-sharding-table-rule sql-case-id="create-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/create.xml
 
b/shardingsphere-test/shardingsphere-parser-test/src/main/resources/sql/supported/rdl/create.xml
index 2001fc9..1e1f12a 100644
--- 
a/shardingsphere-test/shardingsphere-parser-test/src/main/resources/sql/supported/rdl/create.xml
+++ 
b/shardingsphere-test/shardingsphere-parser-test/src/main/resources/sql/supported/rdl/create.xml
@@ -17,9 +17,12 @@
   -->
 
 <sql-cases>
-    <distsql-case id="add-resource-single-without-password" value="ADD 
RESOURCE ds_0(HOST=127.0.0.1,PORT=3306,DB=test0,USER=ROOT);" />
-    <distsql-case id="add-resource-single-with-password" value="ADD RESOURCE 
ds_0(HOST=127.0.0.1,PORT=3306,DB=test0,USER=ROOT,PASSWORD=123456);" />
-    <distsql-case id="add-resource-multiple" value="ADD 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="add-resource-simple-single-without-password" value="ADD 
RESOURCE ds_0(HOST=127.0.0.1,PORT=3306,DB=test0,USER=ROOT);" />
+    <distsql-case id="add-resource-simple-single-with-password" value="ADD 
RESOURCE ds_0(HOST=127.0.0.1,PORT=3306,DB=test0,USER=ROOT,PASSWORD=123456);" />
+    <distsql-case id="add-resource-simple-multiple" value="ADD 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="add-resource-url-single-without-password" value="ADD 
RESOURCE ds_0(URL='jdbc:mysql://127.0.0.1:3306/test0',USER=ROOT);\" />
+    <distsql-case id="add-resource-url-single-with-password" value="ADD 
RESOURCE 
ds_0(URL='jdbc:mysql://127.0.0.1:3306/test0',USER=ROOT,PASSWORD=123456);" />
+    <distsql-case id="add-resource-url-multiple" value="ADD 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="create-sharding-table-rule" value="CREATE 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="create-sharding-binding-table-rule" value="CREATE 
SHARDING BINDING TABLE RULES ((t_order,t_order_item), (t_1,t_2))" />
     <distsql-case id="create-sharding-broadcast-table-rule" value="CREATE 
SHARDING BROADCAST TABLE RULES(t_1,t_2)" />

Reply via email to