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

terrymanu 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 5cb6a309fca Support parsing query properties from Oracle JDBC URLs 
(#38901)
5cb6a309fca is described below

commit 5cb6a309fca70f2ffef9c3b699b2f00177450070
Author: Liang Zhang <[email protected]>
AuthorDate: Wed Jun 24 11:24:09 2026 +0800

    Support parsing query properties from Oracle JDBC URLs (#38901)
    
    * Refactor OracleConnectionPropertiesParser
    
    * Refactor OracleConnectionPropertiesParser
---
 RELEASE-NOTES.md                                   |  7 +++--
 .../jdbcurl/OracleConnectionPropertiesParser.java  | 17 +++++++----
 .../OracleConnectionPropertiesParserTest.java      | 35 ++++++++++++++--------
 3 files changed, 38 insertions(+), 21 deletions(-)

diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md
index 654a94c8c61..5d573d8446a 100644
--- a/RELEASE-NOTES.md
+++ b/RELEASE-NOTES.md
@@ -51,15 +51,16 @@
 1. SQL Parser: Preserve temporal literal text and raw value for MySQL and 
Oracle date-time literal parsing - 
[#38886](https://github.com/apache/shardingsphere/pull/38886)
 1. SQL Binder: Support select order by index bind metadata - 
[#38386](https://github.com/apache/shardingsphere/pull/38386)
 1. SQL Binder: Support SQL bind when with temp table name is same with 
physical table - [#38411](https://github.com/apache/shardingsphere/pull/38411)
+1. Metadata: Support parsing query properties from Oracle JDBC URLs - 
[#38901](https://github.com/apache/shardingsphere/pull/38901)
 1. JDBC: Support setMaxRows and getMaxRows method in jdbc when not execute SQL 
- [#38337](https://github.com/apache/shardingsphere/pull/38337)
 1. JDBC: Support safe close statement manager - 
[#38473](https://github.com/apache/shardingsphere/pull/38473)
-1. Encrypt: Support SqlServer update statement for Specifying a table alias as 
the target object when use encrypt feature - 
[#38733](https://github.com/apache/shardingsphere/pull/38733)
-1. Sharding: Fix HASH_MOD routing mismatch for same negative numeric values 
across numeric Java types with compatibility switch 
`normalize-numeric-int-range` - 
[#38327](https://github.com/apache/shardingsphere/pull/38327)
+1. JDBC: Bump the ClickHouse JDBC Driver used by optional modules to version 
`0.9.8` - [#38878](https://github.com/apache/shardingsphere/pull/38878)
 1. Proxy: Support non column projection for MySQL prepared statement in Proxy 
- [#38507](https://github.com/apache/shardingsphere/pull/38507)
 1. Proxy: Support driverClassName config in proxy storage unit to solve mysql 
and mariadb jdbc url conflict - 
[#38582](https://github.com/apache/shardingsphere/pull/38582)
 1. Proxy: Support Firebird prepared statement cache reuse for held connections 
- [#38644](https://github.com/apache/shardingsphere/pull/38644)
-1. JDBC: Bump the ClickHouse JDBC Driver used by optional modules to version 
`0.9.8` - [#38878](https://github.com/apache/shardingsphere/pull/38878)
 1. JDBC & Proxy: Add a check to verify database name naming conventions. - 
[#38883](https://github.com/apache/shardingsphere/pull/38883)
+1. Encrypt: Support SqlServer update statement for Specifying a table alias as 
the target object when use encrypt feature - 
[#38733](https://github.com/apache/shardingsphere/pull/38733)
+1. Sharding: Fix HASH_MOD routing mismatch for same negative numeric values 
across numeric Java types with compatibility switch 
`normalize-numeric-int-range` - 
[#38327](https://github.com/apache/shardingsphere/pull/38327)
 1. Proxy Native: Support building Proxy Native via GraalVM CE for JDK 25 - 
[#38682](https://github.com/apache/shardingsphere/pull/38682)
 
 ## Release 5.5.3
diff --git 
a/database/connector/dialect/oracle/src/main/java/org/apache/shardingsphere/database/connector/oracle/jdbcurl/OracleConnectionPropertiesParser.java
 
b/database/connector/dialect/oracle/src/main/java/org/apache/shardingsphere/database/connector/oracle/jdbcurl/OracleConnectionPropertiesParser.java
index 2bf9d81db24..b4dfb2a2a47 100644
--- 
a/database/connector/dialect/oracle/src/main/java/org/apache/shardingsphere/database/connector/oracle/jdbcurl/OracleConnectionPropertiesParser.java
+++ 
b/database/connector/dialect/oracle/src/main/java/org/apache/shardingsphere/database/connector/oracle/jdbcurl/OracleConnectionPropertiesParser.java
@@ -21,6 +21,7 @@ import com.google.common.base.Strings;
 import 
org.apache.shardingsphere.database.connector.core.exception.UnrecognizedDatabaseURLException;
 import 
org.apache.shardingsphere.database.connector.core.jdbcurl.parser.ConnectionProperties;
 import 
org.apache.shardingsphere.database.connector.core.jdbcurl.parser.ConnectionPropertiesParser;
+import 
org.apache.shardingsphere.database.connector.core.jdbcurl.parser.StandardJdbcUrlParser;
 
 import java.util.Arrays;
 import java.util.List;
@@ -37,6 +38,8 @@ public final class OracleConnectionPropertiesParser 
implements ConnectionPropert
     
     private static final int THIN_MATCH_GROUP_COUNT = 5;
     
+    private static final String QUERY_DELIMITER = "?";
+    
     private static final Pattern THIN_URL_PATTERN = 
Pattern.compile("jdbc:oracle:(thin|oci|kprb):@(//)?([\\w\\-\\.]+):?(\\d*)[:/]([\\w\\-]+)",
 Pattern.CASE_INSENSITIVE);
     
     private static final Pattern CONNECT_DESCRIPTOR_URL_PATTERN = 
Pattern.compile(
@@ -44,18 +47,20 @@ public final class OracleConnectionPropertiesParser 
implements ConnectionPropert
     
     @Override
     public ConnectionProperties parse(final String url, final String username, 
final String catalog) {
-        List<Matcher> matchers = Arrays.asList(THIN_URL_PATTERN.matcher(url), 
CONNECT_DESCRIPTOR_URL_PATTERN.matcher(url));
+        String urlWithoutQuery = url.contains(QUERY_DELIMITER) ? 
url.substring(0, url.indexOf(QUERY_DELIMITER)) : url;
+        Properties queryProps = url.contains(QUERY_DELIMITER) ? new 
StandardJdbcUrlParser().parseQueryProperties(url.substring(url.indexOf(QUERY_DELIMITER)
 + 1)) : new Properties();
+        List<Matcher> matchers = 
Arrays.asList(THIN_URL_PATTERN.matcher(urlWithoutQuery), 
CONNECT_DESCRIPTOR_URL_PATTERN.matcher(urlWithoutQuery));
         Matcher matcher = 
matchers.stream().filter(Matcher::find).findAny().orElseThrow(() -> new 
UnrecognizedDatabaseURLException(url, THIN_URL_PATTERN.pattern()));
         int groupCount = matcher.groupCount();
-        return THIN_MATCH_GROUP_COUNT == groupCount ? 
getThinConnectionProperties(username, matcher) : 
getStandardConnectionProperties(username, matcher);
+        return THIN_MATCH_GROUP_COUNT == groupCount ? 
getThinConnectionProperties(username, matcher, queryProps) : 
getStandardConnectionProperties(username, matcher, queryProps);
     }
     
-    private ConnectionProperties getThinConnectionProperties(final String 
username, final Matcher matcher) {
-        return new ConnectionProperties(matcher.group(3), 
Strings.isNullOrEmpty(matcher.group(4)) ? DEFAULT_PORT : 
Integer.parseInt(matcher.group(4)), matcher.group(5), username, new 
Properties());
+    private ConnectionProperties getThinConnectionProperties(final String 
username, final Matcher matcher, final Properties queryProps) {
+        return new ConnectionProperties(matcher.group(3), 
Strings.isNullOrEmpty(matcher.group(4)) ? DEFAULT_PORT : 
Integer.parseInt(matcher.group(4)), matcher.group(5), username, queryProps);
     }
     
-    private ConnectionProperties getStandardConnectionProperties(final String 
username, final Matcher matcher) {
-        return new ConnectionProperties(matcher.group(2), 
Integer.parseInt(matcher.group(3)), matcher.group(4), username, new 
Properties());
+    private ConnectionProperties getStandardConnectionProperties(final String 
username, final Matcher matcher, final Properties queryProps) {
+        return new ConnectionProperties(matcher.group(2), 
Integer.parseInt(matcher.group(3)), matcher.group(4), username, queryProps);
     }
     
     @Override
diff --git 
a/database/connector/dialect/oracle/src/test/java/org/apache/shardingsphere/database/connector/oracle/jdbcurl/OracleConnectionPropertiesParserTest.java
 
b/database/connector/dialect/oracle/src/test/java/org/apache/shardingsphere/database/connector/oracle/jdbcurl/OracleConnectionPropertiesParserTest.java
index 5db1e429113..a7308e152b6 100644
--- 
a/database/connector/dialect/oracle/src/test/java/org/apache/shardingsphere/database/connector/oracle/jdbcurl/OracleConnectionPropertiesParserTest.java
+++ 
b/database/connector/dialect/oracle/src/test/java/org/apache/shardingsphere/database/connector/oracle/jdbcurl/OracleConnectionPropertiesParserTest.java
@@ -23,6 +23,8 @@ import 
org.apache.shardingsphere.database.connector.core.jdbcurl.parser.Connecti
 import 
org.apache.shardingsphere.database.connector.core.spi.DatabaseTypedSPILoader;
 import org.apache.shardingsphere.database.connector.core.type.DatabaseType;
 import org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader;
+import org.apache.shardingsphere.infra.util.props.PropertiesBuilder;
+import org.apache.shardingsphere.infra.util.props.PropertiesBuilder.Property;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtensionContext;
 import org.junit.jupiter.params.ParameterizedTest;
@@ -31,12 +33,12 @@ import org.junit.jupiter.params.provider.ArgumentsProvider;
 import org.junit.jupiter.params.provider.ArgumentsSource;
 import org.junit.jupiter.params.support.ParameterDeclarations;
 
+import java.util.Properties;
 import java.util.stream.Stream;
 
-import static org.hamcrest.Matchers.is;
 import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
 import static org.junit.jupiter.api.Assertions.assertThrows;
-import static org.junit.jupiter.api.Assertions.assertTrue;
 
 class OracleConnectionPropertiesParserTest {
     
@@ -46,13 +48,13 @@ class OracleConnectionPropertiesParserTest {
     
     @ParameterizedTest(name = "{0}")
     @ArgumentsSource(NewConstructorTestCaseArgumentsProvider.class)
-    void assertNewConstructor(final String name, final String url, final 
String hostname, final int port, final String catalog, final String schema) {
+    void assertNewConstructor(final String name, final String url, final 
String hostname, final int port, final String catalog, final String schema, 
final Properties queryProps) {
         ConnectionProperties actual = parser.parse(url, "test", null);
         assertThat(actual.getHostname(), is(hostname));
         assertThat(actual.getPort(), is(port));
         assertThat(actual.getCatalog(), is(catalog));
         assertThat(actual.getSchema(), is(schema));
-        assertTrue(actual.getQueryProperties().isEmpty());
+        assertThat(actual.getQueryProperties(), is(queryProps));
     }
     
     @Test
@@ -65,22 +67,31 @@ class OracleConnectionPropertiesParserTest {
         @Override
         public Stream<? extends Arguments> provideArguments(final 
ParameterDeclarations parameters, final ExtensionContext context) {
             return Stream.of(
-                    Arguments.of("port", 
"jdbc:oracle:thin:@//127.0.0.1:9999/foo_ds", "127.0.0.1", 9999, "foo_ds", 
"test"),
-                    Arguments.of("domainPort", 
"jdbc:oracle:oci:@ax-xx.frex.cc:9999/foo_ds", "ax-xx.frex.cc", 9999, "foo_ds", 
"test"),
-                    Arguments.of("ipDefaultPort", 
"jdbc:oracle:oci:@127.0.0.1/foo_ds", "127.0.0.1", 1521, "foo_ds", "test"),
-                    Arguments.of("domainDefaultPort", 
"jdbc:oracle:oci:@axxx.frex.cc/foo_ds", "axxx.frex.cc", 1521, "foo_ds", "test"),
+                    Arguments.of("port", 
"jdbc:oracle:thin:@//127.0.0.1:9999/foo_ds", "127.0.0.1", 9999, "foo_ds", 
"test", new Properties()),
+                    Arguments.of("domainPort", 
"jdbc:oracle:oci:@ax-xx.frex.cc:9999/foo_ds", "ax-xx.frex.cc", 9999, "foo_ds", 
"test", new Properties()),
+                    Arguments.of("ipDefaultPort", 
"jdbc:oracle:oci:@127.0.0.1/foo_ds", "127.0.0.1", 1521, "foo_ds", "test", new 
Properties()),
+                    Arguments.of("domainDefaultPort", 
"jdbc:oracle:oci:@axxx.frex.cc/foo_ds", "axxx.frex.cc", 1521, "foo_ds", "test", 
new Properties()),
+                    Arguments.of("thinQueryProperties", 
"jdbc:oracle:thin:@//127.0.0.1:9999/foo_ds?oracle.jdbc.getObjectReturnsXMLType=true",
 "127.0.0.1", 9999, "foo_ds",
+                            "test", PropertiesBuilder.build(new 
Property("oracle.jdbc.getObjectReturnsXMLType", Boolean.TRUE.toString()))),
                     Arguments.of("connectDescriptorIpUrl", 
"jdbc:oracle:thin:@(DESCRIPTION =(ADDRESS = (PROTOCOL = TCP)(HOST = 
127.0.0.1)(PORT = 1521))(ADDRESS = (PROTOCOL = TCP)"
                             + "(HOST = 127.0.0.1)(PORT = 1521))(LOAD_BALANCE = 
yes)(FAILOVER = ON)(CONNECT_DATA =(SERVER = DEDICATED)"
-                            + "(SERVICE_NAME = rac)(FAILOVER_MODE=(TYPE = 
SELECT)(METHOD = BASIC)(RETIRES = 20)(DELAY = 15))))", "127.0.0.1", 1521, 
"rac", "test"),
+                            + "(SERVICE_NAME = rac)(FAILOVER_MODE=(TYPE = 
SELECT)(METHOD = BASIC)(RETIRES = 20)(DELAY = 15))))", "127.0.0.1", 1521, 
"rac", "test",
+                            new Properties()),
                     Arguments.of("connectDescriptorDomainUrl", 
"jdbc:oracle:thin:@(DESCRIPTION =(ADDRESS = (PROTOCOL = TCP)(HOST = 
axxx.frex.cc)(PORT = 1521))(ADDRESS = (PROTOCOL = TCP)"
                             + "(HOST = axxx.frex.cc)(PORT = 
1521))(LOAD_BALANCE = yes)(FAILOVER = ON)(CONNECT_DATA =(SERVER = DEDICATED)"
-                            + "(SERVICE_NAME = rac)(FAILOVER_MODE=(TYPE = 
SELECT)(METHOD = BASIC)(RETIRES = 20)(DELAY = 15))))", "axxx.frex.cc", 1521, 
"rac", "test"),
+                            + "(SERVICE_NAME = rac)(FAILOVER_MODE=(TYPE = 
SELECT)(METHOD = BASIC)(RETIRES = 20)(DELAY = 15))))", "axxx.frex.cc", 1521, 
"rac", "test",
+                            new Properties()),
                     Arguments.of("connectDescriptorHalfenDomainUrl", 
"jdbc:oracle:thin:@(DESCRIPTION =(ADDRESS = (PROTOCOL = TCP)(HOST = 
ax-xx.frex.cc)(PORT = 1521))(ADDRESS = (PROTOCOL = TCP)"
                             + "(HOST = ax-xx.frex.cc)(PORT = 
1521))(LOAD_BALANCE = yes)(FAILOVER = ON)(CONNECT_DATA =(SERVER = DEDICATED)"
-                            + "(SERVICE_NAME = rac)(FAILOVER_MODE=(TYPE = 
SELECT)(METHOD = BASIC)(RETIRES = 20)(DELAY = 15))))", "ax-xx.frex.cc", 1521, 
"rac", "test"),
+                            + "(SERVICE_NAME = rac)(FAILOVER_MODE=(TYPE = 
SELECT)(METHOD = BASIC)(RETIRES = 20)(DELAY = 15))))", "ax-xx.frex.cc", 1521, 
"rac", "test",
+                            new Properties()),
                     Arguments.of("connectDescriptorUrlWithExtraSpaces", 
"jdbc:oracle:thin:@(DESCRIPTION = description"
                             + "(HOST   =   127.0.0.1)(PORT   =  
1521))(LOAD_BALANCE = yes)(FAILOVER = ON)(CONNECT_DATA =(SERVER = DEDICATED)"
-                            + "(SERVICE_NAME   =   rac)(FAILOVER_MODE=(TYPE = 
SELECT)(METHOD = BASIC)(RETIRES = 20)(DELAY = 15))))", "127.0.0.1", 1521, 
"rac", "test"));
+                            + "(SERVICE_NAME   =   rac)(FAILOVER_MODE=(TYPE = 
SELECT)(METHOD = BASIC)(RETIRES = 20)(DELAY = 15))))", "127.0.0.1", 1521, 
"rac", "test",
+                            new Properties()),
+                    Arguments.of("connectDescriptorQueryProperties", 
"jdbc:oracle:thin:@(DESCRIPTION =(ADDRESS = (PROTOCOL = TCP)(HOST = 
127.0.0.1)(PORT = 1521))"
+                            + "(CONNECT_DATA =(SERVICE_NAME = 
rac)))?oracle.jdbc.getObjectReturnsXMLType=true", "127.0.0.1", 1521, "rac", 
"test",
+                            PropertiesBuilder.build(new 
Property("oracle.jdbc.getObjectReturnsXMLType", Boolean.TRUE.toString()))));
         }
     }
 }

Reply via email to