From 5f9fdfe019dc403cafe4db86e9cc6e534f69f9f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=90=E1=BB=97=20Tr=E1=BB=8Dng=20H=E1=BA=A3i?= <41283691+hainenber@users.noreply.github.com> Date: Sat, 22 Mar 2025 03:36:03 +0700 Subject: [PATCH] fix(model/helper): represent RLS filter clause in proper textual SQL string (#32406) Signed-off-by: hainenber (cherry picked from commit ff0529c9323966a0aa05f7879530953b8557bf00) --- superset/models/helpers.py | 2 +- tests/unit_tests/models/helpers_test.py | 16 +++++++++------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/superset/models/helpers.py b/superset/models/helpers.py index 33c7c17d170..5dc97b602af 100644 --- a/superset/models/helpers.py +++ b/superset/models/helpers.py @@ -1380,7 +1380,7 @@ class ExploreMixin: # pylint: disable=too-many-public-methods if engine.dialect.identifier_preparer._double_percents: sql = sql.replace("%%", "%") - df = pd.read_sql_query(sql=sql, con=engine) + df = pd.read_sql_query(sql=self.text(sql), con=engine) # replace NaN with None to ensure it can be serialized to JSON df = df.replace({np.nan: None}) return df["column_values"].to_list() diff --git a/tests/unit_tests/models/helpers_test.py b/tests/unit_tests/models/helpers_test.py index cc106dbe649..4e8aa493be3 100644 --- a/tests/unit_tests/models/helpers_test.py +++ b/tests/unit_tests/models/helpers_test.py @@ -25,7 +25,7 @@ from unittest.mock import patch import pytest from pytest_mock import MockerFixture -from sqlalchemy import create_engine +from sqlalchemy import create_engine, text from sqlalchemy.orm.session import Session from sqlalchemy.pool import StaticPool @@ -201,10 +201,12 @@ def test_values_for_column_double_percents( ) # make sure final query has single percents with database.get_sqla_engine() as engine: - pd.read_sql_query.assert_called_with( - sql=( - "SELECT DISTINCT CASE WHEN b LIKE 'A%' THEN 'yes' ELSE 'nope' END " - "AS column_values \nFROM t\n LIMIT 10000 OFFSET 0" - ), - con=engine, + expected_sql = text( + "SELECT DISTINCT CASE WHEN b LIKE 'A%' THEN 'yes' ELSE 'nope' END " + "AS column_values \nFROM t\n LIMIT 10000 OFFSET 0" ) + called_sql = pd.read_sql_query.call_args.kwargs["sql"] + called_conn = pd.read_sql_query.call_args.kwargs["con"] + + assert called_sql.compare(expected_sql) is True + assert called_conn == engine