fix(native-filters): populate granularity_sqla from datasource main_dttm_col for time-range parent cascade#39894
Conversation
…ttm_col for time-range parent cascade
Code Review Agent Run #89855eActionable Suggestions - 0Review Details
Bito Usage GuideCommands Type the following command in the pull request comment and save the comment.
Refer to the documentation for additional commands. Configuration This repository uses Documentation & Help |
| useEffect(() => { | ||
| if (datasetId != null) { | ||
| dispatch(fetchDatasourceMetadata(`${datasetId}__table`)); | ||
| } | ||
| }, [datasetId, dispatch]); |
There was a problem hiding this comment.
Suggestion: Dispatching metadata fetch on mount without in-flight deduplication can trigger concurrent duplicate requests when multiple filters use the same dataset and mount together. Each instance sees an empty cache and fires its own request, causing avoidable API load and possible last-write-wins state churn; guard this with request deduplication (or a shared loading flag) before dispatching. [race condition]
Severity Level: Minor 🧹
- ⚠️ Extra GETs to /superset/fetch_datasource_metadata per shared dataset.
- ⚠️ Slightly slower dashboard load for filter-only datasets.
- ⚠️ Unnecessary backend load when many filters share one dataset.Steps of Reproduction ✅
1. Open a dashboard that uses multiple native filters all pointing to the same dataset ID
(each filter's config provides the same `datasetId` in its `targets`), so multiple
`FilterControl` instances render. These controls render `FilterValue` from
`src/dashboard/components/nativeFilters/FilterBar/FilterControls/FilterControl.tsx:20-34`,
which in turn mounts multiple `FilterValue` components.
2. When each `FilterValue` mounts, its `useEffect` at `FilterValue.tsx:205-209` runs, and
for each instance with a non-null `datasetId` it dispatches
`fetchDatasourceMetadata(\`${datasetId}__table\`)` via `dispatch`.
3. The thunk `fetchDatasourceMetadata` is defined in
`src/dashboard/actions/datasources.ts:16-28`. It checks `getState().datasources[key]`, and
if the entry is missing it calls `SupersetClient.get({ endpoint:
\`/superset/fetch_datasource_metadata?datasourceKey=${key}\` })` without tracking
in-flight requests.
4. Because each `FilterValue` instance calls `dispatch(fetchDatasourceMetadata(...))` in a
separate effect but before any of the network calls resolve and populate
`state.datasources[key]`, all of them see an empty cache and issue parallel GET requests
to `/superset/fetch_datasource_metadata?datasourceKey=${datasetId}__table`. This results
in duplicate metadata fetches for the same dataset but does not cause functional race
conditions, since each response ultimately dispatches `setDatasource` with the same
payload.Fix in Cursor | Fix in VSCode Claude
(Use Cmd/Ctrl + Click for best experience)
Prompt for AI Agent 🤖
This is a comment left during a code review.
**Path:** superset-frontend/src/dashboard/components/nativeFilters/FilterBar/FilterControls/FilterValue.tsx
**Line:** 205:209
**Comment:**
*Race Condition: Dispatching metadata fetch on mount without in-flight deduplication can trigger concurrent duplicate requests when multiple filters use the same dataset and mount together. Each instance sees an empty cache and fires its own request, causing avoidable API load and possible last-write-wins state churn; guard this with request deduplication (or a shared loading flag) before dispatching.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix|
Yes, the suggestion is valid — the race condition can occur when multiple FilterValue components mount simultaneously, each dispatching fetchDatasourceMetadata without deduplication, leading to duplicate API requests. To resolve this, modify the fetchDatasourceMetadata thunk in src/dashboard/actions/datasources.ts to track in-flight requests using a module-level Map. There are no other comments on this PR. superset-frontend/src/dashboard/actions/datasources.ts |
…quests When multiple FilterValue components share the same datasetId and mount simultaneously, each sees an empty Redux cache and dispatches fetchDatasourceMetadata. The thunk already short-circuits once the datasource is cached, but has no guard for concurrent in-flight requests. Add a module-level Set to track keys currently being fetched so that parallel dispatches for the same key skip the network call. The Set entry is cleared on both success and error so a failed request can be retried. Addresses review feedback on the FilterValue granularity_sqla fix. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Code Review Agent Run #e7c400Actionable Suggestions - 0Review Details
Bito Usage GuideCommands Type the following command in the pull request comment and save the comment.
Refer to the documentation for additional commands. Configuration This repository uses Documentation & Help |
SUMMARY
When a native Date Range filter is configured as the parent of a Select (Value)
filter, the child filter's dropdown values should be constrained to the selected
date range. This has never worked correctly due to three bugs in
FilterValue.tsx:Bug 1 — Missing
granularity_sqla:getFormDatasends the parent'stime_rangeviaextra_form_datato the child's column-values API request, butsends no
granularity_sqla. The backend receives the temporal constraint but hasno column to apply it to and silently returns all values. Upstream PR #34137 fixed
the timing (child requests now wait for parent values) but did not address the
missing column.
Bug 2 — Datasource not in Redux cache: The fix for Bug 1 reads
main_dttm_colfrom
state.datasources, but/api/v1/dashboard/:id/datasetsonly returns datasetsused by chart slices. Native-filter-only datasets are never in
state.datasources.fetchDatasourceMetadatais now dispatched at mount time to populate the cache forthose datasets.
Bug 3 — Stale React closure:
datasourceMainDttmColwas not in the mainuseEffectdependency array. Filters with a default date range would fire theireffect before the async fetch completed and never re-run once the datasource loaded.
Changes
FilterValue.tsx: importfetchDatasourceMetadataFilterValue.tsx: dispatchfetchDatasourceMetadataat mount whendatasetIdisset, populating
state.datasourcesfor filter-only datasetsFilterValue.tsx: readmain_dttm_colfrom the cache viauseSelectorand use itas a fallback
granularity_sqlawhendependencies.time_rangeis setFilterValue.tsx: adddatasourceMainDttmColto the mainuseEffectdep arrayTESTING INSTRUCTIONS
main_dttm_col(e.g.birth_names), with the Time range filter set as its parentmatching options
ADDITIONAL INFORMATION