You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@superset.apache.org by "endimonan (via GitHub)" <gi...@apache.org> on 2026/03/06 12:04:30 UTC

[PR] feat(native-filters): add configurable LIKE/ILIKE operators to Select filter [superset]

endimonan opened a new pull request, #38470:
URL: https://github.com/apache/superset/pull/38470

   ### 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 long-standing community request ([Discussion #25358](https://github.com/apache/superset/discussions/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.ts` — `getSelectExtraFormData()` 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
   
   <!-- Will add video/screenshots showing the before/after behavior -->
   
   ### TESTING INSTRUCTIONS
   
   1. Open any dashboard with a native Select filter on a text column (e.g., `name` on `birth_names`)
   2. Enter edit mode → click the filter pencil icon to configure
   3. In the configuration modal, find the new **"Match type"** dropdown under "UI Configuration"
   4. Change from "Exact match (IN)" to "Contains text (ILIKE %x%)"
   5. Save the filter configuration
   6. The filter should now show a **text input** instead of a dropdown
   7. Type a partial value (e.g., "Jen") — the dashboard charts should update showing all matching records (Jennifer, Jenna, etc.)
   8. Verify "Starts with" and "Ends with" modes work similarly
   9. Verify "Exact match" still renders the original Select dropdown
   10. Verify inverse selection (is/is not) works correctly with ILIKE operators
   
   ### ADDITIONAL INFORMATION
   - [x] Has associated issue: [Discussion #25358](https://github.com/apache/superset/discussions/25358)
   - [ ] Required feature flags:
   - [x] Changes UI
   - [ ] Includes DB Migration
   - [x] Introduces new feature or API
   - [ ] Removes existing feature or API
   
   Made with [Cursor](https://cursor.com)


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org


Re: [PR] feat(native-filters): add configurable LIKE/ILIKE operators to Select filter [superset]

Posted by "bito-code-review[bot] (via GitHub)" <gi...@apache.org>.
bito-code-review[bot] commented on code in PR #38470:
URL: https://github.com/apache/superset/pull/38470#discussion_r2895769616


##########
superset-frontend/src/filters/components/Select/SelectFilterPlugin.tsx:
##########
@@ -504,39 +547,57 @@ export default function PluginFilterSelect(props: PluginFilterSelectProps) {
               onChange={handleExclusionToggle}
             />
           )}
-          <Select
-            name={formData.nativeFilterId}
-            allowClear
-            allowNewOptions={!searchAllOptions && creatable !== false}
-            allowSelectAll={!searchAllOptions}
-            value={multiSelect ? filterState.value || [] : filterState.value}
-            disabled={isDisabled}
-            getPopupContainer={
-              showOverflow
-                ? () => (parentRef?.current as HTMLElement) || document.body
-                : (trigger: HTMLElement) =>
-                    (trigger?.parentNode as HTMLElement) || document.body
-            }
-            showSearch={showSearch}
-            mode={multiSelect ? 'multiple' : 'single'}
-            placeholder={placeholderText}
-            onClear={() => onSearch('')}
-            onSearch={onSearch}
-            onBlur={handleBlur}
-            onFocus={setFocusedFilter}
-            onMouseEnter={setHoveredFilter}
-            onMouseLeave={unsetHoveredFilter}
-            // @ts-expect-error
-            onChange={handleChange}
-            ref={inputRef}
-            loading={isRefreshing}
-            oneLine={filterBarOrientation === FilterBarOrientation.Horizontal}
-            invertSelection={inverseSelection && excludeFilterValues}
-            options={options}
-            sortComparator={sortComparator}
-            onOpenChange={setFilterActive}
-            className="select-container"
-          />
+          {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}
+            />

Review Comment:
   <div>
   
   
   <div id="suggestion">
   <div id="issue"><b>Uncontrolled input inconsistency</b></div>
   <div id="fix">
   
   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.
   </div>
   
   
   </div>
   
   
   
   
   <small><i>Code Review Run #45eb5e</i></small>
   </div>
   
   ---
   Should Bito avoid suggestions like this for future reviews? (<a href=https://alpha.bito.ai/home/ai-agents/review-rules>Manage Rules</a>)
   - [ ] Yes, avoid them



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org


Re: [PR] feat(native-filters): add configurable LIKE/ILIKE operators to Select filter [superset]

Posted by "richardfogaca (via GitHub)" <gi...@apache.org>.
richardfogaca commented on code in PR #38470:
URL: https://github.com/apache/superset/pull/38470#discussion_r2897034827


##########
superset-frontend/src/filters/components/Select/SelectFilterPlugin.test.tsx:
##########
@@ -1249,3 +1250,133 @@ test('resets dependent filter to first item when value does not exist in data',
     );
   });
 });
