You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by be...@apache.org on 2025/10/01 15:22:41 UTC

(superset) branch compact-cache-key created (now 03a32ce841)

This is an automated email from the ASF dual-hosted git repository.

beto pushed a change to branch compact-cache-key
in repository https://gitbox.apache.org/repos/asf/superset.git


      at 03a32ce841 fix: normalize cache key

This branch includes the following new commits:

     new 03a32ce841 fix: normalize cache key

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



(superset) 01/01: fix: normalize cache key

Posted by be...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

beto pushed a commit to branch compact-cache-key
in repository https://gitbox.apache.org/repos/asf/superset.git

commit 03a32ce8414a6c9136d214ddcd7413a85c5ab335
Author: Beto Dealmeida <ro...@dealmeida.net>
AuthorDate: Wed Oct 1 11:22:33 2025 -0400

    fix: normalize cache key
---
 superset/sql/parse.py               | 15 +++++++++++-
 tests/unit_tests/sql/parse_tests.py | 46 ++++++++++++++++++++++++++++++++++---
 2 files changed, 57 insertions(+), 4 deletions(-)

diff --git a/superset/sql/parse.py b/superset/sql/parse.py
index 822b8ec79b..6a6bad6496 100644
--- a/superset/sql/parse.py
+++ b/superset/sql/parse.py
@@ -1478,8 +1478,21 @@ def process_jinja_sql(
 def sanitize_clause(clause: str, engine: str) -> str:
     """
     Make sure the SQL clause is valid.
+
+    Returns the clause in a normalized, compact format to ensure consistent
+    cache key generation across different execution contexts.
     """
     try:
-        return SQLStatement(clause, engine).format()
+        statement = SQLStatement(clause, engine)
+        # Use compact formatting (pretty=False) for consistent cache keys
+        dialect = SQLGLOT_DIALECTS.get(engine)
+        from sqlglot.dialects.dialect import Dialect
+
+        return Dialect.get_or_raise(dialect).generate(
+            statement._parsed,  # pylint: disable=protected-access
+            copy=True,
+            comments=False,
+            pretty=False,  # Compact formatting for consistent cache keys
+        )
     except SupersetParseError as ex:
         raise QueryClauseValidationException(f"Invalid SQL clause: {clause}") from ex
diff --git a/tests/unit_tests/sql/parse_tests.py b/tests/unit_tests/sql/parse_tests.py
index 406df77934..7a7b0e22f1 100644
--- a/tests/unit_tests/sql/parse_tests.py
+++ b/tests/unit_tests/sql/parse_tests.py
@@ -2593,9 +2593,17 @@ def test_is_valid_cvas(sql: str, engine: str, expected: bool) -> None:
     [
         ("col = 1", "col = 1", "base"),
         ("1=\t\n1", "1 = 1", "base"),
-        ("(col = 1)", "(\n  col = 1\n)", "base"),
-        ("(col1 = 1) AND (col2 = 2)", "(\n  col1 = 1\n) AND (\n  col2 = 2\n)", "base"),
-        ("col = 'abc' -- comment", "col = 'abc' /* comment */", "base"),
+        ("(col = 1)", "(col = 1)", "base"),  # Compact format without newlines
+        (
+            "(col1 = 1) AND (col2 = 2)",
+            "(col1 = 1) AND (col2 = 2)",
+            "base",
+        ),  # Compact format
+        (
+            "col = 'abc' -- comment",
+            "col = 'abc'",
+            "base",
+        ),  # Comments removed for compact format
         ("col = 'col1 = 1) AND (col2 = 2'", "col = 'col1 = 1) AND (col2 = 2'", "base"),
         ("col = 'select 1; select 2'", "col = 'select 1; select 2'", "base"),
         ("col = 'abc -- comment'", "col = 'abc -- comment'", "base"),
@@ -2617,6 +2625,38 @@ def test_sanitize_clause(sql: str, expected: str | Exception, engine: str) -> No
             sanitize_clause(sql, engine)
 
 
+def test_sanitize_clause_cache_key_consistency() -> None:
+    """
+    Test that sanitize_clause returns consistent results for cache key generation.
+
+    This test verifies the fix for the cache key mismatch issue where sqlglot
+    formatting differences between server and worker caused different cache keys.
+    """
+    # Test case from the bug report: where clause with different whitespace
+    clause_with_newlines = "(\n  approval_epoch_ms > 0\n)"
+    clause_without_newlines = "(approval_epoch_ms > 0)"
+
+    result1 = sanitize_clause(clause_with_newlines, "pinot")
+    result2 = sanitize_clause(clause_without_newlines, "pinot")
+
+    # Both should produce the same compact output
+    assert result1 == result2 == "(approval_epoch_ms > 0)"
+
+    # Additional test with more complex clause
+    complex_clause_pretty = """(
+  col1 = 1
+) AND (
+  col2 = 'test'
+)"""
+    complex_clause_compact = "(col1 = 1) AND (col2 = 'test')"
+
+    result3 = sanitize_clause(complex_clause_pretty, "base")
+    result4 = sanitize_clause(complex_clause_compact, "base")
+
+    # Both should produce the same compact output
+    assert result3 == result4
+
+
 @pytest.mark.parametrize(
     "engine",
     [