From cdc1397033188d70f4a5d08b45e8a4330ae91c9f Mon Sep 17 00:00:00 2001 From: Evan Rusackas Date: Mon, 27 Apr 2026 11:49:15 -0700 Subject: [PATCH] fix(sqllab): keep saved-query list working when Jinja `dataset(id)` references a deleted dataset When a saved query contains a Jinja macro such as `{{ dataset(id) }}` and the referenced dataset is later deleted, `process_jinja_sql` raises `DatasetNotFoundError` while computing the `sql_tables` field. That exception was not caught by `SqlTablesMixin.sql_tables`, so the entire saved-query list endpoint failed with "Dataset ID not found", hiding every saved query from the user and preventing them from deleting the broken one (#32771). Treat any `SupersetException` raised during table extraction the same way as existing parse/security/template errors: log a warning and return an empty list so the rest of the row can still be serialized. Co-Authored-By: Claude Opus 4.7 --- superset/models/sql_lab.py | 14 +++++++++++++- tests/unit_tests/models/sql_lab_test.py | 12 +++++++++++- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/superset/models/sql_lab.py b/superset/models/sql_lab.py index 9441a1d4faa..5f9c09e4220 100644 --- a/superset/models/sql_lab.py +++ b/superset/models/sql_lab.py @@ -52,7 +52,11 @@ from superset_core.queries.models import ( ) from superset import security_manager -from superset.exceptions import SupersetParseError, SupersetSecurityException +from superset.exceptions import ( + SupersetException, + SupersetParseError, + SupersetSecurityException, +) from superset.explorables.base import TimeGrainDict from superset.jinja_context import BaseTemplateProcessor, get_template_processor from superset.models.helpers import ( @@ -98,6 +102,14 @@ class SqlTablesMixin: # pylint: disable=too-few-public-methods ) except (SupersetSecurityException, SupersetParseError, TemplateError): return [] + except SupersetException as ex: + # Jinja macros such as ``{{ dataset(id) }}`` or ``{{ metric(...) }}`` + # may reference resources that no longer exist (e.g. a deleted + # dataset). Surfacing the failure here would break list endpoints + # that include ``sql_tables`` in their payload, hiding every saved + # query from the user. Treat it as a parse failure instead. + logger.warning("Unable to extract tables from SQL via Jinja: %s", ex) + return [] class Query( diff --git a/tests/unit_tests/models/sql_lab_test.py b/tests/unit_tests/models/sql_lab_test.py index c359e4f630b..ec8dc38ea4e 100644 --- a/tests/unit_tests/models/sql_lab_test.py +++ b/tests/unit_tests/models/sql_lab_test.py @@ -21,8 +21,13 @@ from flask_appbuilder import Model from jinja2.exceptions import TemplateError from pytest_mock import MockerFixture +from superset.commands.dataset.exceptions import DatasetNotFoundError from superset.errors import ErrorLevel, SupersetError, SupersetErrorType -from superset.exceptions import SupersetParseError, SupersetSecurityException +from superset.exceptions import ( + SupersetParseError, + SupersetSecurityException, + SupersetTemplateException, +) from superset.models.sql_lab import Query, SavedQuery @@ -48,6 +53,11 @@ from superset.models.sql_lab import Query, SavedQuery message="Invalid SQL syntax", ), TemplateError, + # ``{{ dataset(id) }}`` referencing a deleted dataset previously + # bubbled up through ``sql_tables`` and broke saved-query list + # endpoints (see issue #32771). + DatasetNotFoundError("Dataset 1 not found!"), + SupersetTemplateException("Template rendering failed"), ], ) def test_sql_tables_mixin_sql_tables_exception(