Skip to content

fix(adhoc): map regex operators to REGEXP instead of ILIKE#1794

Open
adamyeats wants to merge 4 commits intomainfrom
fix/adhoc-regex-operator-1443
Open

fix(adhoc): map regex operators to REGEXP instead of ILIKE#1794
adamyeats wants to merge 4 commits intomainfrom
fix/adhoc-regex-operator-1443

Conversation

@adamyeats
Copy link
Copy Markdown
Contributor

@adamyeats adamyeats commented Apr 19, 2026

Fixes #1443

Summary

  • Grafana's ad-hoc filter operators =~ ("Matches regex") and !~ ("Does not match regex") were being translated to ILIKE / NOT ILIKE in the additional_table_filters setting. That is semantically wrong (ILIKE is a LIKE pattern, not a regex) and, per the reporter, prevents primary-key / skip-index pruning on indexed columns, producing very slow queries over large tables.
  • Map =~ / !~ to ClickHouse's REGEXP / NOT REGEXP (RE2-backed, alias for match()). Anchored patterns can still benefit from prefix pruning, and the semantics now match the operator label shown in the UI.
  • Only src/data/adHocFilter.ts changes runtime behaviour. The Query Builder's ILIKE / NOT ILIKE options in FilterEditor.tsx are untouched — they're an explicit user choice and unrelated to the regex operators.

Grafana's ad-hoc filter operators `=~` ("Matches regex") and `!~`
("Does not match regex") were translated to `ILIKE` and `NOT ILIKE` in
the `additional_table_filters` setting. ILIKE is a LIKE pattern, not a
regex, so the operator names and semantics did not match, and — more
importantly — ILIKE prevents primary-key and skip-index pruning on
indexed columns, producing very slow queries over large tables.

Map `=~` / `!~` to ClickHouse's `REGEXP` / `NOT REGEXP` (RE2-backed,
alias for `match()`). Anchored patterns can still benefit from prefix
pruning, and the semantics now match the operator label shown in the
Grafana UI.

Adds unit tests for the new mapping plus an e2e regression guard that
runs the full `additional_table_filters` SQL shape against a real
ClickHouse fixture, including a pattern (`^(info|warn)$`) that would
match zero rows under ILIKE — so any future regression back to LIKE
semantics fails loudly.

Fixes #1443
The previous SETTINGS additional_table_filters={...} SQL shape was
mangled by Monaco editor's brace-auto-close when typed through
page.keyboard.type(), so the filter never reached ClickHouse and
queries returned unfiltered rows.

Unit tests in src/data/adHocFilter.test.ts cover the exact SETTINGS
shape AdHocFilter.apply() produces; E2E tests now cover what unit
tests cannot — that ClickHouse actually accepts REGEXP / NOT REGEXP
as a filter operator.
Two defences against Monaco swallowing/mangling the query:

1. Press Escape after typing the SQL to dismiss any suggestion popup
   that may have captured focus mid-stream (common after keywords like
   `NOT `).

2. Rewrite the NOT REGEXP predicate as `NOT (col REGEXP '...')` so
   the `NOT` keyword is not immediately adjacent to `REGEXP`, which
   was triggering keyword autocomplete on the next token.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Adhoc filter for regex uses ILIKE by default

1 participant