From ffe535e40e35e6b20d554461965d174e4ba71558 Mon Sep 17 00:00:00 2001 From: t8y2 <1156263951@qq.com> Date: Thu, 18 Jun 2026 17:00:44 +0800 Subject: [PATCH] fix(jdbc): avoid default max rows rewrite --- crates/dbx-core/src/data_compare.rs | 2 +- crates/dbx-core/src/database_search_sql.rs | 2 +- crates/dbx-core/src/query_result_sql.rs | 2 +- .../dbx-core/src/sql_dialect/table_select.rs | 6 +-- .../main/java/app/dbx/jdbc/DbxJdbcPlugin.java | 2 +- .../java/app/dbx/jdbc/DbxJdbcPluginTest.java | 38 ++++++++++++++++++- 6 files changed, 43 insertions(+), 9 deletions(-) diff --git a/crates/dbx-core/src/data_compare.rs b/crates/dbx-core/src/data_compare.rs index 747a3a058..c79b9ea4a 100644 --- a/crates/dbx-core/src/data_compare.rs +++ b/crates/dbx-core/src/data_compare.rs @@ -787,7 +787,7 @@ fn build_data_compare_select_sql( ); } - // JDBC connections rely on Statement.setMaxRows() for row limiting. + // JDBC connections avoid SQL-level LIMIT; the agent truncates rows while reading. if database_type == DatabaseType::Jdbc { return format!("SELECT {select_columns} FROM {table}{order_by};"); } diff --git a/crates/dbx-core/src/database_search_sql.rs b/crates/dbx-core/src/database_search_sql.rs index c80d02f7b..109a21b79 100644 --- a/crates/dbx-core/src/database_search_sql.rs +++ b/crates/dbx-core/src/database_search_sql.rs @@ -112,7 +112,7 @@ pub fn build_database_search_sql(options: DatabaseSearchSqlOptions) -> Option QuerySqlB return ok(add_fetch_first_limit(&statement, safe_limit, safe_offset)); } - // JDBC connections rely on Statement.setMaxRows() for row limiting. + // JDBC connections avoid SQL-level LIMIT; the agent truncates rows while reading. if options.database_type == Some(DatabaseType::Jdbc) { return ok(format!("{statement};")); } diff --git a/crates/dbx-core/src/sql_dialect/table_select.rs b/crates/dbx-core/src/sql_dialect/table_select.rs index ce09301b7..9d539abd5 100644 --- a/crates/dbx-core/src/sql_dialect/table_select.rs +++ b/crates/dbx-core/src/sql_dialect/table_select.rs @@ -121,8 +121,8 @@ pub fn build_table_data_select_sql(options: TableDataSelectSqlOptions) -> String let offset = options.offset.filter(|offset| *offset > 0).map(|offset| format!(" OFFSET {offset}")).unwrap_or_default(); - // JDBC connections rely on Statement.setMaxRows() for row limiting instead of - // SQL-level LIMIT, which is not universally supported across all JDBC drivers. + // JDBC connections avoid SQL-level LIMIT because it is not universally + // supported across all JDBC drivers; the agent truncates rows while reading. if database_type == Some(DatabaseType::Jdbc) { return format!("SELECT {select_columns} FROM {table_alias}{where_clause}{order};"); } @@ -173,7 +173,7 @@ pub fn build_table_select_sql(options: TableSelectSqlOptions<'_>) -> String { return format!("SELECT TOP ({limit}) {select_columns} FROM {table}{order_by}"); } - // JDBC connections rely on Statement.setMaxRows() for row limiting. + // JDBC connections avoid SQL-level LIMIT; the agent truncates rows while reading. if database_type == Some(DatabaseType::Jdbc) { return format!("SELECT {select_columns} FROM {table}{order_by};"); } 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 c001d90de..f670c507a 100644 --- a/plugins/jdbc/src/main/java/app/dbx/jdbc/DbxJdbcPlugin.java +++ b/plugins/jdbc/src/main/java/app/dbx/jdbc/DbxJdbcPlugin.java @@ -60,7 +60,7 @@ public final class DbxJdbcPlugin { false, false, false, - StatementMaxRowsMode.APPLY_STATEMENT_MAX_ROWS + StatementMaxRowsMode.READ_LOOP_ONLY ); private static final JdbcDriverQuirks USE_CATALOG_QUIRKS = DEFAULT_QUIRKS.withUseCatalogFallbackSql(true); private static final JdbcDriverQuirks KINGBASE_QUIRKS = DEFAULT_QUIRKS.withIgnoreCatalogForSchemaMetadata(true); 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 bee094732..ceda6956d 100644 --- a/plugins/jdbc/src/test/java/app/dbx/jdbc/DbxJdbcPluginTest.java +++ b/plugins/jdbc/src/test/java/app/dbx/jdbc/DbxJdbcPluginTest.java @@ -328,6 +328,11 @@ final class DbxJdbcPluginTest { "connection_string": "jdbc:h2:mem:dbx_quirks" } """); + JsonNode cache = MAPPER.readTree(""" + { + "connection_string": "jdbc:Cache://127.0.0.1:1972/USER" + } + """); JsonNode mysql = MAPPER.readTree(""" { "connection_string": "jdbc:mysql://127.0.0.1:9030/demo" @@ -363,9 +368,13 @@ final class DbxJdbcPluginTest { assertEquals(false, DbxJdbcPlugin.driverQuirks(h2).caseInsensitiveSchemaMetadata()); assertEquals(false, DbxJdbcPlugin.driverQuirks(h2).useCatalogFallbackSql()); assertEquals( - DbxJdbcPlugin.StatementMaxRowsMode.APPLY_STATEMENT_MAX_ROWS, + DbxJdbcPlugin.StatementMaxRowsMode.READ_LOOP_ONLY, DbxJdbcPlugin.driverQuirks(h2).statementMaxRowsMode() ); + assertEquals( + DbxJdbcPlugin.StatementMaxRowsMode.READ_LOOP_ONLY, + DbxJdbcPlugin.driverQuirks(cache).statementMaxRowsMode() + ); assertEquals(true, DbxJdbcPlugin.driverQuirks(mysql).useCatalogFallbackSql()); assertEquals(true, DbxJdbcPlugin.driverQuirks(kingbase).ignoreCatalogForSchemaMetadata()); assertEquals(true, DbxJdbcPlugin.driverQuirks(kyuubi).useCatalogFallbackSql()); @@ -398,7 +407,7 @@ final class DbxJdbcPluginTest { } @Test - void defaultStatementOptionsApplyDriverMaxRowsProtection() throws Exception { + void defaultStatementOptionsSkipDriverMaxRowsRewrite() throws Exception { Method method = DbxJdbcPlugin.class.getDeclaredMethod( "applyStatementOptions", Statement.class, @@ -417,6 +426,31 @@ final class DbxJdbcPluginTest { method.invoke(null, recordingStatement(calls), 100, 50, 30, DbxJdbcPlugin.driverQuirks(h2)); + assertFalse(calls.contains("setMaxRows"), calls.toString()); + assertEquals(true, calls.contains("setFetchSize")); + assertEquals(true, calls.contains("setQueryTimeout")); + } + + @Test + void optInStatementOptionsCanApplyDriverMaxRowsProtection() throws Exception { + Method method = DbxJdbcPlugin.class.getDeclaredMethod( + "applyStatementOptions", + Statement.class, + int.class, + int.class, + int.class, + DbxJdbcPlugin.JdbcDriverQuirks.class + ); + method.setAccessible(true); + JsonNode yashan = MAPPER.readTree(""" + { + "connection_string": "jdbc:yasdb://127.0.0.1:1688/yasdb" + } + """); + List calls = new ArrayList<>(); + + method.invoke(null, recordingStatement(calls), 100, 50, 30, DbxJdbcPlugin.driverQuirks(yashan)); + assertEquals(true, calls.contains("setMaxRows")); assertEquals(true, calls.contains("setFetchSize")); assertEquals(true, calls.contains("setQueryTimeout"));