You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by hu...@apache.org on 2026/10/21 17:43:47 UTC

(superset) branch hughhhh/pfm-6-explore-indicator updated: fix(partition-mapping): version the probe and verdict caches

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

hughhhh pushed a commit to branch hughhhh/pfm-6-explore-indicator
in repository https://gitbox.apache.org/repos/asf/superset.git


The following commit(s) were added to refs/heads/hughhhh/pfm-6-explore-indicator by this push:
     new 91155a08bc2 fix(partition-mapping): version the probe and verdict caches
91155a08bc2 is described below

commit 91155a08bc2a06a6f3ca31bd6fdc6593647d868f
Author: Hugh A Miles II <hu...@gmail.com>
AuthorDate: Wed Oct 21 18:43:33 2026 +0100

    fix(partition-mapping): version the probe and verdict caches
    
    An all-NULL probe stopped recording a working transform in e4a5fd54e1, but a
    True stored before that is indistinguishable from one another input earned,
    which the new rule deliberately keeps -- and the cached probe results behind
    it stop any query re-probing. So after deploy the Explore icon would stay lit
    for up to PARTITION_TRANSFORM_PROBE_CACHE_TIMEOUT. Both keys now carry a
    version, so the old entries are never read and the next query re-probes.
    
    Co-Authored-By: Claude Opus 5.5 <no...@anthropic.com>
---
 superset/connectors/sqla/partition_mapping.py      | 14 ++++++++--
 .../connectors/sqla/partition_mapping_test.py      | 31 ++++++++++++++++++++++
 2 files changed, 43 insertions(+), 2 deletions(-)

diff --git a/superset/connectors/sqla/partition_mapping.py b/superset/connectors/sqla/partition_mapping.py
index 8c19445617d..443c8c6ff49 100644
--- a/superset/connectors/sqla/partition_mapping.py
+++ b/superset/connectors/sqla/partition_mapping.py
@@ -2097,6 +2097,16 @@ def _execution_identity(database: Database) -> str | None:
     return get_username()
 
 
+#: Bumped whenever what the probe cache or the verdict cache *means* changes,
+#: so entries written under the old meaning are never read under the new one.
+#: v2: an all-``NULL`` probe stopped recording a working transform. A ``True``
+#: stored before that is indistinguishable from one another input earned, so
+#: it would have kept Explore's glyph lit for up to a cache timeout -- and the
+#: cached probe results behind it would have kept any query from re-probing
+#: and writing a fresh one.
+PROBE_CACHE_VERSION = "v2"
+
+
 def _probe_cache_key(
     database: Database,
     catalog: str | None,
@@ -2133,7 +2143,7 @@ def _probe_cache_key(
         default=repr,
     )
     digest = hashlib.md5(payload.encode("utf-8")).hexdigest()  # noqa: S324
-    return f"partition_transform_probe:{digest}"
+    return f"partition_transform_probe:{PROBE_CACHE_VERSION}:{digest}"
 
 
 def _cache_get(key: str) -> list[Any] | None:
@@ -2183,7 +2193,7 @@ def _mirror_verdict_cache_key(
         default=repr,
     )
     digest = hashlib.md5(payload.encode("utf-8")).hexdigest()  # noqa: S324
-    return f"partition_transform_verdict:{digest}"
+    return f"partition_transform_verdict:{PROBE_CACHE_VERSION}:{digest}"
 
 
 def record_mirror_verdict(
diff --git a/tests/unit_tests/connectors/sqla/partition_mapping_test.py b/tests/unit_tests/connectors/sqla/partition_mapping_test.py
index 803b2ae471e..78ba14d1aa0 100644
--- a/tests/unit_tests/connectors/sqla/partition_mapping_test.py
+++ b/tests/unit_tests/connectors/sqla/partition_mapping_test.py
@@ -67,6 +67,7 @@ from superset.connectors.sqla.partition_mapping import (
     NON_DETERMINISTIC_FUNCTIONS,
     parse_error_detail,
     placeholder_is_executable,
+    PROBE_CACHE_VERSION,
     probe_sql_is_evaluable,
     probed_value_type_error,
     RawProbeValue,
@@ -2805,6 +2806,36 @@ def test_a_transform_that_only_ever_answers_null_does_not_mirror(
         assert known_mirror_verdict(database, None, None, transform) is False
 
 
+def test_a_verdict_stored_before_the_all_null_rule_is_not_read(app: Flask) -> None:
+    """
+    A `True` written before an all-`NULL` probe stopped counting as working is
+    indistinguishable from one another input earned, and the new rule will not
+    overwrite such a `True`. Ribbon's QA cache held exactly that for
+    `trunc(from_unixtime(:value), 'HH')` on Hive. Both caches are versioned, so
+    the old entries are never read: the next query re-probes and records
+    `False`.
+    """
+    from superset.extensions import cache_manager  # noqa: PLC0415
+
+    transform = "unix_timestamp(trunc(from_unixtime(:value), 'HH'))"
+    database = _database_returning([None])
+
+    with app.app_context():
+        legacy_verdict = _mirror_verdict_cache_key(
+            database, None, None, transform
+        ).replace(f"{PROBE_CACHE_VERSION}:", "")
+        legacy_probe = _probe_cache_key(
+            database, None, None, transform, [1790850600]
+        ).replace(f"{PROBE_CACHE_VERSION}:", "")
+        cache_manager.cache.set(legacy_verdict, True)
+        cache_manager.cache.set(legacy_probe, [None])
+
+        evaluate_transform(database, None, None, transform, [1790850600])
+
+        assert database.get_df.called
+        assert known_mirror_verdict(database, None, None, transform) is False
+
+
 def test_an_answer_after_an_all_null_probe_restores_the_verdict(app: Flask) -> None:
     """The `False` an all-`NULL` probe records is not sticky: the next input that
     answers misses the probe cache, re-probes and re-records."""