mirror of
https://github.com/apache/superset.git
synced 2026-07-18 20:55:47 +00:00
test(sql): reproduce sanitize_clause mutating user aggregation SQL (#36113)
Add a failing regression test for #36113. `sanitize_clause` round-trips a user-authored clause through SQLGlot's dialect generator and returns the re-rendered SQL. The Postgres dialect (borrowed by several engines) rewrites `ROUND(AVG(x), n)` to `ROUND(CAST(AVG(x) AS DECIMAL), n)` at generation time; on engines whose unqualified DECIMAL defaults to scale 0 the injected cast rounds the aggregate before the explicit ROUND, producing wrong values. The test asserts the clause is returned unchanged and currently fails for postgresql/cockroachdb/netezza/hana. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -3208,6 +3208,31 @@ def test_sanitize_clause(sql: str, expected: str | Exception, engine: str) -> No
|
||||
sanitize_clause(sql, engine)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"engine",
|
||||
["postgresql", "redshift", "cockroachdb", "netezza", "hana", "base", "mysql"],
|
||||
)
|
||||
def test_sanitize_clause_preserves_aggregation_semantics(engine: str) -> None:
|
||||
"""
|
||||
Regression test for https://github.com/apache/superset/issues/36113.
|
||||
|
||||
`sanitize_clause` must not silently rewrite a user-authored expression. The
|
||||
Postgres SQLGlot dialect (which several engines borrow) rewrites
|
||||
``ROUND(AVG(x), n)`` to ``ROUND(CAST(AVG(x) AS DECIMAL), n)`` at generation
|
||||
time. On engines whose unqualified ``DECIMAL`` defaults to scale 0 (e.g.
|
||||
Redshift, Netezza) the injected cast rounds the aggregate to an integer
|
||||
*before* the explicit ``ROUND``, producing wrong results.
|
||||
|
||||
The clause must be returned unchanged regardless of the engine dialect.
|
||||
"""
|
||||
clause = "ROUND(AVG(col), 4)"
|
||||
sanitized = sanitize_clause(clause, engine)
|
||||
assert "CAST" not in sanitized.upper(), (
|
||||
f"sanitize_clause injected a cast for engine {engine!r}: {sanitized!r}"
|
||||
)
|
||||
assert sanitized == clause
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"engine",
|
||||
[
|
||||
|
||||
Reference in New Issue
Block a user