This is an automated email from the ASF dual-hosted git repository.
suxiaogang223 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 fd4f4b57fc3 [fix](fe) Detect Doris JDBC targets with stable server
identity (#68321)
fd4f4b57fc3 is described below
commit fd4f4b57fc3a9ee6a1693788b57a9c1711d000ed
Author: Socrates <[email protected]>
AuthorDate: Thu Sep 24 15:32:51 2026 +0800
[fix](fe) Detect Doris JDBC targets with stable server identity (#68321)
### What problem does this PR solve?
JDBC Catalog currently decides whether a MySQL-compatible endpoint is
Doris by parsing `version_comment`. That value is display text and may
change with product branding or packaging. When the expected marker is
absent, the endpoint is treated as MySQL and Doris-specific types can be
mapped incorrectly.
This change exposes a stable, read-only `doris_server_identity` session
variable with the value `apache_doris`. Both JDBC client implementations
probe this variable first and use exact identity matching. If the remote
endpoint does not expose the variable, they fall back to the existing
`version_comment` detection so older endpoints remain compatible.
The compatibility adjustment for existing enterprise version comments
remains a separate commit, allowing it to be reviewed or applied
independently.
### Release note
Use a stable server identity when detecting Doris JDBC endpoints, with
backward-compatible fallback for older endpoints.
### Check List (For Author)
- Test: Unit Test
- `./run-fe-ut.sh --run
org.apache.doris.datasource.jdbc.client.JdbcMySQLClientTest,org.apache.doris.connector.jdbc.client.JdbcMySQLConnectorClientTest`
- Both test classes passed: 4 tests total, 0 failures, 0 errors, 0
skipped
- FE build, checkstyle, and metadata funnel checks passed as part of the
test command
- Behavior changed: Yes. JDBC Catalog prefers the stable server identity
and falls back to the existing version comment probe when the identity
variable is unavailable.
- Does this need documentation: No
---
.../jdbc/client/JdbcMySQLConnectorClient.java | 18 +++++++++++++++---
.../jdbc/client/JdbcMySQLConnectorClientTest.java | 10 ++++++++++
.../doris/datasource/jdbc/client/JdbcMySQLClient.java | 19 ++++++++++++++++---
.../java/org/apache/doris/qe/SessionVariable.java | 5 +++++
.../datasource/jdbc/client/JdbcMySQLClientTest.java | 10 ++++++++++
5 files changed, 56 insertions(+), 6 deletions(-)
diff --git
a/fe/fe-connector/fe-connector-jdbc/src/main/java/org/apache/doris/connector/jdbc/client/JdbcMySQLConnectorClient.java
b/fe/fe-connector/fe-connector-jdbc/src/main/java/org/apache/doris/connector/jdbc/client/JdbcMySQLConnectorClient.java
index 9874d1b2460..992bf5b2b44 100644
---
a/fe/fe-connector/fe-connector-jdbc/src/main/java/org/apache/doris/connector/jdbc/client/JdbcMySQLConnectorClient.java
+++
b/fe/fe-connector/fe-connector-jdbc/src/main/java/org/apache/doris/connector/jdbc/client/JdbcMySQLConnectorClient.java
@@ -47,6 +47,7 @@ import java.util.function.Consumer;
public class JdbcMySQLConnectorClient extends JdbcConnectorClient {
private static final Logger LOG =
LogManager.getLogger(JdbcMySQLConnectorClient.class);
+ private static final String APACHE_DORIS_SERVER_IDENTITY = "apache_doris";
private final boolean convertDateToNull;
private boolean isDoris = false;
@@ -76,10 +77,15 @@ public class JdbcMySQLConnectorClient extends
JdbcConnectorClient {
try {
conn = getConnection();
stmt = conn.createStatement();
- rs = stmt.executeQuery("SHOW VARIABLES LIKE 'version_comment'");
+ rs = stmt.executeQuery("SHOW VARIABLES LIKE 'server_identity'");
if (rs.next()) {
- String versionComment = rs.getString("Value");
- isDoris = isDorisCompatibleVersionComment(versionComment);
+ isDoris = isDorisServerIdentity(rs.getString("Value"));
+ } else {
+ closeResources(rs);
+ rs = stmt.executeQuery("SHOW VARIABLES LIKE
'version_comment'");
+ if (rs.next()) {
+ isDoris =
isDorisCompatibleVersionComment(rs.getString("Value"));
+ }
}
} catch (Exception e) {
LOG.warn("Failed to detect if remote MySQL is Doris: {}",
e.getMessage());
@@ -88,14 +94,20 @@ public class JdbcMySQLConnectorClient extends
JdbcConnectorClient {
}
}
+ static boolean isDorisServerIdentity(String serverIdentity) {
+ return APACHE_DORIS_SERVER_IDENTITY.equalsIgnoreCase(serverIdentity);
+ }
+
static boolean isDorisCompatibleVersionComment(String versionComment) {
if (versionComment == null || versionComment.isEmpty()) {
return false;
}
String lowerVersionComment = versionComment.toLowerCase(Locale.ROOT);
+ // Enterprise releases can omit the optional "(Cloud Mode)" suffix.
return lowerVersionComment.contains("doris")
|| lowerVersionComment.contains("selectdb")
|| lowerVersionComment.contains("velodb")
+ || lowerVersionComment.contains("enterprise version
enterprise-")
|| (lowerVersionComment.contains("enterprise version")
&& lowerVersionComment.contains("cloud mode"));
}
diff --git
a/fe/fe-connector/fe-connector-jdbc/src/test/java/org/apache/doris/connector/jdbc/client/JdbcMySQLConnectorClientTest.java
b/fe/fe-connector/fe-connector-jdbc/src/test/java/org/apache/doris/connector/jdbc/client/JdbcMySQLConnectorClientTest.java
index 5cb178a9268..772108a5b72 100644
---
a/fe/fe-connector/fe-connector-jdbc/src/test/java/org/apache/doris/connector/jdbc/client/JdbcMySQLConnectorClientTest.java
+++
b/fe/fe-connector/fe-connector-jdbc/src/test/java/org/apache/doris/connector/jdbc/client/JdbcMySQLConnectorClientTest.java
@@ -22,6 +22,14 @@ import org.junit.jupiter.api.Test;
public class JdbcMySQLConnectorClientTest {
+ @Test
+ void testIsDorisServerIdentity() {
+
Assertions.assertTrue(JdbcMySQLConnectorClient.isDorisServerIdentity("apache_doris"));
+
Assertions.assertTrue(JdbcMySQLConnectorClient.isDorisServerIdentity("APACHE_DORIS"));
+
Assertions.assertFalse(JdbcMySQLConnectorClient.isDorisServerIdentity("mysql"));
+
Assertions.assertFalse(JdbcMySQLConnectorClient.isDorisServerIdentity(null));
+ }
+
@Test
void testIsDorisCompatibleVersionComment() {
Assertions.assertTrue(JdbcMySQLConnectorClient.isDorisCompatibleVersionComment(
@@ -32,6 +40,8 @@ public class JdbcMySQLConnectorClientTest {
"VeloDB version 2.1.0"));
Assertions.assertTrue(JdbcMySQLConnectorClient.isDorisCompatibleVersionComment(
"enterprise version enterprise-4.0.5-rc01-0724569463d (Cloud
Mode)"));
+
Assertions.assertTrue(JdbcMySQLConnectorClient.isDorisCompatibleVersionComment(
+ "enterprise version enterprise-current"));
Assertions.assertFalse(JdbcMySQLConnectorClient.isDorisCompatibleVersionComment(
"MySQL Community Server - GPL"));
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/datasource/jdbc/client/JdbcMySQLClient.java
b/fe/fe-core/src/main/java/org/apache/doris/datasource/jdbc/client/JdbcMySQLClient.java
index bcdc9ccc03b..c3233c859a3 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/datasource/jdbc/client/JdbcMySQLClient.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/datasource/jdbc/client/JdbcMySQLClient.java
@@ -45,6 +45,8 @@ import java.util.function.Consumer;
public class JdbcMySQLClient extends JdbcClient {
+ private static final String APACHE_DORIS_SERVER_IDENTITY = "apache_doris";
+
private boolean convertDateToNull = false;
private boolean isDoris = false;
@@ -57,10 +59,15 @@ public class JdbcMySQLClient extends JdbcClient {
try {
conn = super.getConnection();
stmt = conn.createStatement();
- rs = stmt.executeQuery("SHOW VARIABLES LIKE 'version_comment'");
+ rs = stmt.executeQuery("SHOW VARIABLES LIKE 'server_identity'");
if (rs.next()) {
- String versionComment = rs.getString("Value");
- isDoris = isDorisCompatibleVersionComment(versionComment);
+ isDoris = isDorisServerIdentity(rs.getString("Value"));
+ } else {
+ close(rs);
+ rs = stmt.executeQuery("SHOW VARIABLES LIKE
'version_comment'");
+ if (rs.next()) {
+ isDoris =
isDorisCompatibleVersionComment(rs.getString("Value"));
+ }
}
} catch (SQLException | JdbcClientException e) {
closeClient();
@@ -76,14 +83,20 @@ public class JdbcMySQLClient extends JdbcClient {
this.dbType = dbType;
}
+ static boolean isDorisServerIdentity(String serverIdentity) {
+ return APACHE_DORIS_SERVER_IDENTITY.equalsIgnoreCase(serverIdentity);
+ }
+
static boolean isDorisCompatibleVersionComment(String versionComment) {
if (Strings.isNullOrEmpty(versionComment)) {
return false;
}
String lowerVersionComment = versionComment.toLowerCase(Locale.ROOT);
+ // Enterprise releases can omit the optional "(Cloud Mode)" suffix.
return lowerVersionComment.contains("doris")
|| lowerVersionComment.contains("selectdb")
|| lowerVersionComment.contains("velodb")
+ || lowerVersionComment.contains("enterprise version
enterprise-")
|| (lowerVersionComment.contains("enterprise version")
&& lowerVersionComment.contains("cloud mode"));
}
diff --git a/fe/fe-core/src/main/java/org/apache/doris/qe/SessionVariable.java
b/fe/fe-core/src/main/java/org/apache/doris/qe/SessionVariable.java
index c0c995e4817..e6ee9525c24 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/qe/SessionVariable.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/qe/SessionVariable.java
@@ -164,6 +164,8 @@ public class SessionVariable implements Serializable,
Writable {
public static final String SQL_SAFE_UPDATES = "sql_safe_updates";
public static final String NET_BUFFER_LENGTH = "net_buffer_length";
public static final String HAVE_QUERY_CACHE = "have_query_cache";
+ public static final String SERVER_IDENTITY = "server_identity";
+ public static final String APACHE_DORIS_SERVER_IDENTITY = "apache_doris";
// mem limit can't smaller than bufferpool's default page size
public static final int MIN_EXEC_MEM_LIMIT = 2097152;
public static final String BATCH_SIZE = "batch_size";
@@ -1385,6 +1387,9 @@ public class SessionVariable implements Serializable,
Writable {
@VarAttrDef.VarAttr(name = HAVE_QUERY_CACHE, flag = VarAttrDef.READ_ONLY)
public boolean haveQueryCache = false;
+ @VarAttrDef.VarAttr(name = SERVER_IDENTITY, flag = VarAttrDef.READ_ONLY)
+ public String serverIdentity = APACHE_DORIS_SERVER_IDENTITY;
+
// 8192 minus 16 + 16 bytes padding that in padding pod array.
// This remains the row cap for output blocks even when adaptive byte
budgeting is enabled.
@VarAttrDef.VarAttr(name = BATCH_SIZE, fuzzy = true, checker =
"checkBatchSize", needForward = true)
diff --git
a/fe/fe-core/src/test/java/org/apache/doris/datasource/jdbc/client/JdbcMySQLClientTest.java
b/fe/fe-core/src/test/java/org/apache/doris/datasource/jdbc/client/JdbcMySQLClientTest.java
index 6379c0db52a..375bb4f2e03 100644
---
a/fe/fe-core/src/test/java/org/apache/doris/datasource/jdbc/client/JdbcMySQLClientTest.java
+++
b/fe/fe-core/src/test/java/org/apache/doris/datasource/jdbc/client/JdbcMySQLClientTest.java
@@ -22,6 +22,14 @@ import org.junit.jupiter.api.Test;
public class JdbcMySQLClientTest {
+ @Test
+ public void testIsDorisServerIdentity() {
+
Assertions.assertTrue(JdbcMySQLClient.isDorisServerIdentity("apache_doris"));
+
Assertions.assertTrue(JdbcMySQLClient.isDorisServerIdentity("APACHE_DORIS"));
+ Assertions.assertFalse(JdbcMySQLClient.isDorisServerIdentity("mysql"));
+ Assertions.assertFalse(JdbcMySQLClient.isDorisServerIdentity(null));
+ }
+
@Test
public void testIsDorisCompatibleVersionComment() {
Assertions.assertTrue(JdbcMySQLClient.isDorisCompatibleVersionComment("Apache
Doris version 3.1.0"));
@@ -29,6 +37,8 @@ public class JdbcMySQLClientTest {
Assertions.assertTrue(JdbcMySQLClient.isDorisCompatibleVersionComment("VeloDB
version 2.1.0"));
Assertions.assertTrue(JdbcMySQLClient.isDorisCompatibleVersionComment(
"enterprise version enterprise-4.0.5-rc01-0724569463d (Cloud
Mode)"));
+ Assertions.assertTrue(JdbcMySQLClient.isDorisCompatibleVersionComment(
+ "enterprise version enterprise-current"));
Assertions.assertFalse(JdbcMySQLClient.isDorisCompatibleVersionComment("MySQL
Community Server - GPL"));
Assertions.assertFalse(JdbcMySQLClient.isDorisCompatibleVersionComment(""));
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]