Support case-insensitive inline / scoped flags (?i) / (?i:…) in regex patterns - #15484
Open
igorpeshansky wants to merge 4 commits into
Open
Support case-insensitive inline / scoped flags (?i) / (?i:…) in regex patterns#15484igorpeshansky wants to merge 4 commits into
igorpeshansky wants to merge 4 commits into
Conversation
Consolidate the per-type unsupported-group handling in CudfRegexTranspiler so an unexpected group type falls back to the CPU rather than crashing the query. Also cover the empty lookaround forms, which Java accepts. Signed-off-by: Igor Peshansky <ipeshansky@nvidia.com>
Collaborator
Author
|
build |
Contributor
Greptile SummaryThe PR extends the regex parser and transpiler to support Java case-insensitive inline and scoped flags while retaining CPU fallback for unsupported flag combinations.
Confidence Score: 5/5The PR appears safe to merge. No blocking failure remains. Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[Java/Spark regex pattern] --> B[Validate with Java Pattern]
B --> C[Parse regex AST]
C --> D{Supported inline flags and scope?}
D -->|No| E[CPU fallback]
D -->|Yes| F[Track case-insensitive state]
F --> G[Fold ASCII literals and character classes]
G --> H[Emit cuDF-compatible regex]
H --> I[GPU execution]
Reviews (3): Last reviewed commit: "Document unsupported group and inline-fl..." | Re-trigger Greptile |
Parse Java inline flag groups into the regex AST, both the bare directive form and the scoped (non-capturing) form, which were previously misparsed or rejected. Restructure parseGroup so the two are distinguished cleanly. Only parsing is added here; the transpiler still falls back on any inline flag. Signed-off-by: Igor Peshansky <ipeshansky@nvidia.com>
igorpeshansky
force-pushed
the
regex-inline-flags
branch
from
August 1, 2026 22:55
93a9b51 to
2b2f9e6
Compare
Collaborator
Author
|
build |
Case-insensitive runs are folded to match either case; unsafe folds and any other positive flags fall back to the CPU; negated non-i flags are no-ops, since they're off by default. Inline flags are zero-width, so they are skipped by the anchor and empty-repetition guards. A scoped-flags group is treated like a non-capturing one so it is not needlessly rejected after $ or when repeated. The rlike fast path is taught to see through case-sensitive scoped-flag groups so they keep their contains/prefix optimization. Signed-off-by: Igor Peshansky <ipeshansky@nvidia.com>
Signed-off-by: Igor Peshansky <ipeshansky@nvidia.com>
igorpeshansky
force-pushed
the
regex-inline-flags
branch
from
August 2, 2026 03:16
2b2f9e6 to
df1b165
Compare
Collaborator
Author
|
build |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #14947.
Description
rlike/regexp_like,regexp_extract, andregexp_replacefell back to the CPU whenever a pattern used inline or scoped flag syntax ((?i)or(?i:…)). TheRegexParseronly special-cased(?:...)non-capturing groups; any other(?sequence that was not a lookahead was rejected, so case-insensitive patterns never ran on the GPU.This PR adds transpiler support for the case-insensitive flag, both the inline
(?i)and the scoped (non-capturing) form(?i:…). ASCII letters in case-insensitive runs (parts of the pattern where theiflag is in effect) are rewritten to match either case: literal characters and character-class ranges are folded (e.g.(?i)abc→[aA][bB][cC],(?i)[a-c]→[a-cA-C]). Scoping follows Java's rules: an inline flag applies from its position to the end of the enclosing group,(?-i)turns it back off, and(?i:...)is only in scope within its group. This covers all three placement shapes from the issue: flag at the start of the pattern, mid-pattern, and inside an alternation branch. Results are unchanged (identical to the CPU); only the execution location changes (GPU instead of CPU fallback).Anything that cannot be folded safely or easily still falls back to the CPU:
i(e.g.(?m),(?s)).a(?i)b|c|d(?-i)e, where carrying the flag state across|would require a significant rearchitecture of the transpiler. Note that the equivalent scoped forma(?i:b)|(?i:c)|(?i:d)ewill run on the GPU.(?i)\x61, which cannot be folded to a character class.A negated non-
iflag (e.g.(?-m)) is treated as a no-op, since those flags are off by default, and there is no mechanism to turn them on.Tip
The three implementation commits in this change (pre-refactoring, parser support, transpiler support) can be reviewed in order. Each builds independently.
Testing
(?i-),(?-),(?-:), and(?i-:).regexp_extractgroup extraction, and for each fallback rule above.regexp_test.pycomparing GPU vs CPU forrlike,regexp_extract, andregexp_replacewith case-insensitive inline and scoped flags, plus fallback coverage for unsupported flags, choice-crossing flags, and anchor combinations.Checklists
Documentation
Testing
(Please provide the names of the existing tests in the PR description.)
Performance