mirror of
https://github.com/apache/superset.git
synced 2026-07-09 00:05:36 +00:00
fix(sql): preserve multi-arg DISTINCT in sanitize_clause and format (#39340)
This commit is contained in:
@@ -3153,6 +3153,48 @@ def test_is_valid_cvas(sql: str, engine: str, expected: bool) -> None:
|
||||
("col1 = 1) AND (col2 = 2", QueryClauseValidationException, "base"),
|
||||
("(col1 = 1)) AND ((col2 = 2)", QueryClauseValidationException, "base"),
|
||||
("TRUE; SELECT 1", QueryClauseValidationException, "base"),
|
||||
# Regression test for https://github.com/apache/superset/issues/39223:
|
||||
# dialects with `MULTI_ARG_DISTINCT=False` (Postgres, Presto, Trino,
|
||||
# DuckDB) must not rewrite user-defined multi-argument DISTINCT
|
||||
# aggregates into row-expression null guards. Dremio is included
|
||||
# below as a defensive regression guard even though its generator
|
||||
# does not currently set `MULTI_ARG_DISTINCT=False`.
|
||||
(
|
||||
"DISTINCT_AVG(DISTINCT report_id, time_to_accept / 86400)",
|
||||
"DISTINCT_AVG(DISTINCT report_id, time_to_accept / 86400)",
|
||||
"postgresql",
|
||||
),
|
||||
(
|
||||
"DISTINCT_SUM(DISTINCT report_id, total_bounty_reward_amount)",
|
||||
"DISTINCT_SUM(DISTINCT report_id, total_bounty_reward_amount)",
|
||||
"postgresql",
|
||||
),
|
||||
(
|
||||
"DISTINCT_AVG(DISTINCT k, v)",
|
||||
"DISTINCT_AVG(DISTINCT k, v)",
|
||||
"presto",
|
||||
),
|
||||
(
|
||||
"DISTINCT_AVG(DISTINCT k, v)",
|
||||
"DISTINCT_AVG(DISTINCT k, v)",
|
||||
"trino",
|
||||
),
|
||||
(
|
||||
"DISTINCT_AVG(DISTINCT k, v)",
|
||||
"DISTINCT_AVG(DISTINCT k, v)",
|
||||
"duckdb",
|
||||
),
|
||||
(
|
||||
"DISTINCT_AVG(DISTINCT k, v)",
|
||||
"DISTINCT_AVG(DISTINCT k, v)",
|
||||
"dremio",
|
||||
),
|
||||
# Single-argument DISTINCT must still round-trip cleanly.
|
||||
(
|
||||
"COUNT(DISTINCT x)",
|
||||
"COUNT(DISTINCT x)",
|
||||
"postgresql",
|
||||
),
|
||||
],
|
||||
)
|
||||
def test_sanitize_clause(sql: str, expected: str | Exception, engine: str) -> None:
|
||||
@@ -3166,6 +3208,30 @@ def test_sanitize_clause(sql: str, expected: str | Exception, engine: str) -> No
|
||||
sanitize_clause(sql, engine)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"engine",
|
||||
[
|
||||
"postgresql",
|
||||
"presto",
|
||||
"trino",
|
||||
"duckdb",
|
||||
"dremio",
|
||||
],
|
||||
)
|
||||
def test_sqlstatement_format_preserves_multi_arg_distinct(engine: str) -> None:
|
||||
"""
|
||||
Regression guard for https://github.com/apache/superset/issues/39223:
|
||||
``SQLStatement.format()`` must not rewrite user-defined multi-argument
|
||||
DISTINCT aggregates into row-expression null guards. This is the SQL Lab /
|
||||
executor path; the metric-expression path is covered by
|
||||
``test_sanitize_clause``.
|
||||
"""
|
||||
sql = "SELECT DISTINCT_AVG(DISTINCT a, b) FROM t"
|
||||
formatted = SQLScript(sql, engine).format()
|
||||
assert "DISTINCT_AVG(DISTINCT a, b)" in formatted
|
||||
assert "CASE WHEN" not in formatted
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"engine",
|
||||
[
|
||||
|
||||
Reference in New Issue
Block a user