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]