You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by va...@apache.org on 2025/03/18 18:13:26 UTC

(superset) 01/01: feat(where_in): Support returning None if filter_values return None

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

vavila pushed a commit to branch feat/return-none-where_in-jinja-filter
in repository https://gitbox.apache.org/repos/asf/superset.git

commit 39edf45341ed4153ff2ac3772bde097b7e385918
Author: Vitor Avila <vi...@preset.io>
AuthorDate: Tue Mar 18 15:12:59 2025 -0300

    feat(where_in): Support returning None if filter_values return None
---
 superset/jinja_context.py              | 17 +++++++++++++++--
 tests/unit_tests/jinja_context_test.py | 13 +++++++++++++
 2 files changed, 28 insertions(+), 2 deletions(-)

diff --git a/superset/jinja_context.py b/superset/jinja_context.py
index f500881ba4..38d53725b2 100644
--- a/superset/jinja_context.py
+++ b/superset/jinja_context.py
@@ -519,7 +519,12 @@ class WhereInMacro:  # pylint: disable=too-few-public-methods
     def __init__(self, dialect: Dialect):
         self.dialect = dialect
 
-    def __call__(self, values: list[Any], mark: Optional[str] = None) -> str:
+    def __call__(
+        self,
+        values: list[Any],
+        mark: Optional[str] = None,
+        default_to_none: bool = False,
+    ) -> str | None:
         """
         Given a list of values, build a parenthesis list suitable for an IN expression.
 
@@ -528,6 +533,10 @@ class WhereInMacro:  # pylint: disable=too-few-public-methods
             >>> where_in([1, "Joe's", 3])
             (1, 'Joe''s', 3)
 
+        The `default_to_none` parameter is used to determine the return value when the
+        list of values is empty:
+            - If `default_to_none` is `False` (default), the return value is ().
+            - If `default_to_none` is `True`, the return value is `None`.
         """
         binds = [bindparam(f"value_{i}", value) for i, value in enumerate(values)]
         string_representations = [
@@ -539,7 +548,11 @@ class WhereInMacro:  # pylint: disable=too-few-public-methods
             for bind in binds
         ]
         joined_values = ", ".join(string_representations)
-        result = f"({joined_values})"
+        result = (
+            f"({joined_values})"
+            if (joined_values is not None or not default_to_none)
+            else None
+        )
 
         if mark:
             result += (
diff --git a/tests/unit_tests/jinja_context_test.py b/tests/unit_tests/jinja_context_test.py
index d2ec9c8345..be6e5fb55e 100644
--- a/tests/unit_tests/jinja_context_test.py
+++ b/tests/unit_tests/jinja_context_test.py
@@ -416,6 +416,19 @@ def test_where_in() -> None:
     assert where_in(["O'Malley's"]) == "('O''Malley''s')"
 
 
+def test_where_in_empty_list() -> None:
+    """
+    Test the ``where_in`` Jinja2 filter when it receives an
+    empty list.
+    """
+    where_in = WhereInMacro(mysql.dialect())
+
+    # By default, the filter should return empty parenthesis (as a string)
+    assert where_in([]) == "()"
+    # With the default_to_none parameter set to True, it should return None
+    assert where_in([], default_to_none=True) is None
+
+
 def test_dataset_macro(mocker: MockerFixture) -> None:
     """
     Test the ``dataset_macro`` macro.