+
+test('renders text input instead of dropdown when operatorType is ILIKE contains', () => {
+  jest.useFakeTimers();
+  const setDataMaskMock = jest.fn();
+
+  render(
+    // @ts-expect-error

Review Comment:
   is there a way to remove these and properly type?



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org


Re: [PR] feat(native-filters): add configurable LIKE/ILIKE operators to Select filter [superset]

Posted by "richardfogaca (via GitHub)" <gi...@apache.org>.
richardfogaca commented on code in PR #38470:
URL: https://github.com/apache/superset/pull/38470#discussion_r2897081131


##########
superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FiltersConfigForm.tsx:
##########
@@ -624,6 +627,23 @@ const FiltersConfigForm = (
     forceUpdate();
   };
 
+  const currentOperatorType: SelectFilterOperatorType =
+    formFilter?.controlValues?.operatorType ??
+    filterToEdit?.controlValues?.operatorType ??
+    SelectFilterOperatorType.Exact;
+
+  const onOperatorTypeChanged = (value: SelectFilterOperatorType) => {

Review 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



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org


Re: [PR] feat(native-filters): add configurable LIKE/ILIKE operators to Select filter [superset]

Posted by "bito-code-review[bot] (via GitHub)" <gi...@apache.org>.
bito-code-review[bot] commented on PR #38470:
URL: https://github.com/apache/superset/pull/38470#issuecomment-4060581640

   AI Code Review is in progress (usually takes 3 to 15 minutes unless it's a very large PR).
   
   <details>
   <summary>
   Bito Usage Guide
   </summary>
   
   **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 <a href="https://docs.bito.ai/bito-dev-agents/ai-code-review-agent/available-commands" target="_blank" rel="noopener noreferrer">documentation</a> for additional commands.
         
   **Configuration**
   
   This repository uses `Superset` You can customize the agent settings <a href="https://alpha.bito.ai/home/ai-agents/code-review-agent" target="_blank" rel="noopener noreferrer">here</a> or contact your Bito workspace admin at evan@preset.io.
         
   **Documentation & Help**
   - <a href="https://docs.bito.ai/bito-dev-agents/ai-code-review-agent/getting-started/install-run-using-bito-cloud/create-or-customize-an-agent-instance" target="_blank" rel="noopener noreferrer">Customize agent settings</a>
   - <a href="https://docs.bito.ai/bito-dev-agents/ai-code-review-agent/implementing-custom-code-review-rules" target="_blank" rel="noopener noreferrer">Review rules</a>
   - <a href="https://docs.bito.ai/bito-dev-agents/ai-code-review-agent" target="_blank" rel="noopener noreferrer">General documentation</a>
   - <a href="https://docs.bito.ai/bito-dev-agents/ai-code-review-agent/faqs" target="_blank" rel="noopener noreferrer">FAQ</a>
   
   </details>
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org


Re: [PR] feat(native-filters): add configurable LIKE/ILIKE operators to Select filter [superset]

Posted by "endimonan (via GitHub)" <gi...@apache.org>.
endimonan commented on code in PR #38470:
URL: https://github.com/apache/superset/pull/38470#discussion_r2911552509


##########
superset-frontend/src/filters/components/Select/SelectFilterPlugin.tsx:
##########
@@ -504,39 +547,57 @@ export default function PluginFilterSelect(props: PluginFilterSelectProps) {
               onChange={handleExclusionToggle}
             />
           )}
-          <Select
-            name={formData.nativeFilterId}
-            allowClear
-            allowNewOptions={!searchAllOptions && creatable !== false}
-            allowSelectAll={!searchAllOptions}
-            value={multiSelect ? filterState.value || [] : filterState.value}
-            disabled={isDisabled}
-            getPopupContainer={
-              showOverflow
-                ? () => (parentRef?.current as HTMLElement) || document.body
-                : (trigger: HTMLElement) =>
-                    (trigger?.parentNode as HTMLElement) || document.body
-            }
-            showSearch={showSearch}
-            mode={multiSelect ? 'multiple' : 'single'}
-            placeholder={placeholderText}
-            onClear={() => onSearch('')}
-            onSearch={onSearch}
-            onBlur={handleBlur}
-            onFocus={setFocusedFilter}
-            onMouseEnter={setHoveredFilter}
-            onMouseLeave={unsetHoveredFilter}
-            // @ts-expect-error
-            onChange={handleChange}
-            ref={inputRef}
-            loading={isRefreshing}
-            oneLine={filterBarOrientation === FilterBarOrientation.Horizontal}
-            invertSelection={inverseSelection && excludeFilterValues}
-            options={options}
-            sortComparator={sortComparator}
-            onOpenChange={setFilterActive}
-            className="select-container"
-          />
+          {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}
+            />

Review Comment:
   Good catch, fixed. Switched to a controlled Input with local state (likeInputValue) synced via useEffect. Also clears on clearAllTrigger.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org


Re: [PR] feat(native-filters): add configurable LIKE/ILIKE operators to Select filter [superset]

Posted by "endimonan (via GitHub)" <gi...@apache.org>.
endimonan commented on code in PR #38470:
URL: https://github.com/apache/superset/pull/38470#discussion_r2913072561


##########
superset-frontend/src/filters/components/Select/SelectFilterPlugin.tsx:
##########
@@ -142,8 +147,11 @@ export default function PluginFilterSelect(props: PluginFilterSelectProps) {
     inverseSelection,
     defaultToFirstItem,
     searchAllOptions,
+    operatorType = SelectFilterOperatorType.Exact,
   } = formData;
 
+  const isLikeOperator = operatorType !== SelectFilterOperatorType.Exact;

Review Comment:
   Good point, done. Now `isLikeOperator` also checks that the column's datatype is `GenericDataType.String`, and the config modal only shows the `ILIKE `options when the selected column is a string type. If someone switches to a non-string column, it auto-resets to Exact match.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org


Re: [PR] feat(native-filters): add configurable LIKE/ILIKE operators to Select filter [superset]

Posted by "codeant-ai-for-open-source[bot] (via GitHub)" <gi...@apache.org>.
codeant-ai-for-open-source[bot] commented on PR #38470:
URL: https://github.com/apache/superset/pull/38470#issuecomment-4033581830

   ## **Sequence Diagram**
   
   This diagram shows how the new Match type option on the Select native filter configures LIKE and ILIKE behavior, and how user input is translated into wildcard ILIKE filters when using partial text matching.
   
   ```mermaid
   sequenceDiagram
       participant User
       participant FiltersConfigModal
       participant SelectFilterPlugin
       participant FilterUtils
       participant Backend
   
       User->>FiltersConfigModal: Open Select filter settings
       FiltersConfigModal->>FiltersConfigModal: Load column metadata and available match types
       User->>FiltersConfigModal: Choose Match type Contains text
       FiltersConfigModal-->>SelectFilterPlugin: Save operatorType for this filter
   
       User->>SelectFilterPlugin: Type search text in filter input
       SelectFilterPlugin->>FilterUtils: Build extra form data with operator type and value
       FilterUtils-->>SelectFilterPlugin: Return filters using ILIKE with wildcards
       SelectFilterPlugin-->>Backend: Update data mask and run query with new filter
       Backend-->>User: Return results matching partial text
   ```
   
   ---
   *Generated by [CodeAnt AI](https://codeant.ai)*
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org


Re: [PR] feat(native-filters): add configurable LIKE/ILIKE operators to Select filter [superset]

Posted by "endimonan (via GitHub)" <gi...@apache.org>.
endimonan commented on code in PR #38470:
URL: https://github.com/apache/superset/pull/38470#discussion_r2936444399


##########
superset-frontend/src/filters/components/Select/SelectFilterPlugin.test.tsx:
##########
@@ -1249,3 +1284,399 @@ test('resets dependent filter to first item when value does not exist in data',
     );
   });
 });
+
+test('renders text input instead of dropdown when operatorType is ILIKE contains', () => {
+  jest.useFakeTimers();
+  const setDataMaskMock = jest.fn();
+  const props = buildSelectFilterProps({
+    formData: { operatorType: SelectFilterOperatorType.Contains },
+    filterState: { value: undefined },
+    setDataMask: setDataMaskMock,
+  });
+
+  render(<SelectFilterPlugin {...props} />, {
+    useRedux: true,
+    initialState: {
+      nativeFilters: {
+        filters: { 'test-filter': { name: 'Test Filter' } },
+      },
+      dataMask: {
+        'test-filter': {
+          extraFormData: {},
+          filterState: { value: undefined },
+        },
+      },
+    },
+  });
+
+  expect(screen.queryByRole('combobox')).not.toBeInTheDocument();
+  expect(
+    screen.getByPlaceholderText('Type to search (contains)...'),
+  ).toBeInTheDocument();
+});
+
+test('renders text input with starts-with placeholder', () => {
+  jest.useFakeTimers();
+  const setDataMaskMock = jest.fn();
+  const props = buildSelectFilterProps({
+    formData: { operatorType: SelectFilterOperatorType.StartsWith },
+    filterState: { value: undefined },
+    setDataMask: setDataMaskMock,
+  });
+
+  render(<SelectFilterPlugin {...props} />, {
+    useRedux: true,
+    initialState: {
+      nativeFilters: {
+        filters: { 'test-filter': { name: 'Test Filter' } },
+      },
+      dataMask: {
+        'test-filter': {
+          extraFormData: {},
+          filterState: { value: undefined },
+        },
+      },
+    },
+  });
+
+  expect(
+    screen.getByPlaceholderText('Type to search (starts with)...'),
+  ).toBeInTheDocument();
+});
+
+test('typing in LIKE input calls setDataMask with ILIKE Contains payload', async () => {
+  jest.useFakeTimers();
+  const setDataMaskMock = jest.fn();
+  const props = buildSelectFilterProps({
+    formData: { operatorType: SelectFilterOperatorType.Contains },
+    filterState: { value: undefined },
+    setDataMask: setDataMaskMock,
+  });
+
+  render(<SelectFilterPlugin {...props} />, {
+    useRedux: true,
+    initialState: {
+      nativeFilters: {
+        filters: { 'test-filter': { name: 'Test Filter' } },
+      },
+      dataMask: {
+        'test-filter': {
+          extraFormData: {},
+          filterState: { value: undefined },
+        },
+      },
+    },
+  });
+
+  setDataMaskMock.mockClear();
+  const input = screen.getByPlaceholderText('Type to search (contains)...');
+  fireEvent.change(input, { target: { value: 'Jen' } });
+  act(() => {
+    jest.advanceTimersByTime(500);
+  });
+
+  expect(setDataMaskMock).toHaveBeenCalledWith(
+    expect.objectContaining({
+      extraFormData: {
+        filters: [
+          {
+            col: 'gender',
+            op: 'ILIKE',
+            val: '%Jen%',
+          },
+        ],
+      },
+    }),
+  );
+});
+
+test('typing in LIKE input with inverse selection calls setDataMask with NOT ILIKE payload', async () => {
+  jest.useFakeTimers();
+  const setDataMaskMock = jest.fn();
+  const props = buildSelectFilterProps({
+    formData: {
+      operatorType: SelectFilterOperatorType.Contains,
+      inverseSelection: true,
+    },
+    filterState: { value: undefined },
+    setDataMask: setDataMaskMock,
+  });
+
+  render(<SelectFilterPlugin {...props} />, {
+    useRedux: true,
+    initialState: {
+      nativeFilters: {
+        filters: { 'test-filter': { name: 'Test Filter' } },
+      },
+      dataMask: {
+        'test-filter': {
+          extraFormData: {},
+          filterState: { value: undefined },
+        },
+      },
+    },
+  });
+
+  setDataMaskMock.mockClear();
+  const input = screen.getByPlaceholderText('Type to search (contains)...');
+  fireEvent.change(input, { target: { value: 'Jen' } });
+  act(() => {
+    jest.advanceTimersByTime(500);
+  });
+
+  expect(setDataMaskMock).toHaveBeenCalledWith(
+    expect.objectContaining({
+      extraFormData: {
+        filters: [
+          {
+            col: 'gender',
+            op: 'NOT ILIKE',
+            val: '%Jen%',
+          },
+        ],
+      },
+    }),
+  );
+});
+
+test('clear-all resets LIKE input value and calls setDataMask with empty state', async () => {
+  jest.useFakeTimers();
+  const setDataMaskMock = jest.fn();
+  const likeProps = buildSelectFilterProps({
+    formData: { operatorType: SelectFilterOperatorType.Contains },
+    filterState: { value: ['Jen'] },
+    setDataMask: setDataMaskMock,
+  });
+
+  const reduxState = {
+    useRedux: true,
+    initialState: {
+      nativeFilters: {
+        filters: { 'test-filter': { name: 'Test Filter' } },
+      },
+      dataMask: {
+        'test-filter': {
+          extraFormData: {
+            filters: [{ col: 'gender', op: 'ILIKE', val: '%Jen%' }],
+          },
+          filterState: { value: ['Jen'] },
+        },
+      },
+    },
+  };
+
+  const { rerender } = render(
+    <SelectFilterPlugin {...likeProps} />,
+    reduxState,
+  );
+
+  const input = screen.getByPlaceholderText('Type to search (contains)...');
+  expect(input).toHaveValue('Jen');
+
+  setDataMaskMock.mockClear();
+
+  rerender(
+    <SelectFilterPlugin
+      {...likeProps}
+      clearAllTrigger={{ 'test-filter': true }}
+    />,
+  );
+
+  await waitFor(() => {
+    expect(input).toHaveValue('');
+  });
+
+  await waitFor(() => {
+    expect(setDataMaskMock).toHaveBeenCalledWith(
+      expect.objectContaining({
+        filterState: expect.objectContaining({
+          value: null,
+        }),
+      }),
+    );
+  });
+
+  act(() => {
+    jest.advanceTimersByTime(500);
+  });
+
+  expect(setDataMaskMock).not.toHaveBeenCalledWith(
+    expect.objectContaining({
+      extraFormData: {
+        filters: [
+          {
+            col: 'gender',
+            op: 'ILIKE',
+            val: '%Jen%',
+          },
+        ],
+      },
+    }),
+  );
+});
+
+test('pending LIKE debounce still applies after rerender recreates updateDataMask', async () => {
+  jest.useFakeTimers();
+  const setDataMaskMock = jest.fn();
+  const likeProps = buildSelectFilterProps({
+    formData: { operatorType: SelectFilterOperatorType.Contains },
+    filterState: { value: undefined },
+    setDataMask: setDataMaskMock,
+  });
+
+  const reduxState = {
+    useRedux: true,
+    initialState: {
+      nativeFilters: {
+        filters: { 'test-filter': { name: 'Test Filter' } },
+      },
+      dataMask: {
+        'test-filter': {
+          extraFormData: {},
+          filterState: { value: undefined },
+        },
+      },
+    },
+  };
+
+  const { rerender } = render(
+    <SelectFilterPlugin {...likeProps} />,
+    reduxState,
+  );
+
+  fireEvent.change(
+    screen.getByPlaceholderText('Type to search (contains)...'),
+    {
+      target: { value: 'Jen' },
+    },
+  );
+
+  setDataMaskMock.mockClear();
+
+  rerender(
+    <SelectFilterPlugin
+      {...buildSelectFilterProps({
+        formData: { operatorType: SelectFilterOperatorType.Contains },
+        filterState: { value: undefined, label: 'external change' },
+        setDataMask: setDataMaskMock,
+      })}
+    />,
+  );
+
+  act(() => {
+    jest.advanceTimersByTime(500);
+  });
+
+  expect(setDataMaskMock).toHaveBeenCalledWith(
+    expect.objectContaining({
+      extraFormData: {
+        filters: [
+          {
+            col: 'gender',
+            op: 'ILIKE',
+            val: '%Jen%',
+          },
+        ],
+      },
+    }),
+  );
+});
+
+test('pending LIKE debounce is canceled when operatorType switches back to Exact', async () => {
+  jest.useFakeTimers();
+  const setDataMaskMock = jest.fn();
+  const likeProps = buildSelectFilterProps({
+    formData: { operatorType: SelectFilterOperatorType.Contains },
+    filterState: { value: undefined },
+    setDataMask: setDataMaskMock,
+  });
+
+  const reduxState = {
+    useRedux: true,
+    initialState: {
+      nativeFilters: {
+        filters: { 'test-filter': { name: 'Test Filter' } },
+      },
+      dataMask: {
+        'test-filter': {
+          extraFormData: {},
+          filterState: { value: undefined },
+        },
+      },
+    },
+  };
+
+  const { rerender } = render(
+    <SelectFilterPlugin {...likeProps} />,
+    reduxState,
+  );
+
+  fireEvent.change(
+    screen.getByPlaceholderText('Type to search (contains)...'),
+    {
+      target: { value: 'Jen' },
+    },
+  );
+
+  setDataMaskMock.mockClear();
+
+  rerender(
+    <SelectFilterPlugin
+      {...buildSelectFilterProps({
+        formData: { operatorType: SelectFilterOperatorType.Exact },
+        filterState: { value: undefined },
+        setDataMask: setDataMaskMock,
+      })}
+    />,
+  );
+
+  act(() => {
+    jest.advanceTimersByTime(500);
+  });
+
+  expect(setDataMaskMock).not.toHaveBeenCalledWith(
+    expect.objectContaining({
+      extraFormData: {
+        filters: [
+          {
+            col: 'gender',
+            op: 'ILIKE',
+            val: '%Jen%',
+          },
+        ],
+      },
+    }),
+  );

Review Comment:
   Done



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org


Re: [PR] feat(native-filters): add configurable LIKE/ILIKE operators to Select filter [superset]

Posted by "richardfogaca (via GitHub)" <gi...@apache.org>.
richardfogaca commented on code in PR #38470:
URL: https://github.com/apache/superset/pull/38470#discussion_r2897054713


##########
superset-frontend/src/filters/components/Select/SelectFilterPlugin.tsx:
##########
@@ -504,39 +547,57 @@ export default function PluginFilterSelect(props: PluginFilterSelectProps) {
               onChange={handleExclusionToggle}
             />
           )}
-          <Select
-            name={formData.nativeFilterId}
-            allowClear
-            allowNewOptions={!searchAllOptions && creatable !== false}
-            allowSelectAll={!searchAllOptions}
-            value={multiSelect ? filterState.value || [] : filterState.value}
-            disabled={isDisabled}
-            getPopupContainer={
-              showOverflow
-                ? () => (parentRef?.current as HTMLElement) || document.body
-                : (trigger: HTMLElement) =>
-                    (trigger?.parentNode as HTMLElement) || document.body
-            }
-            showSearch={showSearch}
-            mode={multiSelect ? 'multiple' : 'single'}
-            placeholder={placeholderText}
-            onClear={() => onSearch('')}
-            onSearch={onSearch}
-            onBlur={handleBlur}
-            onFocus={setFocusedFilter}
-            onMouseEnter={setHoveredFilter}
-            onMouseLeave={unsetHoveredFilter}
-            // @ts-expect-error
-            onChange={handleChange}
-            ref={inputRef}
-            loading={isRefreshing}
-            oneLine={filterBarOrientation === FilterBarOrientation.Horizontal}
-            invertSelection={inverseSelection && excludeFilterValues}
-            options={options}
-            sortComparator={sortComparator}
-            onOpenChange={setFilterActive}
-            className="select-container"
-          />
+          {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}
+            />

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



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org


Re: [PR] feat(native-filters): add configurable LIKE/ILIKE operators to Select filter [superset]

Posted by "bito-code-review[bot] (via GitHub)" <gi...@apache.org>.
bito-code-review[bot] commented on PR #38470:
URL: https://github.com/apache/superset/pull/38470#issuecomment-4011356356

   AI Code Review is in progress (usually takes 3 to 15 minutes unless it's a very large PR).


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org


Re: [PR] feat(native-filters): add configurable LIKE/ILIKE operators to Select filter [superset]

Posted by "bito-code-review[bot] (via GitHub)" <gi...@apache.org>.
bito-code-review[bot] commented on PR #38470:
URL: https://github.com/apache/superset/pull/38470#issuecomment-4033482722

   AI Code Review is in progress (usually takes 3 to 15 minutes unless it's a very large PR).
   
   <details>
   <summary>
   Bito Usage Guide
   </summary>
   
   **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 <a href="https://docs.bito.ai/bito-dev-agents/ai-code-review-agent/available-commands" target="_blank" rel="noopener noreferrer">documentation</a> for additional commands.
         
   **Configuration**
   
   This repository uses `Superset` You can customize the agent settings <a href="https://alpha.bito.ai/home/ai-agents/code-review-agent" target="_blank" rel="noopener noreferrer">here</a> or contact your Bito workspace admin at evan@preset.io.
         
   **Documentation & Help**
   - <a href="https://docs.bito.ai/bito-dev-agents/ai-code-review-agent/getting-started/install-run-using-bito-cloud/create-or-customize-an-agent-instance" target="_blank" rel="noopener noreferrer">Customize agent settings</a>
   - <a href="https://docs.bito.ai/bito-dev-agents/ai-code-review-agent/implementing-custom-code-review-rules" target="_blank" rel="noopener noreferrer">Review rules</a>
   - <a href="https://docs.bito.ai/bito-dev-agents/ai-code-review-agent" target="_blank" rel="noopener noreferrer">General documentation</a>
   - <a href="https://docs.bito.ai/bito-dev-agents/ai-code-review-agent/faqs" target="_blank" rel="noopener noreferrer">FAQ</a>
   
   </details>
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org


Re: [PR] feat(native-filters): add configurable LIKE/ILIKE operators to Select filter [superset]

Posted by "bito-code-review[bot] (via GitHub)" <gi...@apache.org>.
bito-code-review[bot] commented on PR #38470:
URL: https://github.com/apache/superset/pull/38470#issuecomment-4062658969

   AI Code Review is in progress (usually takes 3 to 15 minutes unless it's a very large PR).
   
   <details>
   <summary>
   Bito Usage Guide
   </summary>
   
   **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 <a href="https://docs.bito.ai/bito-dev-agents/ai-code-review-agent/available-commands" target="_blank" rel="noopener noreferrer">documentation</a> for additional commands.
         
   **Configuration**
   
   This repository uses `Superset` You can customize the agent settings <a href="https://alpha.bito.ai/home/ai-agents/code-review-agent" target="_blank" rel="noopener noreferrer">here</a> or contact your Bito workspace admin at evan@preset.io.
         
   **Documentation & Help**
   - <a href="https://docs.bito.ai/bito-dev-agents/ai-code-review-agent/getting-started/install-run-using-bito-cloud/create-or-customize-an-agent-instance" target="_blank" rel="noopener noreferrer">Customize agent settings</a>
   - <a href="https://docs.bito.ai/bito-dev-agents/ai-code-review-agent/implementing-custom-code-review-rules" target="_blank" rel="noopener noreferrer">Review rules</a>
   - <a href="https://docs.bito.ai/bito-dev-agents/ai-code-review-agent" target="_blank" rel="noopener noreferrer">General documentation</a>
   - <a href="https://docs.bito.ai/bito-dev-agents/ai-code-review-agent/faqs" target="_blank" rel="noopener noreferrer">FAQ</a>
   
   </details>
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org


Re: [PR] feat(native-filters): add configurable LIKE/ILIKE operators to Select filter [superset]

Posted by "codeant-ai-for-open-source[bot] (via GitHub)" <gi...@apache.org>.
codeant-ai-for-open-source[bot] commented on PR #38470:
URL: https://github.com/apache/superset/pull/38470#issuecomment-4031179895

   ## **Sequence Diagram**
   
   This PR adds a configurable match type to the Select (Value) native filter so creators can choose exact IN matching or partial ILIKE text matching, and the runtime filter switches between a dropdown and a debounced text input to generate the appropriate query filters.
   
   ```mermaid
   sequenceDiagram
       participant Creator
       participant FiltersConfigModal
       participant FilterConfigStore
       participant Viewer
       participant SelectFilter
       participant FilterUtils
       participant Backend
   
       Creator->>FiltersConfigModal: Open filter configuration
       FiltersConfigModal->>Creator: Show Match type dropdown
       Creator->>FiltersConfigModal: Select match type (Exact or ILIKE)
       FiltersConfigModal->>FilterConfigStore: Save operatorType in filter control values
   
       Viewer->>SelectFilter: Use filter on dashboard
       SelectFilter->>FilterConfigStore: Read operatorType
   
       alt Exact match
           SelectFilter-->>Viewer: Render value dropdown
           Viewer->>SelectFilter: Choose one or more values
           SelectFilter->>FilterUtils: Build IN or NOT IN extra form data
       else Partial text match
           SelectFilter-->>Viewer: Render debounced text input
           Viewer->>SelectFilter: Type search text
           SelectFilter->>FilterUtils: Build ILIKE or NOT ILIKE extra form data with wildcards
       end
   
       FilterUtils->>Backend: Apply filters in query
       Backend-->>Viewer: Return filtered results
   ```
   
   ---
   *Generated by [CodeAnt AI](https://codeant.ai)*
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org


Re: [PR] feat(native-filters): add configurable LIKE/ILIKE operators to Select filter [superset]

Posted by "richardfogaca (via GitHub)" <gi...@apache.org>.
richardfogaca commented on code in PR #38470:
URL: https://github.com/apache/superset/pull/38470#discussion_r2914024408


##########
superset-frontend/src/filters/components/Select/SelectFilterPlugin.test.tsx:
##########
@@ -1249,3 +1250,133 @@ test('resets dependent filter to first item when value does not exist in data',
     );
   });
 });
+
+test('renders text input instead of dropdown when operatorType is ILIKE contains', () => {
+  jest.useFakeTimers();
+  const setDataMaskMock = jest.fn();
+
+  render(
+    // @ts-expect-error

Review Comment:
   I see your point, but I’d rather not add more @ts-expect-error in new tests just because the file already has some existing ones.
   
   Can you avoid repeating that pattern here, ideally by using a small shared helper or a single centralized cast? I’m not asking for a broader typing refactor in this PR, only to avoid extending the suppression pattern in the new coverage.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org


Re: [PR] feat(native-filters): add configurable LIKE/ILIKE operators to Select filter [superset]

Posted by "bito-code-review[bot] (via GitHub)" <gi...@apache.org>.
bito-code-review[bot] commented on PR #38470:
URL: https://github.com/apache/superset/pull/38470#issuecomment-4032279504

   AI Code Review is in progress (usually takes 3 to 15 minutes unless it's a very large PR).
   
   <details>
   <summary>
   Bito Usage Guide
   </summary>
   
   **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 <a href="https://docs.bito.ai/bito-dev-agents/ai-code-review-agent/available-commands" target="_blank" rel="noopener noreferrer">documentation</a> for additional commands.
         
   **Configuration**
   
   This repository uses `Superset` You can customize the agent settings <a href="https://alpha.bito.ai/home/ai-agents/code-review-agent" target="_blank" rel="noopener noreferrer">here</a> or contact your Bito workspace admin at evan@preset.io.
         
   **Documentation & Help**
   - <a href="https://docs.bito.ai/bito-dev-agents/ai-code-review-agent/getting-started/install-run-using-bito-cloud/create-or-customize-an-agent-instance" target="_blank" rel="noopener noreferrer">Customize agent settings</a>
   - <a href="https://docs.bito.ai/bito-dev-agents/ai-code-review-agent/implementing-custom-code-review-rules" target="_blank" rel="noopener noreferrer">Review rules</a>
   - <a href="https://docs.bito.ai/bito-dev-agents/ai-code-review-agent" target="_blank" rel="noopener noreferrer">General documentation</a>
   - <a href="https://docs.bito.ai/bito-dev-agents/ai-code-review-agent/faqs" target="_blank" rel="noopener noreferrer">FAQ</a>
   
   </details>
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org


Re: [PR] feat(native-filters): add configurable LIKE/ILIKE operators to Select filter [superset]

Posted by "endimonan (via GitHub)" <gi...@apache.org>.
endimonan commented on code in PR #38470:
URL: https://github.com/apache/superset/pull/38470#discussion_r2913091232


##########
superset-frontend/src/filters/components/Select/SelectFilterPlugin.tsx:
##########
@@ -504,39 +547,57 @@ export default function PluginFilterSelect(props: PluginFilterSelectProps) {
               onChange={handleExclusionToggle}
             />
           )}
-          <Select
-            name={formData.nativeFilterId}
-            allowClear
-            allowNewOptions={!searchAllOptions && creatable !== false}
-            allowSelectAll={!searchAllOptions}
-            value={multiSelect ? filterState.value || [] : filterState.value}
-            disabled={isDisabled}
-            getPopupContainer={
-              showOverflow
-                ? () => (parentRef?.current as HTMLElement) || document.body
-                : (trigger: HTMLElement) =>
-                    (trigger?.parentNode as HTMLElement) || document.body
-            }
-            showSearch={showSearch}
-            mode={multiSelect ? 'multiple' : 'single'}
-            placeholder={placeholderText}
-            onClear={() => onSearch('')}
-            onSearch={onSearch}
-            onBlur={handleBlur}
-            onFocus={setFocusedFilter}
-            onMouseEnter={setHoveredFilter}
-            onMouseLeave={unsetHoveredFilter}
-            // @ts-expect-error
-            onChange={handleChange}
-            ref={inputRef}
-            loading={isRefreshing}
-            oneLine={filterBarOrientation === FilterBarOrientation.Horizontal}
-            invertSelection={inverseSelection && excludeFilterValues}
-            options={options}
-            sortComparator={sortComparator}
-            onOpenChange={setFilterActive}
-            className="select-container"
-          />
+          {isLikeOperator ? (
+            <Input
+              allowClear
+              placeholder={likeInputPlaceholder}
+              defaultValue={

Review Comment:
   Fixed in the same commit, switched to a controlled Input with local state synced via useEffect so it stays in sync with external changes and clear-all.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org


Re: [PR] feat(native-filters): add configurable LIKE/ILIKE operators to Select filter [superset]

Posted by "endimonan (via GitHub)" <gi...@apache.org>.
endimonan commented on code in PR #38470:
URL: https://github.com/apache/superset/pull/38470#discussion_r2936456222


##########
superset-frontend/src/filters/components/Select/SelectFilterPlugin.test.tsx:
##########
@@ -1249,3 +1284,387 @@ test('resets dependent filter to first item when value does not exist in data',
     );
   });
 });
+
+test('renders text input instead of dropdown when operatorType is ILIKE contains', () => {
+  jest.useFakeTimers();
+  const setDataMaskMock = jest.fn();
+  const props = buildSelectFilterProps({
+    formData: { operatorType: SelectFilterOperatorType.Contains },
+    filterState: { value: undefined },
+    setDataMask: setDataMaskMock,
+  });
+
+  render(<SelectFilterPlugin {...props} />, {
+    useRedux: true,
+    initialState: {
+      nativeFilters: {
+        filters: { 'test-filter': { name: 'Test Filter' } },
+      },
+      dataMask: {
+        'test-filter': {
+          extraFormData: {},
+          filterState: { value: undefined },
+        },
+      },
+    },
+  });
+
+  expect(screen.queryByRole('combobox')).not.toBeInTheDocument();
+  expect(
+    screen.getByPlaceholderText('Type to search (contains)...'),
+  ).toBeInTheDocument();
+});
+
+test('renders text input with starts-with placeholder', () => {
+  jest.useFakeTimers();
+  const setDataMaskMock = jest.fn();
+  const props = buildSelectFilterProps({
+    formData: { operatorType: SelectFilterOperatorType.StartsWith },
+    filterState: { value: undefined },
+    setDataMask: setDataMaskMock,
+  });
+
+  render(<SelectFilterPlugin {...props} />, {
+    useRedux: true,
+    initialState: {
+      nativeFilters: {
+        filters: { 'test-filter': { name: 'Test Filter' } },
+      },
+      dataMask: {
+        'test-filter': {
+          extraFormData: {},
+          filterState: { value: undefined },
+        },
+      },
+    },
+  });
+
+  expect(
+    screen.getByPlaceholderText('Type to search (starts with)...'),
+  ).toBeInTheDocument();
+});
+
+test('typing in LIKE input calls setDataMask with ILIKE Contains payload', async () => {
+  jest.useFakeTimers();
+  const setDataMaskMock = jest.fn();
+  const props = buildSelectFilterProps({
+    formData: { operatorType: SelectFilterOperatorType.Contains },
+    filterState: { value: undefined },
+    setDataMask: setDataMaskMock,
+  });
+
+  render(<SelectFilterPlugin {...props} />, {
+    useRedux: true,
+    initialState: {
+      nativeFilters: {
+        filters: { 'test-filter': { name: 'Test Filter' } },
+      },
+      dataMask: {
+        'test-filter': {
+          extraFormData: {},
+          filterState: { value: undefined },
+        },
+      },
+    },
+  });
+
+  setDataMaskMock.mockClear();
+  const input = screen.getByPlaceholderText('Type to search (contains)...');
+  fireEvent.change(input, { target: { value: 'Jen' } });
+  act(() => {
+    jest.advanceTimersByTime(500);
+  });
+
+  expect(setDataMaskMock).toHaveBeenCalledWith(
+    expect.objectContaining({
+      extraFormData: {
+        filters: [
+          {
+            col: 'gender',
+            op: 'ILIKE',
+            val: '%Jen%',
+          },
+        ],
+      },
+    }),
+  );
+});
+
+test('typing in LIKE input with inverse selection calls setDataMask with NOT ILIKE payload', async () => {
+  jest.useFakeTimers();
+  const setDataMaskMock = jest.fn();
+  const props = buildSelectFilterProps({
+    formData: {
+      operatorType: SelectFilterOperatorType.Contains,
+      inverseSelection: true,
+    },
+    filterState: { value: undefined },
+    setDataMask: setDataMaskMock,
+  });
+
+  render(<SelectFilterPlugin {...props} />, {
+    useRedux: true,
+    initialState: {
+      nativeFilters: {
+        filters: { 'test-filter': { name: 'Test Filter' } },
+      },
+      dataMask: {
+        'test-filter': {
+          extraFormData: {},
+          filterState: { value: undefined },
+        },
+      },
+    },
+  });
+
+  setDataMaskMock.mockClear();
+  const input = screen.getByPlaceholderText('Type to search (contains)...');
+  fireEvent.change(input, { target: { value: 'Jen' } });
+  act(() => {
+    jest.advanceTimersByTime(500);
+  });
+
+  expect(setDataMaskMock).toHaveBeenCalledWith(
+    expect.objectContaining({
+      extraFormData: {
+        filters: [
+          {
+            col: 'gender',
+            op: 'NOT ILIKE',
+            val: '%Jen%',
+          },
+        ],
+      },
+    }),
+  );
+});
+
+test('clear-all resets LIKE input value and calls setDataMask with empty state', async () => {
+  jest.useFakeTimers();
+  const setDataMaskMock = jest.fn();
+  const likeProps = buildSelectFilterProps({
+    formData: { operatorType: SelectFilterOperatorType.Contains },
+    filterState: { value: ['Jen'] },
+    setDataMask: setDataMaskMock,
+  });
+
+  const reduxState = {
+    useRedux: true,
+    initialState: {
+      nativeFilters: {
+        filters: { 'test-filter': { name: 'Test Filter' } },
+      },
+      dataMask: {
+        'test-filter': {
+          extraFormData: {
+            filters: [{ col: 'gender', op: 'ILIKE', val: '%Jen%' }],
+          },
+          filterState: { value: ['Jen'] },
+        },
+      },
+    },
+  };
+
+  const { rerender } = render(
+    <SelectFilterPlugin {...likeProps} />,
+    reduxState,
+  );
+
+  const input = screen.getByPlaceholderText('Type to search (contains)...');
+  expect(input).toHaveValue('Jen');
+
+  setDataMaskMock.mockClear();
+
+  rerender(
+    <SelectFilterPlugin
+      {...likeProps}
+      clearAllTrigger={{ 'test-filter': true }}
+    />,
+  );
+
+  await waitFor(() => {
+    expect(input).toHaveValue('');
+  });
+
+  await waitFor(() => {
+    expect(setDataMaskMock).toHaveBeenCalledWith(
+      expect.objectContaining({
+        filterState: expect.objectContaining({
+          value: null,
+        }),
+      }),
+    );
+  });
+
+  act(() => {
+    jest.advanceTimersByTime(500);
+  });
+
+  expect(setDataMaskMock).not.toHaveBeenCalled();

Review Comment:
   I fixed the clear-all test to assert no extra call after the timer flush, instead of no calls at all. The other test stays as-is because that scenario should not call setDataMask after the flush.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org


Re: [PR] feat(native-filters): add configurable LIKE/ILIKE operators to Select filter [superset]

Posted by "richardfogaca (via GitHub)" <gi...@apache.org>.
richardfogaca commented on PR #38470:
URL: https://github.com/apache/superset/pull/38470#issuecomment-4013170896

   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


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org


Re: [PR] feat(native-filters): add configurable LIKE/ILIKE operators to Select filter [superset]

Posted by "endimonan (via GitHub)" <gi...@apache.org>.
endimonan commented on code in PR #38470:
URL: https://github.com/apache/superset/pull/38470#discussion_r2912151344


##########
superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FiltersConfigForm.tsx:
##########
@@ -1698,6 +1718,57 @@ const FiltersConfigForm = (
                               )}
                             </CollapsibleControl>
                           </FormItem>
+                          {!isChartCustomization && (
+                            <StyledRowFormItem
+                              expanded={expanded}
+                              name={[
+                                'filters',
+                                filterId,
+                                'controlValues',
+                                'operatorType',
+                              ]}
+                              initialValue={currentOperatorType}
+                              label={
+                                <>
+                                  <StyledLabel>{t('Match type')}</StyledLabel>
+                                  &nbsp;
+                                  <InfoTooltip
+                                    placement="top"
+                                    tooltip={t(
+                                      'Warning: ILIKE queries may be slow on large datasets as they cannot use indexes effectively.',
+                                    )}
+                                  />
+                                </>
+                              }
+                            >
+                              <Select
+                                ariaLabel={t('Match type')}
+                                options={[
+                                  {
+                                    value: SelectFilterOperatorType.Exact,
+                                    label: t('Exact match (IN)'),
+                                  },
+                                  {
+                                    value: SelectFilterOperatorType.Contains,
+                                    label: t('Contains text (ILIKE %x%)'),
+                                  },
+                                  {
+                                    value: SelectFilterOperatorType.StartsWith,
+                                    label: t('Starts with (ILIKE x%)'),
+                                  },
+                                  {
+                                    value: SelectFilterOperatorType.EndsWith,
+                                    label: t('Ends with (ILIKE %x)'),
+                                  },
+                                ]}
+                                onChange={value => {
+                                  onOperatorTypeChanged(
+                                    value as SelectFilterOperatorType,
+                                  );
+                                }}
+                              />
+                            </StyledRowFormItem>
+                          )}

Review Comment:
   Makes sense, the Match type dropdown is only relevant to the Select filter since the other native filter types (range, time, timegrain) don't use text matching operators



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org


Re: [PR] feat(native-filters): add configurable LIKE/ILIKE operators to Select filter [superset]

Posted by "netlify[bot] (via GitHub)" <gi...@apache.org>.
netlify[bot] commented on PR #38470:
URL: https://github.com/apache/superset/pull/38470#issuecomment-4031198812

   ### <span aria-hidden="true">✅</span> Deploy Preview for *superset-docs-preview* ready!
   
   
   |  Name | Link |
   |:-:|------------------------|
   |<span aria-hidden="true">🔨</span> Latest commit | b965f5873783a81cea9f09c94623aa1694c09747 |
   |<span aria-hidden="true">🔍</span> Latest deploy log | https://app.netlify.com/projects/superset-docs-preview/deploys/69b01431a857e50007f3b9cf |
   |<span aria-hidden="true">😎</span> Deploy Preview | [https://deploy-preview-38470--superset-docs-preview.netlify.app](https://deploy-preview-38470--superset-docs-preview.netlify.app) |
   |<span aria-hidden="true">📱</span> Preview on mobile | <details><summary> Toggle QR Code... </summary><br /><br />![QR Code](https://app.netlify.com/qr-code/eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1cmwiOiJodHRwczovL2RlcGxveS1wcmV2aWV3LTM4NDcwLS1zdXBlcnNldC1kb2NzLXByZXZpZXcubmV0bGlmeS5hcHAifQ.rHPXSJb5cyx7kZnyprtvwXE_WflUSCJe3T41u8LEj2U)<br /><br />_Use your smartphone camera to open QR code link._</details> |
   ---
   <!-- [superset-docs-preview Preview](https://deploy-preview-38470--superset-docs-preview.netlify.app) -->
   _To edit notification comments on pull requests, go to your [Netlify project configuration](https://app.netlify.com/projects/superset-docs-preview/configuration/notifications#deploy-notifications)._


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org


Re: [PR] feat(native-filters): add configurable LIKE/ILIKE operators to Select filter [superset]

Posted by "endimonan (via GitHub)" <gi...@apache.org>.
endimonan commented on code in PR #38470:
URL: https://github.com/apache/superset/pull/38470#discussion_r2911586907


##########
superset-frontend/src/filters/components/Select/SelectFilterPlugin.test.tsx:
##########
@@ -1249,3 +1250,133 @@ test('resets dependent filter to first item when value does not exist in data',
     );
   });
 });
+
+test('renders text input instead of dropdown when operatorType is ILIKE contains', () => {
+  jest.useFakeTimers();
+  const setDataMaskMock = jest.fn();
+
+  render(
+    // @ts-expect-error

Review Comment:
   Those are inherited from the existing tests, the getWrapper helper on line 83 already uses the same pattern. The issue is that transformProps returns a type that doesn't fully match the component props. Fixing it properly would mean reworking the return type or creating a test fixture type, so I'd rather keep it consistent with what's already there and do that cleanup separately. What do you think?



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org


Re: [PR] feat(native-filters): add configurable LIKE/ILIKE operators to Select filter [superset]

Posted by "bito-code-review[bot] (via GitHub)" <gi...@apache.org>.
bito-code-review[bot] commented on PR #38470:
URL: https://github.com/apache/superset/pull/38470#issuecomment-4038874242

   AI Code Review is in progress (usually takes 3 to 15 minutes unless it's a very large PR).
   
   <details>
   <summary>
   Bito Usage Guide
   </summary>
   
   **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 <a href="https://docs.bito.ai/bito-dev-agents/ai-code-review-agent/available-commands" target="_blank" rel="noopener noreferrer">documentation</a> for additional commands.
         
   **Configuration**
   
   This repository uses `Superset` You can customize the agent settings <a href="https://alpha.bito.ai/home/ai-agents/code-review-agent" target="_blank" rel="noopener noreferrer">here</a> or contact your Bito workspace admin at evan@preset.io.
         
   **Documentation & Help**
   - <a href="https://docs.bito.ai/bito-dev-agents/ai-code-review-agent/getting-started/install-run-using-bito-cloud/create-or-customize-an-agent-instance" target="_blank" rel="noopener noreferrer">Customize agent settings</a>
   - <a href="https://docs.bito.ai/bito-dev-agents/ai-code-review-agent/implementing-custom-code-review-rules" target="_blank" rel="noopener noreferrer">Review rules</a>
   - <a href="https://docs.bito.ai/bito-dev-agents/ai-code-review-agent" target="_blank" rel="noopener noreferrer">General documentation</a>
   - <a href="https://docs.bito.ai/bito-dev-agents/ai-code-review-agent/faqs" target="_blank" rel="noopener noreferrer">FAQ</a>
   
   </details>
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org


Re: [PR] feat(native-filters): add configurable LIKE/ILIKE operators to Select filter [superset]

Posted by "codeant-ai-for-open-source[bot] (via GitHub)" <gi...@apache.org>.
codeant-ai-for-open-source[bot] commented on PR #38470:
URL: https://github.com/apache/superset/pull/38470#issuecomment-4033141760

   ## **Sequence Diagram**
   
   This PR lets filter authors choose a match type for Select filters and, at runtime, uses that configuration to switch between exact IN filtering and text-based ILIKE filtering driven by a free-text input.
   
   ```mermaid
   sequenceDiagram
       participant Author
       participant DashboardConfig
       participant Viewer
       participant SelectFilter
       participant QueryEngine
   
       Author->>DashboardConfig: Configure Select filter match type (e.g. Contains text)
       DashboardConfig->>DashboardConfig: Save operatorType for the filter
   
       Viewer->>SelectFilter: Enter search text in Select filter
       SelectFilter->>SelectFilter: Decide IN vs ILIKE and build ExtraFormData
       SelectFilter->>QueryEngine: Request data with configured match operator
       QueryEngine-->>SelectFilter: Return rows matching filter
       SelectFilter-->>Viewer: Update charts and filter state
   ```
   
   ---
   *Generated by [CodeAnt AI](https://codeant.ai)*
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org


Re: [PR] feat(native-filters): add configurable LIKE/ILIKE operators to Select filter [superset]

Posted by "bito-code-review[bot] (via GitHub)" <gi...@apache.org>.
bito-code-review[bot] commented on code in PR #38470:
URL: https://github.com/apache/superset/pull/38470#discussion_r2911560574


##########
superset-frontend/src/filters/components/Select/SelectFilterPlugin.tsx:
##########
@@ -504,39 +547,57 @@ export default function PluginFilterSelect(props: PluginFilterSelectProps) {
               onChange={handleExclusionToggle}
             />
           )}
-          <Select
-            name={formData.nativeFilterId}
-            allowClear
-            allowNewOptions={!searchAllOptions && creatable !== false}
-            allowSelectAll={!searchAllOptions}
-            value={multiSelect ? filterState.value || [] : filterState.value}
-            disabled={isDisabled}
-            getPopupContainer={
-              showOverflow
-                ? () => (parentRef?.current as HTMLElement) || document.body
-                : (trigger: HTMLElement) =>
-                    (trigger?.parentNode as HTMLElement) || document.body
-            }
-            showSearch={showSearch}
-            mode={multiSelect ? 'multiple' : 'single'}
-            placeholder={placeholderText}
-            onClear={() => onSearch('')}
-            onSearch={onSearch}
-            onBlur={handleBlur}
-            onFocus={setFocusedFilter}
-            onMouseEnter={setHoveredFilter}
-            onMouseLeave={unsetHoveredFilter}
-            // @ts-expect-error
-            onChange={handleChange}
-            ref={inputRef}
-            loading={isRefreshing}
-            oneLine={filterBarOrientation === FilterBarOrientation.Horizontal}
-            invertSelection={inverseSelection && excludeFilterValues}
-            options={options}
-            sortComparator={sortComparator}
-            onOpenChange={setFilterActive}
-            className="select-container"
-          />
+          {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}
+            />

Review Comment:
   <!-- Bito Reply -->
   The change switches to a controlled Input component for like operators, using local state synced via useEffect, which fixes the inconsistency with the Select component and ensures the input updates with external changes. It also clears on clearAllTrigger.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org


Re: [PR] feat(native-filters): add configurable LIKE/ILIKE operators to Select filter [superset]

Posted by "codeant-ai-for-open-source[bot] (via GitHub)" <gi...@apache.org>.
codeant-ai-for-open-source[bot] commented on code in PR #38470:
URL: https://github.com/apache/superset/pull/38470#discussion_r2913327666


##########
superset-frontend/src/filters/components/Select/SelectFilterPlugin.tsx:
##########
@@ -504,39 +560,53 @@ export default function PluginFilterSelect(props: PluginFilterSelectProps) {
               onChange={handleExclusionToggle}
             />
           )}
-          <Select
-            name={formData.nativeFilterId}
-            allowClear
-            allowNewOptions={!searchAllOptions && creatable !== false}
-            allowSelectAll={!searchAllOptions}
-            value={multiSelect ? filterState.value || [] : filterState.value}
-            disabled={isDisabled}
-            getPopupContainer={
-              showOverflow
-                ? () => (parentRef?.current as HTMLElement) || document.body
-                : (trigger: HTMLElement) =>
-                    (trigger?.parentNode as HTMLElement) || document.body
-            }
-            showSearch={showSearch}
-            mode={multiSelect ? 'multiple' : 'single'}
-            placeholder={placeholderText}
-            onClear={() => onSearch('')}
-            onSearch={onSearch}
-            onBlur={handleBlur}
-            onFocus={setFocusedFilter}
-            onMouseEnter={setHoveredFilter}
-            onMouseLeave={unsetHoveredFilter}
-            // @ts-expect-error
-            onChange={handleChange}
-            ref={inputRef}
-            loading={isRefreshing}
-            oneLine={filterBarOrientation === FilterBarOrientation.Horizontal}
-            invertSelection={inverseSelection && excludeFilterValues}
-            options={options}
-            sortComparator={sortComparator}
-            onOpenChange={setFilterActive}
-            className="select-container"
-          />
+          {isLikeOperator ? (
+            <Input
+              allowClear
+              placeholder={likeInputPlaceholder}
+              value={likeInputValue}
+              onChange={handleLikeInputChange}
+              onFocus={setFocusedFilter}
+              onBlur={unsetFocusedFilter}
+              onMouseEnter={setHoveredFilter}
+              onMouseLeave={unsetHoveredFilter}
+              disabled={isDisabled}
+            />
+          ) : (

Review Comment:
   **Suggestion:** When the LIKE/ILIKE text input is rendered, the shared `inputRef` prop is no longer attached to any DOM element, so external code (e.g., filter bar keyboard navigation/focus management) that relies on `inputRef.current` to focus the filter will silently stop working for LIKE-based filters. [logic error]
   
   <details>
   <summary><b>Severity Level:</b> Major ⚠️</summary>
   
   ```mdx
   - ⚠️ Native Select filters with LIKE operators lose auto-focus behavior.
   - ⚠️ Keyboard navigation in `FilterValue.tsx` skips LIKE-based filters.
   - ⚠️ Accessibility degraded for text-match Select filters in filter bar.
   ```
   </details>
   
   ```suggestion
             {isLikeOperator ? (
               <Input
                 allowClear
                 placeholder={likeInputPlaceholder}
                 value={likeInputValue}
                 onChange={handleLikeInputChange}
                 onFocus={setFocusedFilter}
                 onBlur={unsetFocusedFilter}
                 onMouseEnter={setHoveredFilter}
                 onMouseLeave={unsetHoveredFilter}
                 disabled={isDisabled}
                 ref={inputRef}
               />
             ) : (
   ```
   <details>
   <summary><b>Steps of Reproduction ✅ </b></summary>
   
   ```mdx
   1. Open a dashboard using native filters; the filter bar renders `FilterValue` from
   `superset-frontend/src/dashboard/components/nativeFilters/FilterBar/FilterControls/FilterValue.tsx`,
   which creates `const inputRef = useRef<HTMLInputElement>(null);` (line ~141 from Grep) and
   passes it to the chart plugin as `inputRef={inputRef}` (line 409 in the same file per Grep
   output).
   
   2. Configure a "Value (Select)" native filter on a string column and, in the filter
   configuration modal, select a non-exact match type (e.g., "Contains text (ILIKE %x%)").
   This sets `operatorType` on the form data so that in `PluginFilterSelect`
   (`superset-frontend/src/filters/components/Select/SelectFilterPlugin.tsx` lines 165–168)
   `isLikeOperator` becomes `true` for this filter.
   
   3. When the dashboard renders, the Select filter for that column is implemented by
   `PluginFilterSelect`, which destructures `inputRef` from props (line 137) but, for the
   LIKE case, renders the `<Input>` block at lines 563–574 **without** attaching
   `ref={inputRef}`. In contrast, the non-LIKE branch attaches `ref={inputRef}` to the
   `<Select>` at line 600.
   
   4. Trigger focus behavior in the filter bar (for example, by selecting the filter so it
   becomes outlined/active). The effect in `FilterValue.tsx` around lines 290–295 calls
   `inputRef?.current?.focus();`, expecting the plugin to have wired `inputRef` to the actual
   input element. Because the LIKE `<Input>` never receives `ref={inputRef}`,
   `inputRef.current` remains `null`, the focus call becomes a no-op, and the LIKE-based
   Select filter does not receive programmatic focus (breaking keyboard
   navigation/auto-focus) while other Select filters continue to work.
   ```
   </details>
   <details>
   <summary><b>Prompt for AI Agent 🤖 </b></summary>
   
   ```mdx
   This is a comment left during a code review.
   
   **Path:** superset-frontend/src/filters/components/Select/SelectFilterPlugin.tsx
   **Line:** 563:575
   **Comment:**
   	*Logic Error: When the LIKE/ILIKE text input is rendered, the shared `inputRef` prop is no longer attached to any DOM element, so external code (e.g., filter bar keyboard navigation/focus management) that relies on `inputRef.current` to focus the filter will silently stop working for LIKE-based filters.
   
   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.
   ```
   </details>
   <a href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F38470&comment_hash=fc746871318fc6e94275bdd259be9f60e2cb58863720bd4ec783f61e8e5a9fdf&reaction=like'>👍</a> | <a href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F38470&comment_hash=fc746871318fc6e94275bdd259be9f60e2cb58863720bd4ec783f61e8e5a9fdf&reaction=dislike'>👎</a>



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org


Re: [PR] feat(native-filters): add configurable LIKE/ILIKE operators to Select filter [superset]

Posted by "bito-code-review[bot] (via GitHub)" <gi...@apache.org>.
bito-code-review[bot] commented on PR #38470:
URL: https://github.com/apache/superset/pull/38470#issuecomment-4033957772

   AI Code Review is in progress (usually takes 3 to 15 minutes unless it's a very large PR).
   
   <details>
   <summary>
   Bito Usage Guide
   </summary>
   
   **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 <a href="https://docs.bito.ai/bito-dev-agents/ai-code-review-agent/available-commands" target="_blank" rel="noopener noreferrer">documentation</a> for additional commands.
         
   **Configuration**
   
   This repository uses `Superset` You can customize the agent settings <a href="https://alpha.bito.ai/home/ai-agents/code-review-agent" target="_blank" rel="noopener noreferrer">here</a> or contact your Bito workspace admin at evan@preset.io.
         
   **Documentation & Help**
   - <a href="https://docs.bito.ai/bito-dev-agents/ai-code-review-agent/getting-started/install-run-using-bito-cloud/create-or-customize-an-agent-instance" target="_blank" rel="noopener noreferrer">Customize agent settings</a>
   - <a href="https://docs.bito.ai/bito-dev-agents/ai-code-review-agent/implementing-custom-code-review-rules" target="_blank" rel="noopener noreferrer">Review rules</a>
   - <a href="https://docs.bito.ai/bito-dev-agents/ai-code-review-agent" target="_blank" rel="noopener noreferrer">General documentation</a>
   - <a href="https://docs.bito.ai/bito-dev-agents/ai-code-review-agent/faqs" target="_blank" rel="noopener noreferrer">FAQ</a>
   
   </details>
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org


Re: [PR] feat(native-filters): add configurable LIKE/ILIKE operators to Select filter [superset]

Posted by "bito-code-review[bot] (via GitHub)" <gi...@apache.org>.
bito-code-review[bot] commented on PR #38470:
URL: https://github.com/apache/superset/pull/38470#issuecomment-4031571061

   AI Code Review is in progress (usually takes 3 to 15 minutes unless it's a very large PR).
   
   <details>
   <summary>
   Bito Usage Guide
   </summary>
   
   **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 <a href="https://docs.bito.ai/bito-dev-agents/ai-code-review-agent/available-commands" target="_blank" rel="noopener noreferrer">documentation</a> for additional commands.
         
   **Configuration**
   
   This repository uses `Superset` You can customize the agent settings <a href="https://alpha.bito.ai/home/ai-agents/code-review-agent" target="_blank" rel="noopener noreferrer">here</a> or contact your Bito workspace admin at evan@preset.io.
         
   **Documentation & Help**
   - <a href="https://docs.bito.ai/bito-dev-agents/ai-code-review-agent/getting-started/install-run-using-bito-cloud/create-or-customize-an-agent-instance" target="_blank" rel="noopener noreferrer">Customize agent settings</a>
   - <a href="https://docs.bito.ai/bito-dev-agents/ai-code-review-agent/implementing-custom-code-review-rules" target="_blank" rel="noopener noreferrer">Review rules</a>
   - <a href="https://docs.bito.ai/bito-dev-agents/ai-code-review-agent" target="_blank" rel="noopener noreferrer">General documentation</a>
   - <a href="https://docs.bito.ai/bito-dev-agents/ai-code-review-agent/faqs" target="_blank" rel="noopener noreferrer">FAQ</a>
   
   </details>
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org


Re: [PR] feat(native-filters): add configurable LIKE/ILIKE operators to Select filter [superset]

Posted by "richardfogaca (via GitHub)" <gi...@apache.org>.
richardfogaca merged PR #38470:
URL: https://github.com/apache/superset/pull/38470


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org


Re: [PR] feat(native-filters): add configurable LIKE/ILIKE operators to Select filter [superset]

Posted by "endimonan (via GitHub)" <gi...@apache.org>.
endimonan commented on code in PR #38470:
URL: https://github.com/apache/superset/pull/38470#discussion_r2913357811


##########
superset-frontend/src/filters/components/Select/SelectFilterPlugin.tsx:
##########
@@ -504,39 +560,53 @@ export default function PluginFilterSelect(props: PluginFilterSelectProps) {
               onChange={handleExclusionToggle}
             />
           )}
-          <Select
-            name={formData.nativeFilterId}
-            allowClear
-            allowNewOptions={!searchAllOptions && creatable !== false}
-            allowSelectAll={!searchAllOptions}
-            value={multiSelect ? filterState.value || [] : filterState.value}
-            disabled={isDisabled}
-            getPopupContainer={
-              showOverflow
-                ? () => (parentRef?.current as HTMLElement) || document.body
-                : (trigger: HTMLElement) =>
-                    (trigger?.parentNode as HTMLElement) || document.body
-            }
-            showSearch={showSearch}
-            mode={multiSelect ? 'multiple' : 'single'}
-            placeholder={placeholderText}
-            onClear={() => onSearch('')}
-            onSearch={onSearch}
-            onBlur={handleBlur}
-            onFocus={setFocusedFilter}
-            onMouseEnter={setHoveredFilter}
-            onMouseLeave={unsetHoveredFilter}
-            // @ts-expect-error
-            onChange={handleChange}
-            ref={inputRef}
-            loading={isRefreshing}
-            oneLine={filterBarOrientation === FilterBarOrientation.Horizontal}
-            invertSelection={inverseSelection && excludeFilterValues}
-            options={options}
-            sortComparator={sortComparator}
-            onOpenChange={setFilterActive}
-            className="select-container"
-          />
+          {isLikeOperator ? (
+            <Input
+              allowClear
+              placeholder={likeInputPlaceholder}
+              value={likeInputValue}
+              onChange={handleLikeInputChange}
+              onFocus={setFocusedFilter}
+              onBlur={unsetFocusedFilter}
+              onMouseEnter={setHoveredFilter}
+              onMouseLeave={unsetHoveredFilter}
+              disabled={isDisabled}
+            />
+          ) : (

Review Comment:
   Make sense, done! 



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org


Re: [PR] feat(native-filters): add configurable LIKE/ILIKE operators to Select filter [superset]

Posted by "codeant-ai-for-open-source[bot] (via GitHub)" <gi...@apache.org>.
codeant-ai-for-open-source[bot] commented on code in PR #38470:
URL: https://github.com/apache/superset/pull/38470#discussion_r2911575079


##########
superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FiltersConfigForm.tsx:
##########
@@ -1698,6 +1718,57 @@ const FiltersConfigForm = (
                               )}
                             </CollapsibleControl>
                           </FormItem>
+                          {!isChartCustomization && (
+                            <StyledRowFormItem
+                              expanded={expanded}
+                              name={[
+                                'filters',
+                                filterId,
+                                'controlValues',
+                                'operatorType',
+                              ]}
+                              initialValue={currentOperatorType}
+                              label={
+                                <>
+                                  <StyledLabel>{t('Match type')}</StyledLabel>
+                                  &nbsp;
+                                  <InfoTooltip
+                                    placement="top"
+                                    tooltip={t(
+                                      'Warning: ILIKE queries may be slow on large datasets as they cannot use indexes effectively.',
+                                    )}
+                                  />
+                                </>
+                              }
+                            >
+                              <Select
+                                ariaLabel={t('Match type')}
+                                options={[
+                                  {
+                                    value: SelectFilterOperatorType.Exact,
+                                    label: t('Exact match (IN)'),
+                                  },
+                                  {
+                                    value: SelectFilterOperatorType.Contains,
+                                    label: t('Contains text (ILIKE %x%)'),
+                                  },
+                                  {
+                                    value: SelectFilterOperatorType.StartsWith,
+                                    label: t('Starts with (ILIKE x%)'),
+                                  },
+                                  {
+                                    value: SelectFilterOperatorType.EndsWith,
+                                    label: t('Ends with (ILIKE %x)'),
+                                  },
+                                ]}
+                                onChange={value => {
+                                  onOperatorTypeChanged(
+                                    value as SelectFilterOperatorType,
+                                  );
+                                }}
+                              />
+                            </StyledRowFormItem>
+                          )}

Review Comment:
   **Suggestion:** The new "Match type" selector is rendered for all native filter types (time, range, group-by, etc.), but `operatorType` is only honored by the Select (Value) filter; this results in a configuration control that appears to affect other filter types but is silently ignored, which is misleading and can lead to incorrect assumptions about how those filters work. [logic error]
   
   <details>
   <summary><b>Severity Level:</b> Major ⚠️</summary>
   
   ```mdx
   - ⚠️ Non-select filters show unused "Match type" configuration.
   - ⚠️ Dashboard authors may assume ILIKE works on range filters.
   - ⚠️ Misleading UX in native filter settings modal for many filters.
   ```
   </details>
   
   ```suggestion
                             {!isChartCustomization && itemTypeField === 'filter_select' && (
                               <StyledRowFormItem
                                 expanded={expanded}
                                 name={[
                                   'filters',
                                   filterId,
                                   'controlValues',
                                   'operatorType',
                                 ]}
                                 initialValue={currentOperatorType}
                                 label={
                                   <>
                                     <StyledLabel>{t('Match type')}</StyledLabel>
                                     &nbsp;
                                     <InfoTooltip
                                       placement="top"
                                       tooltip={t(
                                         'Warning: ILIKE queries may be slow on large datasets as they cannot use indexes effectively.',
                                       )}
                                     />
                                   </>
                                 }
                               >
                                 <Select
                                   ariaLabel={t('Match type')}
                                   options={[
                                     {
                                       value: SelectFilterOperatorType.Exact,
                                       label: t('Exact match (IN)'),
                                     },
                                     {
                                       value: SelectFilterOperatorType.Contains,
                                       label: t('Contains text (ILIKE %x%)'),
                                     },
                                     {
                                       value: SelectFilterOperatorType.StartsWith,
                                       label: t('Starts with (ILIKE x%)'),
                                     },
                                     {
                                       value: SelectFilterOperatorType.EndsWith,
                                       label: t('Ends with (ILIKE %x)'),
                                     },
                                   ]}
                                   onChange={value => {
                                     onOperatorTypeChanged(
                                       value as SelectFilterOperatorType,
                                     );
                                   }}
                                 />
                               </StyledRowFormItem>
                             )}
   ```
   <details>
   <summary><b>Steps of Reproduction ✅ </b></summary>
   
   ```mdx
   1. Open any dashboard and edit an existing native filter in the Filters Config Modal
   (implemented in `FiltersConfigForm` at
   `superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FiltersConfigForm.tsx:274-810`).
   
   2. In the "Filter Type" dropdown rendered at `FiltersConfigForm.tsx:924-979`, select a
   non-select filter type such as the numerical range filter (`filter_range`), so
   `itemTypeField` (computed at `FiltersConfigForm.tsx:366-370`) becomes `'filter_range'`
   instead of `'filter_select'`.
   
   3. Switch to the "Filter Settings" panel for this filter; observe that the "Match type"
   form item is rendered unconditionally for all non-customization filters at
   `FiltersConfigForm.tsx:1721-1770` under the condition `!isChartCustomization` (no check on
   `itemTypeField`), so the Match type dropdown appears for the range filter.
   
   4. Change the "Match type" value and save the filter; this writes
   `controlValues.operatorType` via `onOperatorTypeChanged` at
   `FiltersConfigForm.tsx:635-645`, but at runtime `operatorType` is only consumed by the
   Select filter implementation (`SelectFilterPlugin.tsx:150-155, 223-229, 485-490` and
   `filters/utils.ts:50-88`), and a repo-wide search for `operatorType` shows no usage in
   other filter plugins, so for non-Select filters the Match type setting is silently ignored
   despite being configurable in the UI.
   ```
   </details>
   <details>
   <summary><b>Prompt for AI Agent 🤖 </b></summary>
   
   ```mdx
   This is a comment left during a code review.
   
   **Path:** superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FiltersConfigForm.tsx
   **Line:** 1721:1771
   **Comment:**
   	*Logic Error: The new "Match type" selector is rendered for all native filter types (time, range, group-by, etc.), but `operatorType` is only honored by the Select (Value) filter; this results in a configuration control that appears to affect other filter types but is silently ignored, which is misleading and can lead to incorrect assumptions about how those filters work.
   
   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.
   ```
   </details>
   <a href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F38470&comment_hash=3f8c35ac05920de768e5054ddf312aa564acccf32b2b656c18b12dd955fd5ce0&reaction=like'>👍</a> | <a href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F38470&comment_hash=3f8c35ac05920de768e5054ddf312aa564acccf32b2b656c18b12dd955fd5ce0&reaction=dislike'>👎</a>



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org


Re: [PR] feat(native-filters): add configurable LIKE/ILIKE operators to Select filter [superset]

Posted by "github-actions[bot] (via GitHub)" <gi...@apache.org>.
github-actions[bot] commented on PR #38470:
URL: https://github.com/apache/superset/pull/38470#issuecomment-4034225396

   🎪 [Showtime](https://github.com/mistercrunch/superset-showtime) deployed environment on [GHA](https://github.com/apache/superset/actions/runs/22921915405) for [a3e6a1e](https://github.com/apache/superset/commit/a3e6a1e)
   
   • **Environment:** http://52.11.104.75:8080 (admin/admin)
   • **Lifetime:** 48h auto-cleanup
   • **Updates:** New commits create fresh environments automatically


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org


Re: [PR] feat(native-filters): add configurable LIKE/ILIKE operators to Select filter [superset]

Posted by "bito-code-review[bot] (via GitHub)" <gi...@apache.org>.
bito-code-review[bot] commented on PR #38470:
URL: https://github.com/apache/superset/pull/38470#issuecomment-4013100470

   <!-- Bito Reply -->
   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.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org


Re: [PR] feat(native-filters): add configurable LIKE/ILIKE operators to Select filter [superset]

Posted by "bito-code-review[bot] (via GitHub)" <gi...@apache.org>.
bito-code-review[bot] commented on PR #38470:
URL: https://github.com/apache/superset/pull/38470#issuecomment-4011679661

   AI Code Review is in progress (usually takes 3 to 15 minutes unless it's a very large PR).
   
   <details>
   <summary>
   Bito Usage Guide
   </summary>
   
   **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 <a href="https://docs.bito.ai/bito-dev-agents/ai-code-review-agent/available-commands" target="_blank" rel="noopener noreferrer">documentation</a> for additional commands.
         
   **Configuration**
   
   This repository uses `Superset` You can customize the agent settings <a href="https://alpha.bito.ai/home/ai-agents/code-review-agent" target="_blank" rel="noopener noreferrer">here</a> or contact your Bito workspace admin at evan@preset.io.
         
   **Documentation & Help**
   - <a href="https://docs.bito.ai/bito-dev-agents/ai-code-review-agent/getting-started/install-run-using-bito-cloud/create-or-customize-an-agent-instance" target="_blank" rel="noopener noreferrer">Customize agent settings</a>
   - <a href="https://docs.bito.ai/bito-dev-agents/ai-code-review-agent/implementing-custom-code-review-rules" target="_blank" rel="noopener noreferrer">Review rules</a>
   - <a href="https://docs.bito.ai/bito-dev-agents/ai-code-review-agent" target="_blank" rel="noopener noreferrer">General documentation</a>
   - <a href="https://docs.bito.ai/bito-dev-agents/ai-code-review-agent/faqs" target="_blank" rel="noopener noreferrer">FAQ</a>
   
   </details>
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org


Re: [PR] feat(native-filters): add configurable LIKE/ILIKE operators to Select filter [superset]

Posted by "richardfogaca (via GitHub)" <gi...@apache.org>.
richardfogaca commented on code in PR #38470:
URL: https://github.com/apache/superset/pull/38470#discussion_r2897101074


##########
superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FiltersConfigForm.tsx:
##########
@@ -1693,6 +1713,57 @@ const FiltersConfigForm = (
                               )}
                             </CollapsibleControl>
                           </FormItem>
+                          {!isChartCustomization && (
+                            <StyledRowFormItem
+                              expanded={expanded}
+                              name={[
+                                'filters',
+                                filterId,
+                                'controlValues',
+                                'operatorType',
+                              ]}
+                              initialValue={currentOperatorType}
+                              label={
+                                <>
+                                  <StyledLabel>{t('Match type')}</StyledLabel>
+                                  &nbsp;
+                                  <InfoTooltip
+                                    placement="top"
+                                    tooltip={t(
+                                      'Warning: ILIKE queries may be slow on large datasets as they cannot use indexes effectively.',
+                                    )}
+                                  />
+                                </>
+                              }
+                            >
+                              <Select

Review Comment:
   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



##########
superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FiltersConfigForm.tsx:
##########
@@ -1693,6 +1713,57 @@ const FiltersConfigForm = (
                               )}
                             </CollapsibleControl>
                           </FormItem>
+                          {!isChartCustomization && (
+                            <StyledRowFormItem
+                              expanded={expanded}
+                              name={[
+                                'filters',
+                                filterId,
+                                'controlValues',
+                                'operatorType',
+                              ]}
+                              initialValue={currentOperatorType}
+                              label={
+                                <>
+                                  <StyledLabel>{t('Match type')}</StyledLabel>
+                                  &nbsp;
+                                  <InfoTooltip
+                                    placement="top"
+                                    tooltip={t(
+                                      'Warning: ILIKE queries may be slow on large datasets as they cannot use indexes effectively.',
+                                    )}
+                                  />
+                                </>
+                              }
+                            >
+                              <Select

Review Comment:
   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



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org


Re: [PR] feat(native-filters): add configurable LIKE/ILIKE operators to Select filter [superset]

Posted by "bito-code-review[bot] (via GitHub)" <gi...@apache.org>.
bito-code-review[bot] commented on code in PR #38470:
URL: https://github.com/apache/superset/pull/38470#discussion_r2897057127


##########
superset-frontend/src/filters/components/Select/SelectFilterPlugin.tsx:
##########
@@ -504,39 +547,57 @@ export default function PluginFilterSelect(props: PluginFilterSelectProps) {
               onChange={handleExclusionToggle}
             />
           )}
-          <Select
-            name={formData.nativeFilterId}
-            allowClear
-            allowNewOptions={!searchAllOptions && creatable !== false}
-            allowSelectAll={!searchAllOptions}
-            value={multiSelect ? filterState.value || [] : filterState.value}
-            disabled={isDisabled}
-            getPopupContainer={
-              showOverflow
-                ? () => (parentRef?.current as HTMLElement) || document.body
-                : (trigger: HTMLElement) =>
-                    (trigger?.parentNode as HTMLElement) || document.body
-            }
-            showSearch={showSearch}
-            mode={multiSelect ? 'multiple' : 'single'}
-            placeholder={placeholderText}
-            onClear={() => onSearch('')}
-            onSearch={onSearch}
-            onBlur={handleBlur}
-            onFocus={setFocusedFilter}
-            onMouseEnter={setHoveredFilter}
-            onMouseLeave={unsetHoveredFilter}
-            // @ts-expect-error
-            onChange={handleChange}
-            ref={inputRef}
-            loading={isRefreshing}
-            oneLine={filterBarOrientation === FilterBarOrientation.Horizontal}
-            invertSelection={inverseSelection && excludeFilterValues}
-            options={options}
-            sortComparator={sortComparator}
-            onOpenChange={setFilterActive}
-            className="select-container"
-          />
+          {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}
+            />

Review Comment:
   <!-- Bito Reply -->
   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.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org


Re: [PR] feat(native-filters): add configurable LIKE/ILIKE operators to Select filter [superset]

Posted by "richardfogaca (via GitHub)" <gi...@apache.org>.
richardfogaca commented on code in PR #38470:
URL: https://github.com/apache/superset/pull/38470#discussion_r2897078462


##########
superset-frontend/src/filters/components/Select/SelectFilterPlugin.tsx:
##########
@@ -504,39 +547,57 @@ export default function PluginFilterSelect(props: PluginFilterSelectProps) {
               onChange={handleExclusionToggle}
             />
           )}
-          <Select
-            name={formData.nativeFilterId}
-            allowClear
-            allowNewOptions={!searchAllOptions && creatable !== false}
-            allowSelectAll={!searchAllOptions}
-            value={multiSelect ? filterState.value || [] : filterState.value}
-            disabled={isDisabled}
-            getPopupContainer={
-              showOverflow
-                ? () => (parentRef?.current as HTMLElement) || document.body
-                : (trigger: HTMLElement) =>
-                    (trigger?.parentNode as HTMLElement) || document.body
-            }
-            showSearch={showSearch}
-            mode={multiSelect ? 'multiple' : 'single'}
-            placeholder={placeholderText}
-            onClear={() => onSearch('')}
-            onSearch={onSearch}
-            onBlur={handleBlur}
-            onFocus={setFocusedFilter}
-            onMouseEnter={setHoveredFilter}
-            onMouseLeave={unsetHoveredFilter}
-            // @ts-expect-error
-            onChange={handleChange}
-            ref={inputRef}
-            loading={isRefreshing}
-            oneLine={filterBarOrientation === FilterBarOrientation.Horizontal}
-            invertSelection={inverseSelection && excludeFilterValues}
-            options={options}
-            sortComparator={sortComparator}
-            onOpenChange={setFilterActive}
-            className="select-container"
-          />
+          {isLikeOperator ? (
+            <Input
+              allowClear
+              placeholder={likeInputPlaceholder}
+              defaultValue={

Review 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



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org


Re: [PR] feat(native-filters): add configurable LIKE/ILIKE operators to Select filter [superset]

Posted by "richardfogaca (via GitHub)" <gi...@apache.org>.
richardfogaca commented on PR #38470:
URL: https://github.com/apache/superset/pull/38470#issuecomment-4011533995

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


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org


Re: [PR] feat(native-filters): add configurable LIKE/ILIKE operators to Select filter [superset]

Posted by "codeant-ai-for-open-source[bot] (via GitHub)" <gi...@apache.org>.
codeant-ai-for-open-source[bot] commented on PR #38470:
URL: https://github.com/apache/superset/pull/38470#issuecomment-4038540203

   ## **Sequence Diagram**
   
   This PR lets filter creators choose a match type for Select filters and, when an ILIKE option is selected on a string column, switches the runtime UI to a debounced text input that sends ILIKE or NOT ILIKE queries with appropriate wildcards.
   
   ```mermaid
   sequenceDiagram
       participant User
       participant ConfigUI as Filter config UI
       participant Dashboard as Dashboard filter
       participant Backend as Query engine
   
       User->>ConfigUI: Configure Select filter
       ConfigUI->>ConfigUI: Choose Match type for column
       ConfigUI->>Dashboard: Save operatorType and reset default data mask
   
       User->>Dashboard: Use Select filter on dashboard
   
       alt Match type is Exact
           Dashboard->>Dashboard: Render dropdown and collect selected values
           Dashboard->>Backend: Send IN or NOT IN filter via extra form data
       else Match type is ILIKE and column is string
           Dashboard->>Dashboard: Render text input with operator-specific hint
           User->>Dashboard: Type search text
           Dashboard->>Backend: Send ILIKE or NOT ILIKE filter with wildcard
       end
   ```
   
   ---
   *Generated by [CodeAnt AI](https://codeant.ai)*
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org


Re: [PR] feat(native-filters): add configurable LIKE/ILIKE operators to Select filter [superset]

Posted by "endimonan (via GitHub)" <gi...@apache.org>.
endimonan commented on code in PR #38470:
URL: https://github.com/apache/superset/pull/38470#discussion_r2917731200


##########
superset-frontend/src/filters/components/Select/SelectFilterPlugin.test.tsx:
##########
@@ -1249,3 +1250,133 @@ test('resets dependent filter to first item when value does not exist in data',
     );
   });
 });
+
+test('renders text input instead of dropdown when operatorType is ILIKE contains', () => {
+  jest.useFakeTimers();
+  const setDataMaskMock = jest.fn();
+
+  render(
+    // @ts-expect-error

Review Comment:
   Added a buildSelectFilterProps helper with a typed SelectTestOverrides interface so the new tests use a single centralized cast instead of repeating `@ts-expect-error`.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org


Re: [PR] feat(native-filters): add configurable LIKE/ILIKE operators to Select filter [superset]

Posted by "codeant-ai-for-open-source[bot] (via GitHub)" <gi...@apache.org>.
codeant-ai-for-open-source[bot] commented on code in PR #38470:
URL: https://github.com/apache/superset/pull/38470#discussion_r2935869261


##########
superset-frontend/src/filters/components/Select/SelectFilterPlugin.test.tsx:
##########
@@ -1249,3 +1284,399 @@ test('resets dependent filter to first item when value does not exist in data',
     );
   });
 });
+
+test('renders text input instead of dropdown when operatorType is ILIKE contains', () => {
+  jest.useFakeTimers();
+  const setDataMaskMock = jest.fn();
+  const props = buildSelectFilterProps({
+    formData: { operatorType: SelectFilterOperatorType.Contains },
+    filterState: { value: undefined },
+    setDataMask: setDataMaskMock,
+  });
+
+  render(<SelectFilterPlugin {...props} />, {
+    useRedux: true,
+    initialState: {
+      nativeFilters: {
+        filters: { 'test-filter': { name: 'Test Filter' } },
+      },
+      dataMask: {
+        'test-filter': {
+          extraFormData: {},
+          filterState: { value: undefined },
+        },
+      },
+    },
+  });
+
+  expect(screen.queryByRole('combobox')).not.toBeInTheDocument();
+  expect(
+    screen.getByPlaceholderText('Type to search (contains)...'),
+  ).toBeInTheDocument();
+});
+
+test('renders text input with starts-with placeholder', () => {
+  jest.useFakeTimers();
+  const setDataMaskMock = jest.fn();
+  const props = buildSelectFilterProps({
+    formData: { operatorType: SelectFilterOperatorType.StartsWith },
+    filterState: { value: undefined },
+    setDataMask: setDataMaskMock,
+  });
+
+  render(<SelectFilterPlugin {...props} />, {
+    useRedux: true,
+    initialState: {
+      nativeFilters: {
+        filters: { 'test-filter': { name: 'Test Filter' } },
+      },
+      dataMask: {
+        'test-filter': {
+          extraFormData: {},
+          filterState: { value: undefined },
+        },
+      },
+    },
+  });
+
+  expect(
+    screen.getByPlaceholderText('Type to search (starts with)...'),
+  ).toBeInTheDocument();
+});
+
+test('typing in LIKE input calls setDataMask with ILIKE Contains payload', async () => {
+  jest.useFakeTimers();
+  const setDataMaskMock = jest.fn();
+  const props = buildSelectFilterProps({
+    formData: { operatorType: SelectFilterOperatorType.Contains },
+    filterState: { value: undefined },
+    setDataMask: setDataMaskMock,
+  });
+
+  render(<SelectFilterPlugin {...props} />, {
+    useRedux: true,
+    initialState: {
+      nativeFilters: {
+        filters: { 'test-filter': { name: 'Test Filter' } },
+      },
+      dataMask: {
+        'test-filter': {
+          extraFormData: {},
+          filterState: { value: undefined },
+        },
+      },
+    },
+  });
+
+  setDataMaskMock.mockClear();
+  const input = screen.getByPlaceholderText('Type to search (contains)...');
+  fireEvent.change(input, { target: { value: 'Jen' } });
+  act(() => {
+    jest.advanceTimersByTime(500);
+  });
+
+  expect(setDataMaskMock).toHaveBeenCalledWith(
+    expect.objectContaining({
+      extraFormData: {
+        filters: [
+          {
+            col: 'gender',
+            op: 'ILIKE',
+            val: '%Jen%',
+          },
+        ],
+      },
+    }),
+  );
+});
+
+test('typing in LIKE input with inverse selection calls setDataMask with NOT ILIKE payload', async () => {
+  jest.useFakeTimers();
+  const setDataMaskMock = jest.fn();
+  const props = buildSelectFilterProps({
+    formData: {
+      operatorType: SelectFilterOperatorType.Contains,
+      inverseSelection: true,
+    },
+    filterState: { value: undefined },
+    setDataMask: setDataMaskMock,
+  });
+
+  render(<SelectFilterPlugin {...props} />, {
+    useRedux: true,
+    initialState: {
+      nativeFilters: {
+        filters: { 'test-filter': { name: 'Test Filter' } },
+      },
+      dataMask: {
+        'test-filter': {
+          extraFormData: {},
+          filterState: { value: undefined },
+        },
+      },
+    },
+  });
+
+  setDataMaskMock.mockClear();
+  const input = screen.getByPlaceholderText('Type to search (contains)...');
+  fireEvent.change(input, { target: { value: 'Jen' } });
+  act(() => {
+    jest.advanceTimersByTime(500);
+  });
+
+  expect(setDataMaskMock).toHaveBeenCalledWith(
+    expect.objectContaining({
+      extraFormData: {
+        filters: [
+          {
+            col: 'gender',
+            op: 'NOT ILIKE',
+            val: '%Jen%',
+          },
+        ],
+      },
+    }),
+  );
+});
+
+test('clear-all resets LIKE input value and calls setDataMask with empty state', async () => {
+  jest.useFakeTimers();
+  const setDataMaskMock = jest.fn();
+  const likeProps = buildSelectFilterProps({
+    formData: { operatorType: SelectFilterOperatorType.Contains },
+    filterState: { value: ['Jen'] },
+    setDataMask: setDataMaskMock,
+  });
+
+  const reduxState = {
+    useRedux: true,
+    initialState: {
+      nativeFilters: {
+        filters: { 'test-filter': { name: 'Test Filter' } },
+      },
+      dataMask: {
+        'test-filter': {
+          extraFormData: {
+            filters: [{ col: 'gender', op: 'ILIKE', val: '%Jen%' }],
+          },
+          filterState: { value: ['Jen'] },
+        },
+      },
+    },
+  };
+
+  const { rerender } = render(
+    <SelectFilterPlugin {...likeProps} />,
+    reduxState,
+  );
+
+  const input = screen.getByPlaceholderText('Type to search (contains)...');
+  expect(input).toHaveValue('Jen');
+
+  setDataMaskMock.mockClear();
+
+  rerender(
+    <SelectFilterPlugin
+      {...likeProps}
+      clearAllTrigger={{ 'test-filter': true }}
+    />,
+  );
+
+  await waitFor(() => {
+    expect(input).toHaveValue('');
+  });
+
+  await waitFor(() => {
+    expect(setDataMaskMock).toHaveBeenCalledWith(
+      expect.objectContaining({
+        filterState: expect.objectContaining({
+          value: null,
+        }),
+      }),
+    );
+  });
+
+  act(() => {
+    jest.advanceTimersByTime(500);
+  });
+
+  expect(setDataMaskMock).not.toHaveBeenCalledWith(
+    expect.objectContaining({
+      extraFormData: {
+        filters: [
+          {
+            col: 'gender',
+            op: 'ILIKE',
+            val: '%Jen%',
+          },
+        ],
+      },
+    }),
+  );
+});
+
+test('pending LIKE debounce still applies after rerender recreates updateDataMask', async () => {
+  jest.useFakeTimers();
+  const setDataMaskMock = jest.fn();
+  const likeProps = buildSelectFilterProps({
+    formData: { operatorType: SelectFilterOperatorType.Contains },
+    filterState: { value: undefined },
+    setDataMask: setDataMaskMock,
+  });
+
+  const reduxState = {
+    useRedux: true,
+    initialState: {
+      nativeFilters: {
+        filters: { 'test-filter': { name: 'Test Filter' } },
+      },
+      dataMask: {
+        'test-filter': {
+          extraFormData: {},
+          filterState: { value: undefined },
+        },
+      },
+    },
+  };
+
+  const { rerender } = render(
+    <SelectFilterPlugin {...likeProps} />,
+    reduxState,
+  );
+
+  fireEvent.change(
+    screen.getByPlaceholderText('Type to search (contains)...'),
+    {
+      target: { value: 'Jen' },
+    },
+  );
+
+  setDataMaskMock.mockClear();
+
+  rerender(
+    <SelectFilterPlugin
+      {...buildSelectFilterProps({
+        formData: { operatorType: SelectFilterOperatorType.Contains },
+        filterState: { value: undefined, label: 'external change' },
+        setDataMask: setDataMaskMock,
+      })}
+    />,
+  );
+
+  act(() => {
+    jest.advanceTimersByTime(500);
+  });
+
+  expect(setDataMaskMock).toHaveBeenCalledWith(
+    expect.objectContaining({
+      extraFormData: {
+        filters: [
+          {
+            col: 'gender',
+            op: 'ILIKE',
+            val: '%Jen%',
+          },
+        ],
+      },
+    }),
+  );
+});
+
+test('pending LIKE debounce is canceled when operatorType switches back to Exact', async () => {
+  jest.useFakeTimers();
+  const setDataMaskMock = jest.fn();
+  const likeProps = buildSelectFilterProps({
+    formData: { operatorType: SelectFilterOperatorType.Contains },
+    filterState: { value: undefined },
+    setDataMask: setDataMaskMock,
+  });
+
+  const reduxState = {
+    useRedux: true,
+    initialState: {
+      nativeFilters: {
+        filters: { 'test-filter': { name: 'Test Filter' } },
+      },
+      dataMask: {
+        'test-filter': {
+          extraFormData: {},
+          filterState: { value: undefined },
+        },
+      },
+    },
+  };
+
+  const { rerender } = render(
+    <SelectFilterPlugin {...likeProps} />,
+    reduxState,
+  );
+
+  fireEvent.change(
+    screen.getByPlaceholderText('Type to search (contains)...'),
+    {
+      target: { value: 'Jen' },
+    },
+  );
+
+  setDataMaskMock.mockClear();
+
+  rerender(
+    <SelectFilterPlugin
+      {...buildSelectFilterProps({
+        formData: { operatorType: SelectFilterOperatorType.Exact },
+        filterState: { value: undefined },
+        setDataMask: setDataMaskMock,
+      })}
+    />,
+  );
+
+  act(() => {
+    jest.advanceTimersByTime(500);
+  });
+
+  expect(setDataMaskMock).not.toHaveBeenCalledWith(
+    expect.objectContaining({
+      extraFormData: {
+        filters: [
+          {
+            col: 'gender',
+            op: 'ILIKE',
+            val: '%Jen%',
+          },
+        ],
+      },
+    }),
+  );

Review Comment:
   **Suggestion:** This assertion only checks that an `ILIKE` payload was not emitted, but a stale debounced callback could still fire after switching to exact mode and emit an `IN` payload, making the test pass even when cancellation is broken. Assert that no call happens after the timer flush to actually verify debounce cancellation. [logic error]
   
   <details>
   <summary><b>Severity Level:</b> Major ⚠️</summary>
   
   ```mdx
   - ⚠️ Debounce-cancel regressions can bypass SelectFilterPlugin test coverage.
   - ❌ CI may miss stale filter updates after operator switch.
   ```
   </details>
   
   ```suggestion
     expect(setDataMaskMock).not.toHaveBeenCalled();
   ```
   <details>
   <summary><b>Steps of Reproduction ✅ </b></summary>
   
   ```mdx
   1. Run test `pending LIKE debounce is canceled when operatorType switches back to Exact`
   in `superset-frontend/src/filters/components/Select/SelectFilterPlugin.test.tsx:1585`; it
   types into LIKE input at lines 1614-1619, which triggers `handleLikeInputChange` in
   `SelectFilterPlugin.tsx:405-409`.
   
   2. That input schedules `debouncedLikeChange` (`SelectFilterPlugin.tsx:385-393`), and the
   callback uses `updateDataMaskRef.current([text])` (`SelectFilterPlugin.tsx:389`), not a
   fixed operator payload.
   
   3. After rerender to Exact mode (`SelectFilterPlugin.test.tsx:1623-1631`),
   `updateDataMaskRef` is refreshed in `SelectFilterPlugin.tsx:381-383`; if debounce
   cancellation regresses, timer flush at test lines 1633-1635 still executes pending
   callback.
   
   4. Callback then builds Exact-mode filter via `updateDataMask`
   (`SelectFilterPlugin.tsx:87-101`) and `getSelectExtraFormData`
   (`superset-frontend/src/filters/utils.ts:67-83`), producing `IN` instead of `ILIKE`.
   
   5. Current assertion (`SelectFilterPlugin.test.tsx:1637-1649`) only rejects an `ILIKE`
   payload, so a stale `IN` call still passes; replacing with `not.toHaveBeenCalled()`
   correctly validates cancellation.
   ```
   </details>
   <details>
   <summary><b>Prompt for AI Agent 🤖 </b></summary>
   
   ```mdx
   This is a comment left during a code review.
   
   **Path:** superset-frontend/src/filters/components/Select/SelectFilterPlugin.test.tsx
   **Line:** 1637:1649
   **Comment:**
   	*Logic Error: This assertion only checks that an `ILIKE` payload was not emitted, but a stale debounced callback could still fire after switching to exact mode and emit an `IN` payload, making the test pass even when cancellation is broken. Assert that no call happens after the timer flush to actually verify debounce cancellation.
   
   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.
   ```
   </details>
   <a href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F38470&comment_hash=9fe22f8648c0468f4bf74ccc40e374dac2131db4c78e73661b16d6053560191e&reaction=like'>👍</a> | <a href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F38470&comment_hash=9fe22f8648c0468f4bf74ccc40e374dac2131db4c78e73661b16d6053560191e&reaction=dislike'>👎</a>



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org


Re: [PR] feat(native-filters): add configurable LIKE/ILIKE operators to Select filter [superset]

Posted by "endimonan (via GitHub)" <gi...@apache.org>.
endimonan commented on code in PR #38470:
URL: https://github.com/apache/superset/pull/38470#discussion_r2935282423


##########
superset-frontend/src/filters/components/Select/SelectFilterPlugin.tsx:
##########
@@ -483,6 +506,47 @@ export default function PluginFilterSelect(props: PluginFilterSelectProps) {
     setExcludeFilterValues(value === 'true');
   };
 
+  const debouncedLikeChange = useMemo(
+    () =>
+      debounce((text: string) => {
+        if (text) {
+          updateDataMask([text]);
+        } else {
+          updateDataMask(null);
+        }
+      }, Constants.SLOW_DEBOUNCE),
+    [updateDataMask],
+  );
+
+  useEffect(() => {
+    if (!isLikeOperator || clearAllTrigger) {
+      debouncedLikeChange.cancel();
+    }
+  }, [clearAllTrigger, debouncedLikeChange, isLikeOperator]);
+
+  useEffect(() => () => debouncedLikeChange.cancel(), [debouncedLikeChange]);

Review Comment:
   It doesn't seem to me to be a real regression in this component... debouncedLikeChange is recreated only when updateDataMask changes and this depends on filter-state, not ordinary typing renders so normal text entry does not recreate the debounced callback.
   
   Canceling the previous debounced instance is intentional because it prevents stale LIKE updates from replaying after clearAll. This is what was fixed here.
   
   So I don't see a concrete reproduction where a user input is silently dropped during normal typing, while the proposed ref-based change would weaken the stale-work cancellation we want.
   
   
   



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org


Re: [PR] feat(native-filters): add configurable LIKE/ILIKE operators to Select filter [superset]

Posted by "endimonan (via GitHub)" <gi...@apache.org>.
endimonan commented on code in PR #38470:
URL: https://github.com/apache/superset/pull/38470#discussion_r2935296399


##########
superset-frontend/src/filters/components/Select/SelectFilterPlugin.tsx:
##########
@@ -483,6 +506,47 @@ export default function PluginFilterSelect(props: PluginFilterSelectProps) {
     setExcludeFilterValues(value === 'true');
   };
 
+  const debouncedLikeChange = useMemo(
+    () =>
+      debounce((text: string) => {
+        if (text) {
+          updateDataMask([text]);
+        } else {
+          updateDataMask(null);
+        }
+      }, Constants.SLOW_DEBOUNCE),
+    [updateDataMask],
+  );
+
+  useEffect(() => {
+    if (!isLikeOperator || clearAllTrigger) {
+      debouncedLikeChange.cancel();
+    }
+  }, [clearAllTrigger, debouncedLikeChange, isLikeOperator]);
+
+  useEffect(() => () => debouncedLikeChange.cancel(), [debouncedLikeChange]);

Review Comment:
   This is a valid edge case, but the suggested ref-based cleanup is not safe as written. It stops canceling previously created debounced instances when debouncedLikeChange is recreated, which can reintroduce stale updates.
   
   I fixed this by keeping a single stable debounced function and reading the latest updateDataMask from a ref. That preserves pending LIKE input across rerenders while still canceling correctly on clear-all, operator transitions, and unmount. I also added a test covering the rerender-before-debounce case.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org


Re: [PR] feat(native-filters): add configurable LIKE/ILIKE operators to Select filter [superset]

Posted by "endimonan (via GitHub)" <gi...@apache.org>.
endimonan commented on code in PR #38470:
URL: https://github.com/apache/superset/pull/38470#discussion_r2913192302


##########
superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FiltersConfigForm.tsx:
##########
@@ -1693,6 +1713,57 @@ const FiltersConfigForm = (
                               )}
                             </CollapsibleControl>
                           </FormItem>
+                          {!isChartCustomization && (
+                            <StyledRowFormItem
+                              expanded={expanded}
+                              name={[
+                                'filters',
+                                filterId,
+                                'controlValues',
+                                'operatorType',
+                              ]}
+                              initialValue={currentOperatorType}
+                              label={
+                                <>
+                                  <StyledLabel>{t('Match type')}</StyledLabel>
+                                  &nbsp;
+                                  <InfoTooltip
+                                    placement="top"
+                                    tooltip={t(
+                                      'Warning: ILIKE queries may be slow on large datasets as they cannot use indexes effectively.',
+                                    )}
+                                  />
+                                </>
+                              }
+                            >
+                              <Select

Review Comment:
   I considered that, but the two usages have different shapes (controlPanel uses [value, label] tuples, FiltersConfigForm uses {value, label} objects) and the config modal filters options conditionally based on column type. Extracting a shared constant for 4 static labels felt like it would add indirection without much gain. The enum itself is the source of truth for valid values, and both files are in the same feature scope so drift is unlikely. 
   
   Happy to reconsider if you feel strongly about it though.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org


Re: [PR] feat(native-filters): add configurable LIKE/ILIKE operators to Select filter [superset]

Posted by "endimonan (via GitHub)" <gi...@apache.org>.
endimonan commented on code in PR #38470:
URL: https://github.com/apache/superset/pull/38470#discussion_r2913198084


##########
superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FiltersConfigForm.tsx:
##########
@@ -624,6 +627,23 @@ const FiltersConfigForm = (
     forceUpdate();
   };
 
+  const currentOperatorType: SelectFilterOperatorType =
+    formFilter?.controlValues?.operatorType ??
+    filterToEdit?.controlValues?.operatorType ??
+    SelectFilterOperatorType.Exact;
+
+  const onOperatorTypeChanged = (value: SelectFilterOperatorType) => {

Review Comment:
   Good call, added an explicit `defaultDataMask: null` reset inside `onOperatorTypeChanged` so the filter value is cleared when switching between match types. It already cleared naturally on save/re-mount, but now it's explicit and consistent with how the rest of the form handles mode changes.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org


Re: [PR] feat(native-filters): add configurable LIKE/ILIKE operators to Select filter [superset]

Posted by "richardfogaca (via GitHub)" <gi...@apache.org>.
richardfogaca commented on PR #38470:
URL: https://github.com/apache/superset/pull/38470#issuecomment-4034764488

   @endimonan can we move the Match type field 1 level up, do we don't mix different field types? 
   <img width="586" height="366" alt="Screenshot 2026-03-10 at 19 06 18" src="https://github.com/user-attachments/assets/2893a0b0-4922-43cc-9bc0-6e6b33064cb1" />
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org


Re: [PR] feat(native-filters): add configurable LIKE/ILIKE operators to Select filter [superset]

Posted by "endimonan (via GitHub)" <gi...@apache.org>.
endimonan commented on PR #38470:
URL: https://github.com/apache/superset/pull/38470#issuecomment-4033137012

   
   Added three new tests: one that types into the LIKE input and asserts setDataMask gets the ILIKE payload with correct wildcards, another for NOT ILIKE with inverse selection, and a clear-all test that verifies the input resets and the dataMask clears properly.
   
   > * 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?
   
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org


Re: [PR] feat(native-filters): add configurable LIKE/ILIKE operators to Select filter [superset]

Posted by "github-actions[bot] (via GitHub)" <gi...@apache.org>.
github-actions[bot] commented on PR #38470:
URL: https://github.com/apache/superset/pull/38470#issuecomment-4034116390

   🎪 [Showtime](https://github.com/mistercrunch/superset-showtime) is building environment on [GHA](https://github.com/apache/superset/actions/runs/22921915405) for [a3e6a1e](https://github.com/apache/superset/commit/a3e6a1e)


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org


Re: [PR] feat(native-filters): add configurable LIKE/ILIKE operators to Select filter [superset]

Posted by "richardfogaca (via GitHub)" <gi...@apache.org>.
richardfogaca commented on code in PR #38470:
URL: https://github.com/apache/superset/pull/38470#discussion_r2897092187


##########
superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FiltersConfigForm.tsx:
##########
@@ -1693,6 +1713,57 @@ const FiltersConfigForm = (
                               )}
                             </CollapsibleControl>
                           </FormItem>
+                          {!isChartCustomization && (
+                            <StyledRowFormItem
+                              expanded={expanded}
+                              name={[
+                                'filters',
+                                filterId,
+                                'controlValues',
+                                'operatorType',
+                              ]}
+                              initialValue={currentOperatorType}
+                              label={
+                                <>
+                                  <StyledLabel>{t('Match type')}</StyledLabel>
+                                  &nbsp;
+                                  <InfoTooltip
+                                    placement="top"
+                                    tooltip={t(
+                                      'Warning: ILIKE queries may be slow on large datasets as they cannot use indexes effectively.',
+                                    )}
+                                  />
+                                </>
+                              }
+                            >
+                              <Select

Review 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



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org


Re: [PR] feat(native-filters): add configurable LIKE/ILIKE operators to Select filter [superset]

Posted by "richardfogaca (via GitHub)" <gi...@apache.org>.
richardfogaca commented on code in PR #38470:
URL: https://github.com/apache/superset/pull/38470#discussion_r2897074023


##########
superset-frontend/src/filters/components/Select/SelectFilterPlugin.tsx:
##########
@@ -142,8 +147,11 @@ export default function PluginFilterSelect(props: PluginFilterSelectProps) {
     inverseSelection,
     defaultToFirstItem,
     searchAllOptions,
+    operatorType = SelectFilterOperatorType.Exact,
   } = formData;
 
+  const isLikeOperator = operatorType !== SelectFilterOperatorType.Exact;

Review 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



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org


Re: [PR] feat(native-filters): add configurable LIKE/ILIKE operators to Select filter [superset]

Posted by "codeant-ai-for-open-source[bot] (via GitHub)" <gi...@apache.org>.
codeant-ai-for-open-source[bot] commented on code in PR #38470:
URL: https://github.com/apache/superset/pull/38470#discussion_r2936446667


##########
superset-frontend/src/filters/components/Select/SelectFilterPlugin.test.tsx:
##########
@@ -1249,3 +1284,387 @@ test('resets dependent filter to first item when value does not exist in data',
     );
   });
 });
+
+test('renders text input instead of dropdown when operatorType is ILIKE contains', () => {
+  jest.useFakeTimers();
+  const setDataMaskMock = jest.fn();
+  const props = buildSelectFilterProps({
+    formData: { operatorType: SelectFilterOperatorType.Contains },
+    filterState: { value: undefined },
+    setDataMask: setDataMaskMock,
+  });
+
+  render(<SelectFilterPlugin {...props} />, {
+    useRedux: true,
+    initialState: {
+      nativeFilters: {
+        filters: { 'test-filter': { name: 'Test Filter' } },
+      },
+      dataMask: {
+        'test-filter': {
+          extraFormData: {},
+          filterState: { value: undefined },
+        },
+      },
+    },
+  });
+
+  expect(screen.queryByRole('combobox')).not.toBeInTheDocument();
+  expect(
+    screen.getByPlaceholderText('Type to search (contains)...'),
+  ).toBeInTheDocument();
+});
+
+test('renders text input with starts-with placeholder', () => {
+  jest.useFakeTimers();
+  const setDataMaskMock = jest.fn();
+  const props = buildSelectFilterProps({
+    formData: { operatorType: SelectFilterOperatorType.StartsWith },
+    filterState: { value: undefined },
+    setDataMask: setDataMaskMock,
+  });
+
+  render(<SelectFilterPlugin {...props} />, {
+    useRedux: true,
+    initialState: {
+      nativeFilters: {
+        filters: { 'test-filter': { name: 'Test Filter' } },
+      },
+      dataMask: {
+        'test-filter': {
+          extraFormData: {},
+          filterState: { value: undefined },
+        },
+      },
+    },
+  });
+
+  expect(
+    screen.getByPlaceholderText('Type to search (starts with)...'),
+  ).toBeInTheDocument();
+});
+
+test('typing in LIKE input calls setDataMask with ILIKE Contains payload', async () => {
+  jest.useFakeTimers();
+  const setDataMaskMock = jest.fn();
+  const props = buildSelectFilterProps({
+    formData: { operatorType: SelectFilterOperatorType.Contains },
+    filterState: { value: undefined },
+    setDataMask: setDataMaskMock,
+  });
+
+  render(<SelectFilterPlugin {...props} />, {
+    useRedux: true,
+    initialState: {
+      nativeFilters: {
+        filters: { 'test-filter': { name: 'Test Filter' } },
+      },
+      dataMask: {
+        'test-filter': {
+          extraFormData: {},
+          filterState: { value: undefined },
+        },
+      },
+    },
+  });
+
+  setDataMaskMock.mockClear();
+  const input = screen.getByPlaceholderText('Type to search (contains)...');
+  fireEvent.change(input, { target: { value: 'Jen' } });
+  act(() => {
+    jest.advanceTimersByTime(500);
+  });
+
+  expect(setDataMaskMock).toHaveBeenCalledWith(
+    expect.objectContaining({
+      extraFormData: {
+        filters: [
+          {
+            col: 'gender',
+            op: 'ILIKE',
+            val: '%Jen%',
+          },
+        ],
+      },
+    }),
+  );
+});
+
+test('typing in LIKE input with inverse selection calls setDataMask with NOT ILIKE payload', async () => {
+  jest.useFakeTimers();
+  const setDataMaskMock = jest.fn();
+  const props = buildSelectFilterProps({
+    formData: {
+      operatorType: SelectFilterOperatorType.Contains,
+      inverseSelection: true,
+    },
+    filterState: { value: undefined },
+    setDataMask: setDataMaskMock,
+  });
+
+  render(<SelectFilterPlugin {...props} />, {
+    useRedux: true,
+    initialState: {
+      nativeFilters: {
+        filters: { 'test-filter': { name: 'Test Filter' } },
+      },
+      dataMask: {
+        'test-filter': {
+          extraFormData: {},
+          filterState: { value: undefined },
+        },
+      },
+    },
+  });
+
+  setDataMaskMock.mockClear();
+  const input = screen.getByPlaceholderText('Type to search (contains)...');
+  fireEvent.change(input, { target: { value: 'Jen' } });
+  act(() => {
+    jest.advanceTimersByTime(500);
+  });
+
+  expect(setDataMaskMock).toHaveBeenCalledWith(
+    expect.objectContaining({
+      extraFormData: {
+        filters: [
+          {
+            col: 'gender',
+            op: 'NOT ILIKE',
+            val: '%Jen%',
+          },
+        ],
+      },
+    }),
+  );
+});
+
+test('clear-all resets LIKE input value and calls setDataMask with empty state', async () => {
+  jest.useFakeTimers();
+  const setDataMaskMock = jest.fn();
+  const likeProps = buildSelectFilterProps({
+    formData: { operatorType: SelectFilterOperatorType.Contains },
+    filterState: { value: ['Jen'] },
+    setDataMask: setDataMaskMock,
+  });
+
+  const reduxState = {
+    useRedux: true,
+    initialState: {
+      nativeFilters: {
+        filters: { 'test-filter': { name: 'Test Filter' } },
+      },
+      dataMask: {
+        'test-filter': {
+          extraFormData: {
+            filters: [{ col: 'gender', op: 'ILIKE', val: '%Jen%' }],
+          },
+          filterState: { value: ['Jen'] },
+        },
+      },
+    },
+  };
+
+  const { rerender } = render(
+    <SelectFilterPlugin {...likeProps} />,
+    reduxState,
+  );
+
+  const input = screen.getByPlaceholderText('Type to search (contains)...');
+  expect(input).toHaveValue('Jen');
+
+  setDataMaskMock.mockClear();
+
+  rerender(
+    <SelectFilterPlugin
+      {...likeProps}
+      clearAllTrigger={{ 'test-filter': true }}
+    />,
+  );
+
+  await waitFor(() => {
+    expect(input).toHaveValue('');
+  });
+
+  await waitFor(() => {
+    expect(setDataMaskMock).toHaveBeenCalledWith(
+      expect.objectContaining({
+        filterState: expect.objectContaining({
+          value: null,
+        }),
+      }),
+    );
+  });
+
+  act(() => {
+    jest.advanceTimersByTime(500);
+  });
+
+  expect(setDataMaskMock).not.toHaveBeenCalled();

Review Comment:
   **Suggestion:** This assertion is logically impossible after the preceding `waitFor` already verified that `setDataMaskMock` was called, so the test will fail even when behavior is correct. Capture the call count before flushing timers and assert it does not increase, which validates that no extra debounced call fires. [logic error]
   
   <details>
   <summary><b>Severity Level:</b> Critical 🚨</summary>
   
   ```mdx
   - ⚠️ Jest suite fails for SelectFilterPlugin clear-all scenario.
   - ❌ Frontend CI blocked by deterministic failing assertion.
   ```
   </details>
   
   ```suggestion
     const callsBeforeDebounceFlush = setDataMaskMock.mock.calls.length;
   
     act(() => {
       jest.advanceTimersByTime(500);
     });
   
     expect(setDataMaskMock).toHaveBeenCalledTimes(callsBeforeDebounceFlush);
   ```
   <details>
   <summary><b>Steps of Reproduction ✅ </b></summary>
   
   ```mdx
   1. Run the focused Jest test in
   `superset-frontend/src/filters/components/Select/SelectFilterPlugin.test.tsx` (test name:
   `clear-all resets LIKE input value and calls setDataMask with empty state`).
   
   2. In that test, `setDataMaskMock.mockClear()` is called, then `rerender(...
   clearAllTrigger={{ 'test-filter': true }})` triggers the clear-all flow
   (`SelectFilterPlugin.test.tsx:1476-1487` in final file state).
   
   3. The test explicitly waits for `setDataMaskMock` to be called with `filterState.value:
   null` via `await waitFor(...toHaveBeenCalledWith...)`
   (`SelectFilterPlugin.test.tsx:1490-1497`), proving at least one call already happened.
   
   4. Immediately after timer flush (`SelectFilterPlugin.test.tsx:1499-1501`), the assertion
   `expect(setDataMaskMock).not.toHaveBeenCalled()` (`SelectFilterPlugin.test.tsx:1503`)
   fails deterministically because prior steps already required a call.
   ```
   </details>
   <details>
   <summary><b>Prompt for AI Agent 🤖 </b></summary>
   
   ```mdx
   This is a comment left during a code review.
   
   **Path:** superset-frontend/src/filters/components/Select/SelectFilterPlugin.test.tsx
   **Line:** 1499:1503
   **Comment:**
   	*Logic Error: This assertion is logically impossible after the preceding `waitFor` already verified that `setDataMaskMock` was called, so the test will fail even when behavior is correct. Capture the call count before flushing timers and assert it does not increase, which validates that no extra debounced call fires.
   
   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.
   ```
   </details>
   <a href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F38470&comment_hash=3147852f6095d33fc7bfd1cfb2c5c1682b5ad00853dfea7eee07e6424743d195&reaction=like'>👍</a> | <a href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F38470&comment_hash=3147852f6095d33fc7bfd1cfb2c5c1682b5ad00853dfea7eee07e6424743d195&reaction=dislike'>👎</a>



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org


Re: [PR] feat(native-filters): add configurable LIKE/ILIKE operators to Select filter [superset]

Posted by "codeant-ai-for-open-source[bot] (via GitHub)" <gi...@apache.org>.
codeant-ai-for-open-source[bot] commented on code in PR #38470:
URL: https://github.com/apache/superset/pull/38470#discussion_r2935255026


##########
superset-frontend/src/filters/components/Select/SelectFilterPlugin.tsx:
##########
@@ -483,6 +506,47 @@ export default function PluginFilterSelect(props: PluginFilterSelectProps) {
     setExcludeFilterValues(value === 'true');
   };
 
+  const debouncedLikeChange = useMemo(
+    () =>
+      debounce((text: string) => {
+        if (text) {
+          updateDataMask([text]);
+        } else {
+          updateDataMask(null);
+        }
+      }, Constants.SLOW_DEBOUNCE),
+    [updateDataMask],
+  );
+
+  useEffect(() => {
+    if (!isLikeOperator || clearAllTrigger) {
+      debouncedLikeChange.cancel();
+    }
+  }, [clearAllTrigger, debouncedLikeChange, isLikeOperator]);
+
+  useEffect(() => () => debouncedLikeChange.cancel(), [debouncedLikeChange]);

Review Comment:
   **Suggestion:** The cleanup effect tied to `debouncedLikeChange` cancels pending debounced updates every time the debounced function is recreated, which can happen on normal prop/state changes. This can silently drop the latest typed LIKE input (input shows text but filter is not applied). Track the latest debounced function in a ref and only cancel on operator/clear-all transitions and unmount. [race condition]
   
   <details>
   <summary><b>Severity Level:</b> Major ⚠️</summary>
   
   ```mdx
   - ⚠️ LIKE input text may not reach filter state.
   - ❌ Dashboard filtering can show stale unfiltered results.
   - ⚠️ UI text and applied query become inconsistent.
   ```
   </details>
   
   ```suggestion
     const debouncedLikeChangeRef = useRef(debouncedLikeChange);
   
     useEffect(() => {
       debouncedLikeChangeRef.current = debouncedLikeChange;
     }, [debouncedLikeChange]);
   
     useEffect(() => {
       if (!isLikeOperator || clearAllTrigger) {
         debouncedLikeChangeRef.current.cancel();
       }
     }, [clearAllTrigger, isLikeOperator]);
   
     useEffect(
       () => () => {
         debouncedLikeChangeRef.current.cancel();
       },
       [],
     );
   ```
   <details>
   <summary><b>Steps of Reproduction ✅ </b></summary>
   
   ```mdx
   1. Open a dashboard Filter Bar where Select filter renders through
   `FilterControl.tsx:133-146` → `FilterValue.tsx:153-170` (`<SuperChart
   chartType={filterType}>`) into `SelectFilterPlugin.tsx`.
   
   2. Configure that Select filter with LIKE mode (`isLikeOperator` true) and inverse
   selection enabled; UI shows both text input (`SelectFilterPlugin.tsx:575-576`) and exclude
   dropdown (`SelectFilterPlugin.tsx:560-563`).
   
   3. Type text in the LIKE input; `handleLikeInputChange` queues a debounced update
   (`SelectFilterPlugin.tsx:529-533`, `509-517`) rather than immediate `updateDataMask`.
   
   4. Before debounce timeout, toggle the exclude dropdown (`handleExclusionToggle` at
   `SelectFilterPlugin.tsx:505-507`), which changes `excludeFilterValues`; `updateDataMask`
   depends on that (`SelectFilterPlugin.tsx:255`) so `debouncedLikeChange` is recreated.
   
   5. On recreation, cleanup effect `useEffect(() => () => debouncedLikeChange.cancel(),
   [debouncedLikeChange])` (`SelectFilterPlugin.tsx:527`) cancels the pending typed update;
   input still displays text (`likeInputValue`) but no filter mask update is emitted
   (`setDataMask` only runs from dataMask changes at `SelectFilterPlugin.tsx:460`).
   ```
   </details>
   <details>
   <summary><b>Prompt for AI Agent 🤖 </b></summary>
   
   ```mdx
   This is a comment left during a code review.
   
   **Path:** superset-frontend/src/filters/components/Select/SelectFilterPlugin.tsx
   **Line:** 521:527
   **Comment:**
   	*Race Condition: The cleanup effect tied to `debouncedLikeChange` cancels pending debounced updates every time the debounced function is recreated, which can happen on normal prop/state changes. This can silently drop the latest typed LIKE input (input shows text but filter is not applied). Track the latest debounced function in a ref and only cancel on operator/clear-all transitions and unmount.
   
   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.
   ```
   </details>
   <a href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F38470&comment_hash=f3f4ea07fdffc6c3b20d320a127be802d0ba05bc807228491e391d375b4c6107&reaction=like'>👍</a> | <a href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F38470&comment_hash=f3f4ea07fdffc6c3b20d320a127be802d0ba05bc807228491e391d375b4c6107&reaction=dislike'>👎</a>



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org


Re: [PR] feat(native-filters): add configurable LIKE/ILIKE operators to Select filter [superset]

Posted by "endimonan (via GitHub)" <gi...@apache.org>.
endimonan commented on code in PR #38470:
URL: https://github.com/apache/superset/pull/38470#discussion_r2935282423


##########
superset-frontend/src/filters/components/Select/SelectFilterPlugin.tsx:
##########
@@ -483,6 +506,47 @@ export default function PluginFilterSelect(props: PluginFilterSelectProps) {
     setExcludeFilterValues(value === 'true');
   };
 
+  const debouncedLikeChange = useMemo(
+    () =>
+      debounce((text: string) => {
+        if (text) {
+          updateDataMask([text]);
+        } else {
+          updateDataMask(null);
+        }
+      }, Constants.SLOW_DEBOUNCE),
+    [updateDataMask],
+  );
+
+  useEffect(() => {
+    if (!isLikeOperator || clearAllTrigger) {
+      debouncedLikeChange.cancel();
+    }
+  }, [clearAllTrigger, debouncedLikeChange, isLikeOperator]);
+
+  useEffect(() => () => debouncedLikeChange.cancel(), [debouncedLikeChange]);

Review Comment:
   It doesn't seem to me to be a real regression in this component... debouncedLikeChange is recreated only when updateDataMask changes and this depends on filter-state, not ordinary typing renders so normal text entry does not recreate the debounced callback.
   
   Canceling the previous debounced instance is intentional because it prevents stale LIKE updates from replaying after clearAll. This is what was fixed here.
   
   So I don't see a concrete reproduction where a user input is silently dropped during normal typing, while the proposed ref-based change would weaken the stale-work cancellation we want.
   
   
   



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org


Re: [PR] feat(native-filters): add configurable LIKE/ILIKE operators to Select filter [superset]

Posted by "bito-code-review[bot] (via GitHub)" <gi...@apache.org>.
bito-code-review[bot] commented on PR #38470:
URL: https://github.com/apache/superset/pull/38470#issuecomment-4071549648

   **Bito Automatic Review Skipped – PR Already Merged**<br/><br/>Bito scheduled an automatic review for this pull request, but the review was skipped because this PR was merged before the review could be run.<br/>No action is needed if you didn't intend to review it. To get a review, you can type `/review` in a comment and save it


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org