perf(dashboard): Batch RLS filter lookups for dashboard digest computation (#37941)

This commit is contained in:
Kamil Gabryjelski
2026-02-16 21:35:55 +01:00
committed by GitHub
parent 7b21979fa3
commit 3e3c9686de
4 changed files with 390 additions and 1 deletions

View File

@@ -433,3 +433,52 @@ def test_chart_digest(
)
with cm:
assert get_chart_digest(chart=chart) == expected_result
def test_dashboard_digest_prefetches_rls_filters(
app_context: None,
) -> None:
"""
Test that _adjust_string_with_rls calls prefetch_rls_filters with
table IDs from RLS-supporting datasources before iterating.
"""
from superset import security_manager
from superset.models.dashboard import Dashboard
from superset.models.slice import Slice
from superset.thumbnails.digest import get_dashboard_digest
kwargs = {**_DEFAULT_DASHBOARD_KWARGS}
slices = [Slice(**slice_kwargs) for slice_kwargs in kwargs.pop("slices")]
dashboard = Dashboard(**kwargs, slices=slices)
datasources = []
for ds_id, rls_supported in [(10, True), (20, True), (30, False)]:
ds = MagicMock(spec=BaseDatasource)
ds.id = ds_id
ds.is_rls_supported = rls_supported
ds.get_sqla_row_level_filters = MagicMock(return_value=[])
datasources.append(ds)
user = User(id=1, username="1")
with (
patch.dict(
current_app.config,
{
"THUMBNAIL_EXECUTORS": [ExecutorType.CURRENT_USER],
"THUMBNAIL_DASHBOARD_DIGEST_FUNC": None,
},
),
patch.object(
type(dashboard),
"datasources",
new_callable=PropertyMock,
return_value=datasources,
),
patch.object(security_manager, "find_user", return_value=user),
patch.object(security_manager, "prefetch_rls_filters") as mock_prefetch,
override_user(user),
):
get_dashboard_digest(dashboard=dashboard)
# Should be called with only the RLS-supporting datasource IDs
mock_prefetch.assert_called_once_with([10, 20])