feat(native-filters): add configurable LIKE/ILIKE operators to Select filter#38470
feat(native-filters): add configurable LIKE/ILIKE operators to Select filter#38470endimonan wants to merge 1 commit intoapache:masterfrom
Conversation
… filter Adds a "Match type" dropdown to the Select (Value) filter configuration, allowing filter creators to choose between exact matching (IN) and partial text matching via ILIKE with configurable wildcard patterns: - Exact match (IN) - default, preserves existing behavior - Contains text (ILIKE %x%) - matches anywhere in the string - Starts with (ILIKE x%) - matches from the beginning - Ends with (ILIKE %x) - matches at the end When an ILIKE operator is selected, the filter renders a free-text Input field instead of the dropdown Select, with debounced updates. Inverse selection uses NOT ILIKE accordingly. Includes a performance warning tooltip since ILIKE queries may be slow on large datasets as they cannot leverage indexes effectively. Ref: apache#25358
16cab98 to
006de66
Compare
|
Hey @endimonan this is awesome, great job and congratulations on your first Superset PR! 🥳 |
There was a problem hiding this comment.
Code Review Agent Run #45eb5e
Actionable Suggestions - 1
-
superset-frontend/src/filters/components/Select/SelectFilterPlugin.tsx - 1
- Uncontrolled input inconsistency · Line 550-565
Additional Suggestions - 1
-
superset-frontend/src/filters/components/Select/SelectFilterPlugin.tsx - 1
-
Missing Input Ref · Line 551-565The Input lacks ref={inputRef} unlike the Select, which may break programmatic focus if inputRef is used elsewhere.
Code suggestion
@@ -574,2 +574,3 @@ - disabled={isDisabled} - /> + disabled={isDisabled} + ref={inputRef} + />
-
Review Details
-
Files reviewed - 9 · Commit Range:
006de66..006de66- superset-frontend/packages/superset-ui-core/src/query/types/Operator.ts
- superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FiltersConfigForm.tsx
- superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/getControlItemsMap.tsx
- superset-frontend/src/filters/components/Select/SelectFilterPlugin.test.tsx
- superset-frontend/src/filters/components/Select/SelectFilterPlugin.tsx
- superset-frontend/src/filters/components/Select/buildQuery.test.ts
- superset-frontend/src/filters/components/Select/controlPanel.ts
- superset-frontend/src/filters/components/Select/types.ts
- superset-frontend/src/filters/utils.ts
-
Files skipped - 0
-
Tools
- Whispers (Secret Scanner) - ✔︎ Successful
- Detect-secrets (Secret Scanner) - ✔︎ Successful
- Eslint (Linter) - ✔︎ Successful
Bito Usage Guide
Commands
Type the following command in the pull request comment and save the comment.
-
/review- Manually triggers a full AI review. -
/pause- Pauses automatic reviews on this pull request. -
/resume- Resumes automatic reviews. -
/resolve- Marks all Bito-posted review comments as resolved. -
/abort- Cancels all in-progress reviews.
Refer to the documentation for additional commands.
Configuration
This repository uses Superset You can customize the agent settings here or contact your Bito workspace admin at evan@preset.io.
Documentation & Help
| {isLikeOperator ? ( | ||
| <Input | ||
| allowClear | ||
| placeholder={likeInputPlaceholder} | ||
| defaultValue={ | ||
| filterState.value?.[0] != null | ||
| ? String(filterState.value[0]) | ||
| : undefined | ||
| } | ||
| onChange={handleLikeInputChange} | ||
| onFocus={setFocusedFilter} | ||
| onBlur={unsetFocusedFilter} | ||
| onMouseEnter={setHoveredFilter} | ||
| onMouseLeave={unsetHoveredFilter} | ||
| disabled={isDisabled} | ||
| /> |
There was a problem hiding this comment.
The Input component uses defaultValue, making it uncontrolled and inconsistent with the controlled Select. If filterState.value changes externally (e.g., filter reset), the input won't update, potentially showing stale data. This differs from Select, which reflects changes immediately. To fix, add a local state for the input value and make the Input controlled.
Code Review Run #45eb5e
Should Bito avoid suggestions like this for future reviews? (Manage Rules)
- Yes, avoid them
There was a problem hiding this comment.
I think the bot might have a point here, can you please double check?
There was a problem hiding this comment.
Yes, the suggestion is valid — the Input uses defaultValue, making it uncontrolled and inconsistent with the controlled Select, which could lead to stale data if filterState.value changes externally. Adding local state to control the Input would ensure it updates properly.
| const setDataMaskMock = jest.fn(); | ||
|
|
||
| render( | ||
| // @ts-expect-error |
There was a problem hiding this comment.
is there a way to remove these and properly type?
|
Yes, you can remove @ts-expect-error by properly typing the test props, such as defining interfaces for the mock data or using type assertions. For example, cast the props to the expected type or extend the types to include the test-specific fields. |
| operatorType = SelectFilterOperatorType.Exact, | ||
| } = formData; | ||
|
|
||
| const isLikeOperator = operatorType !== SelectFilterOperatorType.Exact; |
There was a problem hiding this comment.
Can we restrict the new ILIKE modes to string columns? As written, any non-Exact operator flips to text input + ILIKE/NOT ILIKE, which may not be valid for non-text columns on all engines
| <Input | ||
| allowClear | ||
| placeholder={likeInputPlaceholder} | ||
| defaultValue={ |
There was a problem hiding this comment.
I think this input should probably be controlled instead of using defaultValue. In LIKE mode, filter state can change from clear-all/defaults/parent updates, and the visible text could get out of sync with the actual dataMask
| filterToEdit?.controlValues?.operatorType ?? | ||
| SelectFilterOperatorType.Exact; | ||
|
|
||
| const onOperatorTypeChanged = (value: SelectFilterOperatorType) => { |
There was a problem hiding this comment.
One edge case here: if a user already has Exact selections and then switches to a LIKE mode, we only use the first selected value. It may be safer to clear/reset the filter value when operatorType changes
| </> | ||
| } | ||
| > | ||
| <Select |
There was a problem hiding this comment.
The Match type options are duplicated here and in the Select filter control config. It would be better to share one source of truth to avoid drift
|
SUMMARY
Adds a configurable "Match type" option to the native Select (Value) dashboard filter, enabling partial text matching via ILIKE operators in addition to the default exact match (IN).
This addresses a community request (Discussion #25358) where users need to filter by partial text (e.g., typing "Jen" to find "Jennifer", "Jenna", "Jenny") but are limited to selecting exact values from a dropdown.
New "Match type" options in filter configuration:
When an ILIKE operator is selected, the filter renders a free-text Input field (with debounce) instead of the dropdown Select. Inverse selection uses NOT ILIKE accordingly.
Includes a performance warning tooltip since ILIKE queries may not leverage indexes on large datasets.
Files changed (9):
types.ts— newSelectFilterOperatorTypeenum +operatorTypein form datacontrolPanel.ts— new "Match type" SelectControl with 4 optionsutils.ts—getSelectExtraFormData()now supports ILIKE/NOT ILIKE with wildcardsSelectFilterPlugin.tsx— conditional Input vs Select rendering based on operatorOperator.ts— addedNOT ILIKEtoBINARY_OPERATORSFiltersConfigForm.tsx— custom rendering of Match type dropdown in config modalgetControlItemsMap.tsx— excludesoperatorTypefrom generic checkbox loopBEFORE/AFTER SCREENSHOTS OR ANIMATED GIF
Before:

After:

TESTING INSTRUCTIONS
nameonbirth_names)ADDITIONAL INFORMATION