mirror of
https://github.com/apache/superset.git
synced 2026-07-18 04:35:40 +00:00
fix: cover MUTATE_AFTER_SPLIT branches, guard empty/mismatched mutated statements
Add missing coverage for the MUTATE_AFTER_SPLIT=True branch, add type hints to satisfy dev-standard lint, and guard against a SQL_QUERY_MUTATOR that strips all statements or changes statement count when mutating before the split. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -151,11 +151,26 @@ def _prepare_statement_blocks(
|
||||
# `execute_sql_with_cursor`, which is a no-op here since its
|
||||
# `is_split=True` no longer matches the config) operate on the
|
||||
# already-mutated SQL.
|
||||
mutated_sql = database.mutate_sql_based_on_config(
|
||||
mutated_sql: str = database.mutate_sql_based_on_config(
|
||||
parsed_script.format(comments=db_engine_spec.allows_sql_comments),
|
||||
is_split=False,
|
||||
)
|
||||
parsed_script = SQLScript(mutated_sql, engine=db_engine_spec.engine)
|
||||
if not parsed_script.statements:
|
||||
# A `SQL_QUERY_MUTATOR` that strips a query down to nothing
|
||||
# (e.g. only comments/whitespace) would otherwise leave us with
|
||||
# an empty `blocks` list, skipping the execution loop below and
|
||||
# surfacing a confusing error instead of a clean one.
|
||||
raise SupersetErrorException(
|
||||
SupersetError(
|
||||
message=__(
|
||||
"The SQL query mutator removed all executable "
|
||||
"statements from this query."
|
||||
),
|
||||
error_type=SupersetErrorType.INVALID_SQL_ERROR,
|
||||
level=ErrorLevel.ERROR,
|
||||
)
|
||||
)
|
||||
blocks = [
|
||||
statement.format(comments=db_engine_spec.allows_sql_comments)
|
||||
for statement in parsed_script.statements
|
||||
@@ -179,6 +194,14 @@ def _finalize_successful_query(
|
||||
# Get original statement strings
|
||||
original_sqls = [stmt.format() for stmt in original_script.statements]
|
||||
|
||||
if len(original_sqls) != len(execution_results):
|
||||
# A `SQL_QUERY_MUTATOR` that changes the number of statements (e.g. by
|
||||
# prepending a `SET ROLE` statement when run on the whole, un-split
|
||||
# query) can leave the un-mutated `original_script` no longer aligned
|
||||
# 1:1 with `execution_results`. Fall back to labeling each result with
|
||||
# its own executed SQL rather than crash a query that ran successfully.
|
||||
original_sqls = [exec_sql for exec_sql, *_ in execution_results]
|
||||
|
||||
for orig_sql, (exec_sql, result_set, exec_time, rowcount) in zip(
|
||||
original_sqls, execution_results, strict=True
|
||||
):
|
||||
|
||||
Reference in New Issue
Block a user