diff --git a/crates/dbx-core/src/query_result_sql.rs b/crates/dbx-core/src/query_result_sql.rs index ad1081fe0a..09515b6a48 100644 --- a/crates/dbx-core/src/query_result_sql.rs +++ b/crates/dbx-core/src/query_result_sql.rs @@ -321,6 +321,9 @@ fn has_top_level_select_into(sql: &str) -> bool { } fn add_sql_server_top(sql: &str, limit: usize) -> String { + if has_top_level_select_top(sql) { + return sql.to_string(); + } if sql.len() >= 6 && sql[..6].to_ascii_uppercase() == "SELECT" { format!("SELECT TOP ({limit}){}", &sql[6..]) } else { @@ -588,6 +591,19 @@ mod tests { assert_eq!(result.sql.unwrap(), "SELECT TOP (100) COUNT(*) FROM TicketInfo"); } + #[test] + fn keeps_existing_sqlserver_top_clause() { + let result = build_paginated_query_sql(PaginatedQuerySqlOptions { + original_sql: "SELECT TOP 1000 * FROM TicketInfo".to_string(), + database_type: Some(DatabaseType::SqlServer), + limit: 100, + offset: 0, + }); + + assert_eq!(result.ok, true); + assert_eq!(result.sql.unwrap(), "SELECT TOP 1000 * FROM TicketInfo"); + } + #[test] fn wraps_sqlserver_select_with_unnamed_column() { let result = build_paginated_query_sql(PaginatedQuerySqlOptions { diff --git a/packages/app-tests/queryResultSqlBackend.test.ts b/packages/app-tests/queryResultSqlBackend.test.ts index a95a180684..98e6f2df8c 100644 --- a/packages/app-tests/queryResultSqlBackend.test.ts +++ b/packages/app-tests/queryResultSqlBackend.test.ts @@ -43,3 +43,9 @@ test("Rust backends register query result SQL builders", () => { assert.match(webMainSource, /\/query\/prepare-pagination-plan/); assert.match(webMainSource, /\/query\/build-sorted-sql/); }); + +test("SQL Server pagination keeps user-provided TOP clauses", () => { + assert.match(rustQueryResultSqlSource, /fn add_sql_server_top/); + assert.match(rustQueryResultSqlSource, /if has_top_level_select_top\(sql\)/); + assert.match(rustQueryResultSqlSource, /SELECT TOP 1000 \* FROM TicketInfo/); +});