Skip to content

ADP-1966 | Escape regex metacharacters in Postgres LIKE filter values - #330

Closed
sanjulksharma wants to merge 1 commit into
hypertrace:mainfrom
sanjulksharma:ADP-1966/escape-regex-metacharacters-in-postgres-like
Closed

sanjulksharma wants to merge 1 commit into
hypertrace:mainfrom
sanjulksharma:ADP-1966/escape-regex-metacharacters-in-postgres-like

Conversation

@sanjulksharma

@sanjulksharma sanjulksharma commented Oct 21, 2026 •

Copy link
Copy Markdown
Collaborator

Fixes ASP-3514: a LIKE filter value containing regex metacharacters (e.g. {{) works on MongoDB but throws invalid regular expression: quantifier operand invalid on Postgres, since Postgres's ~* (POSIX ARE) hard-errors on malformed patterns that MongoDB's PCRE2 tolerates. Adds a validity gate that escapes such values to match literally instead of erroring, applied to both the legacy and v1 LIKE parsers, and drops the now-redundant .* wrapping since ~* is already unanchored.

🤖 Generated with Claude Code

Postgres's `~*` operator (used to implement the LIKE/"contains" filter)
is a case-insensitive, unanchored regex match using POSIX ARE, whereas
MongoDB's $regex uses PCRE2. PCRE2 tolerates malformed patterns (e.g. an
unmatched quantifier brace like "{{") by treating them literally, while
Postgres's ARE engine hard-errors with "invalid regular expression:
quantifier operand invalid" on the same input - breaking LIKE/"contains"
filters on Postgres for values containing regex metacharacters (e.g. API
Inventory domain search values like "{{" or "${${8gs").

Add a validity gate (PostgresUtils#sanitizeRegexValue) that passes a LIKE
value through unchanged if it is already a valid regex (preserving
existing regex-filter semantics, e.g. ".*amp.*", "^Sun"), and otherwise
escapes POSIX ARE metacharacters so the value is matched literally
instead of erroring out. Apply this in both LIKE code paths: the legacy
Filter/Op parser and the v1 expression parser
(PostgresLikeRelationalFilterParser), the latter being the actual path
hit by the reported production stacktrace.

Also drop the now-redundant ".*<value>.*" wrapping previously applied to
LIKE values before the ~* search, since `~*` is already an unanchored
substring regex match.

Note: for a value that is not a valid regex in either engine but IS
syntactically valid Perl/PCRE2 (e.g. "${${8gs", which PCRE2 compiles but
matches 0 documents because "$" is treated as an end-of-line anchor),
this introduces a narrow Mongo/Postgres result divergence (Mongo: 0
matches, Postgres: 1 literal match) - a deliberate, documented trade-off
versus leaving Postgres's LIKE operator broken for such inputs.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

AI-Session-Id: f9a3360e-ecb3-4388-beeb-682ed3b1d400
AI-Tool: claude-code
AI-Model: unknown
@sanjulksharma
sanjulksharma force-pushed the ADP-1966/escape-regex-metacharacters-in-postgres-like branch from 3abba57 to 1f38464 Compare October 21, 2026 06:03
@sanjulksharma

Copy link
Copy Markdown
Collaborator Author

Reopening from a branch pushed directly to hypertrace/document-store (now that I have collaborator access), since CI's pull_request_target workflow can't check out fork PR code.

@codecov

codecov Bot commented Oct 21, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 93.75000% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 58.97%. Comparing base (cd897e9) to head (1f38464).

Files with missing lines Patch % Lines
...re/documentstore/postgres/utils/PostgresUtils.java 93.33% 1 Missing ⚠️

❗ There is a different number of reports uploaded between BASE (cd897e9) and HEAD (1f38464). Click for more details.

HEAD has 1 upload less than BASE
Flag BASE (cd897e9) HEAD (1f38464)
integration 1 0
Additional details and impacted files
@@              Coverage Diff              @@
##               main     #330       +/-   ##
=============================================
- Coverage     81.23%   58.97%   -22.26%     
- Complexity     1698     1703        +5     
=============================================
  Files           243      243               
  Lines          7780     7793       +13     
  Branches        771      773        +2     
=============================================
- Hits           6320     4596     -1724     
- Misses          962     2712     +1750     
+ Partials        498      485       -13     
Flag Coverage Δ
integration ?
unit 58.97% <93.75%> (+0.13%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant