diff --git a/crates/dbx-core/src/agent_connection.rs b/crates/dbx-core/src/agent_connection.rs
index 5aa9672f5..9b5475ea4 100644
--- a/crates/dbx-core/src/agent_connection.rs
+++ b/crates/dbx-core/src/agent_connection.rs
@@ -59,6 +59,7 @@ pub fn agent_connect_params(config: &ConnectionConfig, host: &str, port: u16, da
"ca_cert_path": config.ca_cert_path,
"client_cert_path": config.client_cert_path,
"client_key_path": config.client_key_path,
+ "connect_timeout_secs": config.effective_connect_timeout_secs(),
"etcd_endpoints": etcd_endpoints,
"zookeeper_connect_string": zookeeper_connect_string,
"gbase_server": config.gbase_server,
@@ -734,6 +735,16 @@ mod tests {
assert_eq!(params["connection_timeout_ms"], 20_000);
}
+ #[test]
+ fn agent_params_include_effective_connect_timeout_seconds() {
+ let mut cfg = config(DatabaseType::Mysql, Some("app"));
+ cfg.connect_timeout_secs = 45;
+
+ let params = agent_connect_params(&cfg, "mysql.example.com", 3306, "app");
+
+ assert_eq!(params["connect_timeout_secs"], 45);
+ }
+
#[test]
fn zookeeper_agent_params_fall_back_to_host_port_connect_string() {
let cfg = config(DatabaseType::ZooKeeper, None);
diff --git a/plugins/jdbc/manifest.json b/plugins/jdbc/manifest.json
index d19a48d6d..5f45506a0 100644
--- a/plugins/jdbc/manifest.json
+++ b/plugins/jdbc/manifest.json
@@ -1,7 +1,7 @@
{
"id": "jdbc",
"name": "DBX JDBC Plugin",
- "version": "0.1.24",
+ "version": "0.1.25",
"protocol_version": 1,
"description": "Adds optional JDBC driver support to DBX.",
"executable": "bin/dbx-jdbc-plugin",
diff --git a/plugins/jdbc/pom.xml b/plugins/jdbc/pom.xml
index 88ad74a77..92607fdfb 100644
--- a/plugins/jdbc/pom.xml
+++ b/plugins/jdbc/pom.xml
@@ -4,7 +4,7 @@
4.0.0
app.dbx
dbx-jdbc-plugin
- 0.1.24
+ 0.1.25
17
diff --git a/plugins/jdbc/src/main/java/app/dbx/jdbc/DbxJdbcPlugin.java b/plugins/jdbc/src/main/java/app/dbx/jdbc/DbxJdbcPlugin.java
index a099e95c6..43381f200 100644
--- a/plugins/jdbc/src/main/java/app/dbx/jdbc/DbxJdbcPlugin.java
+++ b/plugins/jdbc/src/main/java/app/dbx/jdbc/DbxJdbcPlugin.java
@@ -554,7 +554,36 @@ public final class DbxJdbcPlugin {
}
String value = Integer.toString(connectTimeoutSecs);
properties.putIfAbsent("loginTimeout", value);
- properties.putIfAbsent("connectTimeout", value);
+ if (!jdbcUrlHasParameter(jdbcUrl(connection), "connectTimeout")) {
+ properties.putIfAbsent("connectTimeout", connectTimeoutPropertyValue(connection, connectTimeoutSecs));
+ }
+ }
+
+ private static String connectTimeoutPropertyValue(JsonNode connection, int connectTimeoutSecs) {
+ if (usesMillisecondConnectTimeout(connection)) {
+ return Integer.toString(connectTimeoutSecs * 1000);
+ }
+ return Integer.toString(connectTimeoutSecs);
+ }
+
+ private static boolean usesMillisecondConnectTimeout(JsonNode connection) {
+ String url = jdbcUrl(connection);
+ if (
+ urlMatchesPrefix(url, "jdbc:mysql:") ||
+ urlMatchesPrefix(url, "jdbc:mariadb:") ||
+ urlMatchesPrefix(url, "jdbc:starrocks:") ||
+ urlMatchesPrefix(url, "jdbc:doris:")
+ ) {
+ return true;
+ }
+ String driverClass = optionalText(connection, "jdbc_driver_class");
+ if (driverClass == null) {
+ return false;
+ }
+ String normalized = driverClass.toLowerCase(Locale.ROOT);
+ return normalized.equals("com.mysql.cj.jdbc.driver") ||
+ normalized.equals("com.mysql.jdbc.driver") ||
+ normalized.equals("org.mariadb.jdbc.driver");
}
private static boolean isPrestoOrTrinoConnection(JsonNode connection) {
@@ -2396,6 +2425,13 @@ public final class DbxJdbcPlugin {
}
private static boolean urlHasQueryParam(String url, String key) {
+ return jdbcUrlHasParameter(url, key);
+ }
+
+ private static boolean jdbcUrlHasParameter(String url, String key) {
+ if (url == null) {
+ return false;
+ }
int queryStart = url.indexOf('?');
if (queryStart < 0) {
return false;
diff --git a/plugins/jdbc/src/test/java/app/dbx/jdbc/DbxJdbcPluginTest.java b/plugins/jdbc/src/test/java/app/dbx/jdbc/DbxJdbcPluginTest.java
index 494d1178d..ab9bb5b72 100644
--- a/plugins/jdbc/src/test/java/app/dbx/jdbc/DbxJdbcPluginTest.java
+++ b/plugins/jdbc/src/test/java/app/dbx/jdbc/DbxJdbcPluginTest.java
@@ -485,6 +485,43 @@ final class DbxJdbcPluginTest {
assertEquals("45", properties.getProperty("connectTimeout"));
}
+ @Test
+ void mysqlConnectTimeoutSecondsAreMappedToMilliseconds() throws Exception {
+ Method method = DbxJdbcPlugin.class.getDeclaredMethod("applyConnectTimeout", JsonNode.class, Properties.class);
+ method.setAccessible(true);
+ Properties properties = new Properties();
+ JsonNode connection = MAPPER.readTree("""
+ {
+ "connection_string": "jdbc:mysql://ddb.example.test:6000/app",
+ "jdbc_driver_class": "com.mysql.cj.jdbc.Driver",
+ "connect_timeout_secs": 45
+ }
+ """);
+
+ method.invoke(null, connection, properties);
+
+ assertEquals("45", properties.getProperty("loginTimeout"));
+ assertEquals("45000", properties.getProperty("connectTimeout"));
+ }
+
+ @Test
+ void explicitJdbcUrlConnectTimeoutIsNotOverridden() throws Exception {
+ Method method = DbxJdbcPlugin.class.getDeclaredMethod("applyConnectTimeout", JsonNode.class, Properties.class);
+ method.setAccessible(true);
+ Properties properties = new Properties();
+ JsonNode connection = MAPPER.readTree("""
+ {
+ "connection_string": "jdbc:mysql://ddb.example.test:6000/app?connectTimeout=5000",
+ "connect_timeout_secs": 45
+ }
+ """);
+
+ method.invoke(null, connection, properties);
+
+ assertEquals("45", properties.getProperty("loginTimeout"));
+ assertFalse(properties.containsKey("connectTimeout"));
+ }
+
@Test
void jdbcxHighPrivilegeExtensionsAreDisabledByDefault() throws Exception {
Method method = DbxJdbcPlugin.class.getDeclaredMethod(