diff --git a/superset/models/core.py b/superset/models/core.py index b0d662e3cf0f..c98df7ef01ac 100755 --- a/superset/models/core.py +++ b/superset/models/core.py @@ -780,8 +780,11 @@ def _log_query(sql_: str) -> None: description = None for i, statement in enumerate(script.statements): + # For a single statement, execute the original SQL as-is. Re-rendering + # via statement.format() would round-trip through sqlglot + rendered = sql if len(script.statements) == 1 else statement.format() sql_ = self.mutate_sql_based_on_config( - statement.format(), + rendered, is_split=True, ) _log_query(sql_) diff --git a/tests/unit_tests/models/core_test.py b/tests/unit_tests/models/core_test.py index 0da5055624b1..4a22b1564dd7 100644 --- a/tests/unit_tests/models/core_test.py +++ b/tests/unit_tests/models/core_test.py @@ -1597,3 +1597,29 @@ def test_clear_bootstrap_cache_logs_warning_on_failure( mock_logger.warning.assert_called_once() call_args = mock_logger.warning.call_args assert call_args[0][0] == "Failed to clear theme bootstrap cache: %s" + + +def test_execute_sql_preserves_line_comments_single_statement( + mocker: MockerFixture, +) -> None: + """ + A single statement is executed verbatim, so the ``--`` line comments added by + ``SQL_QUERY_MUTATOR`` are not round-tripped through sqlglot (which would rewrite + them into ``/* */`` blocks). Regression test for the comment-mangling bug. + """ + database = Database(database_name="db", sqlalchemy_uri="sqlite://") + mocker.patch.object(database, "get_sqla_engine") + mocker.patch.object(database, "get_raw_connection") + mocker.patch.object(database.db_engine_spec, "fetch_data", return_value=[]) + # Identity mutator so the test isolates whether the SQL got reformatted. + mocker.patch.object( + database, "mutate_sql_based_on_config", side_effect=lambda sql, **kwargs: sql + ) + execute = mocker.patch.object(database.db_engine_spec, "execute") + + sql = "SELECT 1 AS one\n-- user: alice\n-- company: dunder mifflin" + database._execute_sql_with_mutation_and_logging(sql, fetch_last_result=True) + + executed_sql = execute.call_args.args[1] + assert executed_sql == sql + assert "/*" not in executed_sql