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

michaelsmolina pushed a commit to branch pulse
in repository https://gitbox.apache.org/repos/asf/superset.git

commit d8b01c668fdd3e6d12de52e8df104f70b46b96b0
Author: Beto Dealmeida <[email protected]>
AuthorDate: Thu Jul 31 08:33:34 2025 -0400

    fix: prevent anonymous code in Postgres (#34412)
    
    (cherry picked from commit 6fc734da5154524b2e235c4df0d75977a7d5211f)
---
 superset/sql/parse.py               | 10 ++++++++++
 tests/unit_tests/sql/parse_tests.py | 37 +++++++++++++++++++++++++++++++++++++
 2 files changed, 47 insertions(+)

diff --git a/superset/sql/parse.py b/superset/sql/parse.py
index 792d0e9e6f..9286bca65a 100644
--- a/superset/sql/parse.py
+++ b/superset/sql/parse.py
@@ -382,6 +382,16 @@ class SQLStatement(BaseSQLStatement[exp.Expression]):
             if isinstance(node, exp.Command) and node.name == "ALTER":
                 return True
 
+        if (
+            self._dialect == Dialects.POSTGRES
+            and isinstance(self._parsed, exp.Command)
+            and self._parsed.name == "DO"
+        ):
+            # anonymous blocks can be written in many different languages (the 
default
+            # is PL/pgSQL), so parsing them it out of scope of this class; we 
just
+            # assume the anonymous block is mutating
+            return True
+
         # Postgres runs DMLs prefixed by `EXPLAIN ANALYZE`, see
         # https://www.postgresql.org/docs/current/sql-explain.html
         if (
diff --git a/tests/unit_tests/sql/parse_tests.py 
b/tests/unit_tests/sql/parse_tests.py
index 8dc06aeea3..dd93ad230c 100644
--- a/tests/unit_tests/sql/parse_tests.py
+++ b/tests/unit_tests/sql/parse_tests.py
@@ -1072,6 +1072,43 @@ def test_is_mutating(engine: str) -> None:
     ).is_mutating()
 
 
[email protected](
+    "sql, expected",
+    [
+        (
+            """
+DO $$
+BEGIN
+  INSERT INTO public.users (name, real_name)
+    VALUES ('SQLLab bypass DML', 'SQLLab bypass DML');
+END;
+$$;
+            """,
+            True,
+        ),
+        (
+            """
+DO $$
+BEGIN
+    IF (SELECT COUNT(*) FROM orders WHERE status = 'pending') > 100 THEN
+        RAISE NOTICE 'High pending order volume detected';
+    END IF;
+END;
+$$;
+            """,
+            True,
+        ),
+    ],
+)
+def test_is_mutating_anonymous_block(sql: str, expected: bool) -> None:
+    """
+    Test for `is_mutating` with a Postgres anonymous block.
+
+    Since we can't parse the PL/pgSQL inside the block we always assume it is 
mutating.
+    """
+    assert SQLStatement(sql, "postgresql").is_mutating() == expected
+
+
 def test_optimize() -> None:
     """
     Test that the `optimize` method works as expected.

Reply via email to