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

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


The following commit(s) were added to refs/heads/master by this push:
     new 5986fe92c2f fix(rls): roll back db.session after RLS failure in 
get_from_clause (#43883)
5986fe92c2f is described below

commit 5986fe92c2f97711916d777e636ec8acd4ed138d
Author: Elizabeth Thompson <[email protected]>
AuthorDate: Tue Sep 8 15:04:32 2026 -0700

    fix(rls): roll back db.session after RLS failure in get_from_clause (#43883)
    
    Co-authored-by: Claude Opus 4.6 <[email protected]>
---
 superset/models/helpers.py                         |  4 ++++
 .../models/test_virtual_dataset_format.py          | 25 ++++++++++++++++++++++
 2 files changed, 29 insertions(+)

diff --git a/superset/models/helpers.py b/superset/models/helpers.py
index 9589613f674..8d2cae5ce36 100644
--- a/superset/models/helpers.py
+++ b/superset/models/helpers.py
@@ -3640,6 +3640,10 @@ class ExploreMixin:  # pylint: 
disable=too-many-public-methods
                     from_sql = parsed_script.format()
 
             except Exception as ex:  # pylint: disable=broad-except
+                # A caught DB error can leave db.session in "pending rollback"
+                # state, which would poison unrelated queries later in this 
request.
+                db.session.rollback()  # pylint: 
disable=consider-using-transaction
+
                 # RLS injection failures fail closed: only continue when it is
                 # positively confirmed that no RLS predicates apply to the
                 # referenced tables; any other outcome aborts the query.
diff --git a/tests/unit_tests/models/test_virtual_dataset_format.py 
b/tests/unit_tests/models/test_virtual_dataset_format.py
index c063d32efb7..ee0898c09dd 100644
--- a/tests/unit_tests/models/test_virtual_dataset_format.py
+++ b/tests/unit_tests/models/test_virtual_dataset_format.py
@@ -36,6 +36,7 @@ from unittest.mock import MagicMock, patch
 
 import pytest
 from flask import Flask
+from sqlalchemy.exc import OperationalError
 from sqlalchemy.sql.elements import TextClause
 
 from superset.exceptions import QueryObjectValidationError
@@ -472,3 +473,27 @@ class TestVirtualDatasetRLSFailClosed:
 
         with pytest.raises(QueryObjectValidationError):
             virtual_datasource.get_from_clause(template_processor=None)
+
+    @patch("superset.models.helpers.db")
+    @patch(
+        "superset.models.helpers.get_predicates_for_table",
+        return_value=["user_id = 42"],
+    )
+    @patch(
+        "superset.models.helpers.apply_rls",
+        side_effect=OperationalError("SSL connection closed unexpectedly", {}, 
None),
+    )
+    def test_get_from_clause_rolls_back_session_on_rls_failure(
+        self,
+        mock_apply_rls: MagicMock,
+        mock_get_predicates: MagicMock,
+        mock_db: MagicMock,
+        virtual_datasource: MagicMock,
+        app: Flask,
+    ) -> None:
+        _set_virtual_sql(virtual_datasource, "SELECT pen_id FROM public.pens")
+
+        with pytest.raises(QueryObjectValidationError):
+            virtual_datasource.get_from_clause(template_processor=None)
+
+        mock_db.session.rollback.assert_called_once()

Reply via email to