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

zhangstar333 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/master by this push:
     new 647d5a77881 [bug](jdbc) fix sqlserver couldn't get schema with higher 
version driver jar (#63626)
647d5a77881 is described below

commit 647d5a7788146bd8aa42cf1a0bdedecfda7b0615
Author: zhangstar333 <[email protected]>
AuthorDate: Tue May 26 11:16:40 2026 +0800

    [bug](jdbc) fix sqlserver couldn't get schema with higher version driver 
jar (#63626)
    
    ### What problem does this PR solve?
    Problem Summary:
    
    
https://github.com/microsoft/mssql-jdbc/blob/v13.4.0/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerDatabaseMetaData.java#L1887-L1934
    ```
    SQLServer JDBC catalog lists schemas through 
DatabaseMetaData.getSchemas(conn.getCatalog(), null). With mssql-jdbc 13.4.x, 
when catalog is non-empty and schemaPattern is null, the
    driver filters built-in schemas such as dbo, guest, sys, 
INFORMATION_SCHEMA, and db_*. As a result, SHOW DATABASES on a SQLServer JDBC 
catalog may miss schemas that were visible with
    older mssql-jdbc versions.
    
    Now SQLServer-specific override for schema discovery and passes 
schemaPattern % to getSchemas. % is the JDBC wildcard pattern for matching all 
schemas, so mssql-jdbc 13.4.x
    returns the expected schemas without the driver-side built-in schema 
filtering. Older mssql-jdbc versions are also compatible with this behavior.
    ```
---
 be/src/service/internal_service.cpp                      |  7 +++++++
 .../doris/connector/jdbc/client/JdbcConnectorClient.java | 14 +++++++++++++-
 .../jdbc/client/JdbcSQLServerConnectorClient.java        |  7 +++++++
 .../jdbc/client/JdbcSQLServerConnectorClientTest.java    |  7 +++++++
 .../apache/doris/datasource/jdbc/client/JdbcClient.java  | 14 +++++++++++++-
 .../datasource/jdbc/client/JdbcSQLServerClient.java      |  7 +++++++
 .../type_test/select/test_sqlserver_all_types_select.out | 16 ++++++++++++++++
 .../select/test_sqlserver_all_types_select.groovy        | 14 ++++++++++++++
 8 files changed, 84 insertions(+), 2 deletions(-)

diff --git a/be/src/service/internal_service.cpp 
b/be/src/service/internal_service.cpp
index 2e6754c103a..057181ec80e 100644
--- a/be/src/service/internal_service.cpp
+++ b/be/src/service/internal_service.cpp
@@ -991,6 +991,13 @@ void 
PInternalService::test_jdbc_connection(google::protobuf::RpcController* con
                                             const PJdbcTestConnectionRequest* 
request,
                                             PJdbcTestConnectionResult* result,
                                             google::protobuf::Closure* done) {
+    if (!doris::config::enable_java_support) {
+        doris::Status status = doris::Status::InternalError(
+                "you can change be config enable_java_support to true and 
restart be.");
+        status.to_protobuf(result->mutable_status());
+        done->Run();
+        return;
+    }
     bool ret = _heavy_work_pool.try_offer([request, result, done]() {
         VLOG_RPC << "test jdbc connection";
         brpc::ClosureGuard closure_guard(done);
diff --git 
a/fe/fe-connector/fe-connector-jdbc/src/main/java/org/apache/doris/connector/jdbc/client/JdbcConnectorClient.java
 
b/fe/fe-connector/fe-connector-jdbc/src/main/java/org/apache/doris/connector/jdbc/client/JdbcConnectorClient.java
index 4adb567a846..03dbaa3ab76 100644
--- 
a/fe/fe-connector/fe-connector-jdbc/src/main/java/org/apache/doris/connector/jdbc/client/JdbcConnectorClient.java
+++ 
b/fe/fe-connector/fe-connector-jdbc/src/main/java/org/apache/doris/connector/jdbc/client/JdbcConnectorClient.java
@@ -352,7 +352,7 @@ public abstract class JdbcConnectorClient implements 
Closeable {
                 String current = conn.getSchema();
                 names.add(current);
             } else {
-                rs = conn.getMetaData().getSchemas(conn.getCatalog(), null);
+                rs = conn.getMetaData().getSchemas(conn.getCatalog(), 
getSchemaPatternForDatabaseNameList());
                 while (rs.next()) {
                     names.add(rs.getString("TABLE_SCHEM"));
                 }
@@ -365,6 +365,18 @@ public abstract class JdbcConnectorClient implements 
Closeable {
         return filterDatabaseNames(names);
     }
 
+    /**
+     * Schema pattern passed to {@link 
java.sql.DatabaseMetaData#getSchemas(String, String)} when listing
+     * remote database names.
+     *
+     * <p>The default {@code null} follows JDBC semantics of "schema name 
should not be used to narrow
+     * the search", preserving the existing generic behavior. Subclasses 
should override this only when
+     * a driver treats {@code null} specially and does not return the schemas 
Doris expects.
+     */
+    protected String getSchemaPatternForDatabaseNameList() {
+        return null;
+    }
+
     public List<String> getTablesNameList(String remoteDbName) {
         List<String> names = new ArrayList<>();
         String[] tableTypes = getTableTypes();
diff --git 
a/fe/fe-connector/fe-connector-jdbc/src/main/java/org/apache/doris/connector/jdbc/client/JdbcSQLServerConnectorClient.java
 
b/fe/fe-connector/fe-connector-jdbc/src/main/java/org/apache/doris/connector/jdbc/client/JdbcSQLServerConnectorClient.java
index a61d25803e0..73d1efdfcf1 100644
--- 
a/fe/fe-connector/fe-connector-jdbc/src/main/java/org/apache/doris/connector/jdbc/client/JdbcSQLServerConnectorClient.java
+++ 
b/fe/fe-connector/fe-connector-jdbc/src/main/java/org/apache/doris/connector/jdbc/client/JdbcSQLServerConnectorClient.java
@@ -110,6 +110,13 @@ public class JdbcSQLServerConnectorClient extends 
JdbcConnectorClient {
         }
     }
 
+    @Override
+    protected String getSchemaPatternForDatabaseNameList() {
+        // "%" is a JDBC schemaPattern wildcard that matches all schemas. 
mssql-jdbc 13.4 filters
+        // built-in schemas when catalog is non-empty and schemaPattern is 
null.
+        return "%";
+    }
+
     @Override
     public long getRowCount(String dbName, String tableName) {
         String sql = "SELECT sum(rows) FROM sys.partitions "
diff --git 
a/fe/fe-connector/fe-connector-jdbc/src/test/java/org/apache/doris/connector/jdbc/client/JdbcSQLServerConnectorClientTest.java
 
b/fe/fe-connector/fe-connector-jdbc/src/test/java/org/apache/doris/connector/jdbc/client/JdbcSQLServerConnectorClientTest.java
index 3ee4618808d..513e49bbe63 100644
--- 
a/fe/fe-connector/fe-connector-jdbc/src/test/java/org/apache/doris/connector/jdbc/client/JdbcSQLServerConnectorClientTest.java
+++ 
b/fe/fe-connector/fe-connector-jdbc/src/test/java/org/apache/doris/connector/jdbc/client/JdbcSQLServerConnectorClientTest.java
@@ -127,4 +127,11 @@ public class JdbcSQLServerConnectorClientTest {
         Assertions.assertEquals("STRING", ct.getTypeName(),
                 "SQL Server timestamp (rowversion) should map to STRING");
     }
+
+    @Test
+    void testUseWildcardSchemaPatternForDatabaseNameList() {
+        JdbcSQLServerConnectorClient client = createClient();
+
+        Assertions.assertEquals("%", 
client.getSchemaPatternForDatabaseNameList());
+    }
 }
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/datasource/jdbc/client/JdbcClient.java
 
b/fe/fe-core/src/main/java/org/apache/doris/datasource/jdbc/client/JdbcClient.java
index 7fa454d7813..8b496f82dd7 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/datasource/jdbc/client/JdbcClient.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/datasource/jdbc/client/JdbcClient.java
@@ -318,7 +318,7 @@ public abstract class JdbcClient {
                 String currentDatabase = conn.getSchema();
                 remoteDatabaseNames.add(currentDatabase);
             } else {
-                rs = conn.getMetaData().getSchemas(conn.getCatalog(), null);
+                rs = conn.getMetaData().getSchemas(conn.getCatalog(), 
getSchemaPatternForDatabaseNameList());
                 while (rs.next()) {
                     remoteDatabaseNames.add(rs.getString("TABLE_SCHEM"));
                 }
@@ -331,6 +331,18 @@ public abstract class JdbcClient {
         return filterDatabaseNames(remoteDatabaseNames);
     }
 
+    /**
+     * Schema pattern passed to {@link 
java.sql.DatabaseMetaData#getSchemas(String, String)} when listing
+     * remote database names.
+     *
+     * <p>The default {@code null} follows JDBC semantics of "schema name 
should not be used to narrow
+     * the search", preserving the existing generic behavior. Subclasses 
should override this only when
+     * a driver treats {@code null} specially and does not return the schemas 
Doris expects.
+     */
+    protected String getSchemaPatternForDatabaseNameList() {
+        return null;
+    }
+
     /**
      * get all tables of one database
      */
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/datasource/jdbc/client/JdbcSQLServerClient.java
 
b/fe/fe-core/src/main/java/org/apache/doris/datasource/jdbc/client/JdbcSQLServerClient.java
index d4cb6a092ad..50cd5ed9244 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/datasource/jdbc/client/JdbcSQLServerClient.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/datasource/jdbc/client/JdbcSQLServerClient.java
@@ -27,6 +27,13 @@ public class JdbcSQLServerClient extends JdbcClient {
         super(jdbcClientConfig);
     }
 
+    @Override
+    protected String getSchemaPatternForDatabaseNameList() {
+        // "%" is a JDBC schemaPattern wildcard that matches all schemas. 
mssql-jdbc 13.4 filters
+        // built-in schemas when catalog is non-empty and schemaPattern is 
null.
+        return "%";
+    }
+
     @Override
     protected Type jdbcTypeToDoris(JdbcFieldSchema fieldSchema) {
         String originSqlserverType = 
fieldSchema.getDataTypeName().orElse("unknown");
diff --git 
a/regression-test/data/external_table_p0/jdbc/type_test/select/test_sqlserver_all_types_select.out
 
b/regression-test/data/external_table_p0/jdbc/type_test/select/test_sqlserver_all_types_select.out
index 400710b308e..c83261743d7 100644
--- 
a/regression-test/data/external_table_p0/jdbc/type_test/select/test_sqlserver_all_types_select.out
+++ 
b/regression-test/data/external_table_p0/jdbc/type_test/select/test_sqlserver_all_types_select.out
@@ -53,3 +53,19 @@ IPv6_Nullable        text    Yes     true    \N
 -- !select_all_types_multi_block --
 4100
 
+-- !order_show_db --
+db_accessadmin
+db_backupoperator
+db_datareader
+db_datawriter
+db_ddladmin
+db_denydatareader
+db_denydatawriter
+db_owner
+db_securityadmin
+dbo
+guest
+information_schema
+mysql
+sys
+
diff --git 
a/regression-test/suites/external_table_p0/jdbc/type_test/select/test_sqlserver_all_types_select.groovy
 
b/regression-test/suites/external_table_p0/jdbc/type_test/select/test_sqlserver_all_types_select.groovy
index 66b648d9164..98bc1eee058 100644
--- 
a/regression-test/suites/external_table_p0/jdbc/type_test/select/test_sqlserver_all_types_select.groovy
+++ 
b/regression-test/suites/external_table_p0/jdbc/type_test/select/test_sqlserver_all_types_select.groovy
@@ -21,6 +21,7 @@ suite("test_sqlserver_all_types_select", "p0,external") {
     String s3_endpoint = getS3Endpoint()
     String bucket = getS3BucketName()
     String driver_url = 
"https://${bucket}.${s3_endpoint}/regression/jdbc_driver/mssql-jdbc-11.2.3.jre8.jar";
+    String driver_url13 = 
"https://${bucket}.${s3_endpoint}/regression/jdbc_driver/mssql-jdbc-13.4.0.jre8.jar";
     if (enabled != null && enabled.equalsIgnoreCase("true")) {
         String sqlserver_port = 
context.config.otherConfigs.get("sqlserver_2022_port");
 
@@ -43,5 +44,18 @@ suite("test_sqlserver_all_types_select", "p0,external") {
         qt_select_all_types_multi_block """select count(*) from 
dbo.extreme_test_multi_block;"""
 
         sql """drop catalog if exists sqlserver_all_type_test """
+
+        sql """drop catalog if exists sqlserver_13_test """
+        sql """create catalog if not exists sqlserver_13_test properties(
+                    "type"="jdbc",
+                    "user"="sa",
+                    "password"="Doris123456",
+                    "jdbc_url" = 
"jdbc:sqlserver://${externalEnvIp}:${sqlserver_port};encrypt=false;databaseName=doris_test;",
+                    "driver_url" = "${driver_url13}",
+                    "driver_class" = 
"com.microsoft.sqlserver.jdbc.SQLServerDriver"
+        );"""
+        sql """switch sqlserver_13_test"""
+        qt_order_show_db """show databases"""
+        sql """drop catalog if exists sqlserver_13_test """
     }
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to