fix(sqlserver): preserve commented CTE queries
This commit is contained in:
1 file changed
+46
-8
@@ -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 {
|
||||||
|
|||||||
Reference in new issue
Block a user