fix(sqlserver): preserve commented CTE queries

This commit is contained in:
zipg authored and GitHub committed 2026-08-19 15:08:19 +08:00
1 parent ab2444c757
commit be171e9976
1 file changed
+46 -8
+46 -8
View File
@@ -142,12 +142,16 @@ pub fn build_query_pagination_execution_plan(
single_execution: false, single_execution: false,
}; };
let counted = build_count_query_sql(CountQuerySqlOptions { let sql_server_cte =
original_sql: options.query_base_sql.clone(), options.database_type == Some(DatabaseType::SqlServer) && starts_with_cte(&options.query_base_sql);
database_type: options.database_type, if !sql_server_cte {
}); let counted = build_count_query_sql(CountQuerySqlOptions {
if counted.ok { original_sql: options.query_base_sql.clone(),
plan.count_sql = counted.sql; database_type: options.database_type,
});
if counted.ok {
plan.count_sql = counted.sql;
}
} }
if options.pagination.session_id.is_some() { if options.pagination.session_id.is_some() {
@@ -157,7 +161,7 @@ pub fn build_query_pagination_execution_plan(
return plan; return plan;
} }
if options.database_type == Some(DatabaseType::SqlServer) && starts_with_cte(&options.query_base_sql) { if sql_server_cte {
return plan; return plan;
} }
@@ -451,7 +455,16 @@ fn single_statement_matches_base_sql(statement: &str, base_sql: &str) -> bool {
} }
fn starts_with_cte(sql: &str) -> bool { fn starts_with_cte(sql: &str) -> bool {
sql.trim_start().trim_start_matches(';').trim_start().to_ascii_uppercase().starts_with("WITH") let mut statement = sql;
loop {
let previous_len = statement.len();
statement = strip_leading_statement_comments(statement);
statement = statement.trim_start_matches(';').trim_start();
if statement.len() == previous_len {
break;
}
}
sql_keyword_at(statement, 0, "WITH")
} }
fn cte_main_statement_is_select(sql: &str) -> bool { fn cte_main_statement_is_select(sql: &str) -> bool {
@@ -2633,6 +2646,31 @@ mod tests {
assert_eq!(plan.page_offset, None); assert_eq!(plan.page_offset, None);
} }
#[test]
fn sqlserver_cte_after_leading_comments_executes_original_sql() {
for sql in [
"-- heading comment\nWITH staff AS (SELECT 1 AS id) SELECT id FROM staff;",
"/* heading comment */\nWITH staff AS (SELECT 1 AS id) SELECT id FROM staff;",
";-- heading comment\nWITH staff AS (SELECT 1 AS id) SELECT id FROM staff;",
"-- heading comment\n;WITH staff AS (SELECT 1 AS id) SELECT id FROM staff;",
] {
let plan = build_query_pagination_execution_plan(QueryPaginationExecutionPlanOptions {
sql: sql.to_string(),
query_base_sql: sql.to_string(),
database_type: Some(DatabaseType::SqlServer),
pagination: QueryPagination { limit: 100, offset: 0, session_id: None },
use_agent_cursor: false,
first_page_uses_actual_sql: false,
});
assert_eq!(plan.sql_to_execute, sql);
assert!(plan.page_sql.is_none());
assert!(plan.count_sql.is_none());
assert_eq!(plan.page_limit, None);
assert_eq!(plan.page_offset, None);
}
}
#[test] #[test]
fn sqlserver_cte_count_query_is_not_wrapped_as_derived_table() { fn sqlserver_cte_count_query_is_not_wrapped_as_derived_table() {
let result = build_count_query_sql(CountQuerySqlOptions { let result = build_count_query_sql(CountQuerySqlOptions {