Skip to content

Pattern Matching

Use ~ to match a value against a regular expression, and !~ to negate the match:

message ~ "error.*timeout"
path !~ "^/health"
OperatorMeaning
~Value matches regex pattern
!~Value does not match regex pattern

The regex syntax depends on the target backend:

  • ClickHouse — uses match() function (RE2 syntax)

  • PostgreSQL — uses ~ and !~ operators (POSIX regex)

  • StarRocks — uses regexp function

  • In-memory matcher — uses the host language’s regex engine:

    • Go: stdlib regexp (RE2-based, always available)
    • Python: google-re2 via the optional [re2] extra (required for ~ and LIKE operators; otherwise raises ERR_RE2_MISSING)
    • JavaScript: native RegExp (PCRE-ish — supports backreferences and lookahead, but not RE2-safe against catastrophic backtracking)

    Portable patterns should avoid backreferences and lookahead. A pattern using either is accepted in JS but rejected in Python/Go.

Quote the pattern when it contains spaces or special characters:

message ~ "connection (refused|reset)"
host ~ "^prod-[0-9]+"

You can modify regex behavior using inline flags at the start of your pattern with the (?...) syntax. FlyQL supports three flags that work across all backends:

Makes the pattern match regardless of letter case:

message ~ "(?i)error"
level ~ "(?i)^(warn|error|fatal)$"

(?i)error matches “Error”, “ERROR”, “error”, etc.

Changes ^ and $ to match the start and end of each line instead of the entire string:

log ~ "(?m)^ERROR"

Without (?m), ^ERROR only matches if the entire string starts with “ERROR”. With (?m), it also matches “INFO first\nERROR second” because “ERROR” appears at the start of a line.

Makes . match any character including newlines. By default, . does not match \n:

log ~ "(?s)start.*end"

Without (?s), start.*end does not match “start\nend” because . won’t cross the newline. With (?s), it matches.

Flags can be combined in a single group:

log ~ "(?im)^ERROR"
log ~ "(?ims)^START.*END$"

All three flags work across every FlyQL backend:

Backend(?i)(?m)(?s)
ClickHouseYesYesYes
PostgreSQLYesYesYes
StarRocksYesYesYes
Go matcherYesYesYes
Python matcherYesYesYes
JavaScript matcherYesYesYes

Combine case-insensitive matching with negation to exclude patterns regardless of case:

message ~ "(?i)error" and message !~ "(?i)warning"

Use like and ilike for SQL-style pattern matching with wildcards:

host like 'prod%'
service like 'api-%'
message ilike '%Error%'
OperatorMeaning
likeValue matches pattern (case-sensitive)
not likeValue does not match pattern
ilikeValue matches pattern (case-insensitive)
not ilikeValue does not match pattern (case-insensitive)

Two wildcard characters are available in like / ilike patterns:

WildcardMeaningExampleMatches
%Any sequence of characters (including empty)host like 'prod%'prod, prod-1, production
_Exactly one charactercode like 'E__'E01, Exx, but not E1 or Error

Wildcards can appear anywhere in the pattern — start, middle, end, or combined:

message like '%timeout%'
host like 'web-_-prod'
path like '/api/%/status'

To match a literal % or _, escape it with a backslash:

value like '100\%'
col like 'foo\_bar'

100\% matches the literal string “100%”, not “100” followed by anything.

Use ilike for case-insensitive pattern matching:

message ilike '%error%'
host not ilike 'TEST%'
Use caseSyntaxExample
Prefix matchkey like 'prefix%'host like 'prod%'
Containskey like '%word%'msg like '%error%'
Complex patternkey ~ "pattern"host ~ "^prod-[0-9]+"

Use like for simple wildcard matching. Use regex (~) when you need character classes, alternation, or other advanced patterns.

All SQL backends (ClickHouse, PostgreSQL, StarRocks) emit native LIKE / ILIKE / NOT LIKE / NOT ILIKE SQL operators. The in-memory matcher converts the pattern to a regex internally.

message ~ "error|fail"
path ~ "^/api/v2"
path !~ "^/health"
host like 'prod%'
host like 'prod%' and message ~ "timeout.*" and path !~ "^/health"