Skip to content

feat(native-filters): add configurable LIKE/ILIKE operators to Select filter#38470

Open
endimonan wants to merge 1 commit intoapache:masterfrom
endimonan:feat/filter-ilike-operator
Open

feat(native-filters): add configurable LIKE/ILIKE operators to Select filter#38470
endimonan wants to merge 1 commit intoapache:masterfrom
endimonan:feat/filter-ilike-operator

Conversation

@endimonan
Copy link

@endimonan endimonan commented Mar 6, 2026

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:

  • 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 (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 — new SelectFilterOperatorType enum + operatorType in form data
  • controlPanel.ts — new "Match type" SelectControl with 4 options
  • utils.tsgetSelectExtraFormData() now supports ILIKE/NOT ILIKE with wildcards
  • SelectFilterPlugin.tsx — conditional Input vs Select rendering based on operator
  • Operator.ts — added NOT ILIKE to BINARY_OPERATORS
  • FiltersConfigForm.tsx — custom rendering of Match type dropdown in config modal
  • getControlItemsMap.tsx — excludes operatorType from generic checkbox loop

BEFORE/AFTER SCREENSHOTS OR ANIMATED GIF

Before:
2026-03-06 13-24-13

After:
2026-03-06 13-25-30

TESTING INSTRUCTIONS

  1. Open any dashboard with a native Select filter on a text column (e.g., name on birth_names)
  2. On the filter bar, click the gear/settings icon to open the filter configuration modal
  3. Select an existing filter (or create a new one on a text column)
  4. In the configuration modal, find the new "Match type" dropdown under the filter settings
  5. Change from "Exact match (IN)" to "Contains text (ILIKE %x%)"
  6. Save the filter configuration
  7. The filter should now show a text input instead of a dropdown
  8. Type a partial value (e.g., "Jen") — the dashboard charts should update showing all matching records (Jennifer, Jenna, etc.)
  9. Verify "Starts with" and "Ends with" modes work similarly
  10. Verify switching back to "Exact match" restores the original Select dropdown
  11. Verify inverse selection (is/is not) works correctly with ILIKE operators

ADDITIONAL INFORMATION

  • Has associated issue: closes #38483
  • Required feature flags:
  • Changes UI
  • Includes DB Migration
  • Introduces new feature or API
  • Removes existing feature or API

… 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
@endimonan endimonan force-pushed the feat/filter-ilike-operator branch from 16cab98 to 006de66 Compare March 6, 2026 12:10
@richardfogaca richardfogaca self-requested a review March 6, 2026 12:39
@richardfogaca
Copy link
Contributor

Hey @endimonan this is awesome, great job and congratulations on your first Superset PR! 🥳

@endimonan endimonan marked this pull request as ready for review March 6, 2026 12:50
@dosubot dosubot bot added the dashboard:native-filters Related to the native filters of the Dashboard label Mar 6, 2026
Copy link
Contributor

@bito-code-review bito-code-review bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review Agent Run #45eb5e

Actionable Suggestions - 1
  • superset-frontend/src/filters/components/Select/SelectFilterPlugin.tsx - 1
Additional Suggestions - 1
  • superset-frontend/src/filters/components/Select/SelectFilterPlugin.tsx - 1
    • Missing Input Ref · Line 551-565
      The 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

AI Code Review powered by Bito Logo

Comment on lines +550 to +565
{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}
/>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Uncontrolled input inconsistency

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

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the bot might have a point here, can you please double check?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is there a way to remove these and properly type?

@bito-code-review
Copy link
Contributor

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;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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={
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

@richardfogaca
Copy link
Contributor

richardfogaca commented Mar 6, 2026

  • The added tests are helpful, especially around rendering and extra form data generation. I think one more test would strengthen this: simulate typing into the new LIKE input and assert that setDataMask receives the expected ILIKE / NOT ILIKE payload. A clear-all or default-value sync test for LIKE mode would also help cover the new state-management path
  • Also could you take a look at the bot suggestion please?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dashboard:native-filters Related to the native filters of the Dashboard packages size/XL

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Enabling partial text matches in dashboard filters.

2 participants