Skip to content

fix(adapters): refuse a regex the engine cannot compile as a query error - #1030

Merged
abnegate merged 3 commits into
mainfrom
fix/regex-invalid-pattern
Oct 16, 2026
Merged

abnegate merged 3 commits into
mainfrom
fix/regex-invalid-pattern

Conversation

@abnegate

@abnegate abnegate commented Oct 16, 2026 •

Copy link
Copy Markdown
Member

What

Staging bug C: regex("s", ["(("]) gave a 500, PDOException 3691 Mismatched parenthesis in regular expression.

On origin/main a regex pattern that the engine cannot compile fails as follows:

  • MariaDB: unmapped PDOException 1139.
  • MySQL: unmapped PDOException 3685–3700 or 3887.
  • PostgreSQL: unmapped PDOException 2201B.
  • MongoDB: raw driver error 51091.
  • SQLite, Memory and Redis match with PCRE, read such a pattern as matching nothing, and return no rows silently.

Each engine's invalid-pattern errors now map to Exception\Query ("Invalid regular expression"). The PCRE adapters refuse a pattern that does not compile with the same error. The pattern is not pre-validated in PHP, because each engine has its own dialect (PCRE2, ICU, ARE), so a pattern valid on one engine may not compile on another.

This is ported from the unpushed qfix-overflow work (83aae640d) without the spatial error mapping, which is in the spatial PR. The E2E test was extended to cover count() and more patterns.

Regression tests

Test Adapters origin/main this PR
DocumentTests::testInvalidRegexIsAQueryError: ((, [, a{2,1}, ), *a on find() and count(); a valid ^tar still matches MySQL error: PDOException 3691 Mismatched parenthesis in regular expression pass
MariaDB error: PDOException 1139 Regex error 'missing closing parenthesis at offset 2' pass
Postgres error: PDOException 2201B invalid regular expression: parentheses () not balanced pass
MongoDB error: Utopia\Mongo\Exception E51091 Regular expression is invalid pass
SQLite, Memory, Redis fail: pattern accepted, no rows returned pass
Unit\EngineErrorMappingTest (regex errors per engine), Unit\MemoryRegexTest, Unit\SQLiteRegexTest n/a fail pass

MongoReadFilterTests::testCountReportsDriverErrors pinned the raw driver exception to show that count() reports the error instead of answering 0. It now expects Exception\Query with the driver error as its previous exception, which still shows that.

Run locally against Docker: the full adapter suites for MySQL, MariaDB, Postgres, SQLite, MongoDB, Memory and Redis pass, as do the full unit suite, Pint and PHPStan.

API repro (Appwrite)

GET /v1/tablesdb/{db}/tables/{t}/rows?queries[]={"method":"regex","attribute":"s","values":["(("]} → 400 general_query_invalid, message Invalid regular expression (was 500). The same holds with total=true (the count path).

🤖 Generated with Claude Code

abnegate and others added 2 commits October 16, 2026 16:31
A regex filter with a pattern such as `((` or `[` failed with an unmapped
PDOException on MariaDB (1139), MySQL (3685 to 3700, 3887) and PostgreSQL
(2201B), and a raw driver error on MongoDB (51091), which consumers report
as a server error. SQLite, Memory and Redis match with PCRE and read such a
pattern as matching nothing. 7.4.2 maps none of them either.

Each engine's invalid pattern errors map to Exception\Query, and the PCRE
adapters refuse a pattern that does not compile with the same error. The
pattern is not checked up front: each engine has its own dialect (PCRE2,
ICU, ARE), so a pattern valid on one may not compile on another.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
testCountReportsDriverErrors pinned the raw driver exception to prove
count() reports the error rather than answering 0. It now arrives as
Exception\Query with the driver error as its previous, which still proves
that.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Oct 16, 2026 •

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 13 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

⚙️ Run configuration
  • Configuration used: Repository: utopia-php/database/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: c830aa6f-94a6-41c5-8772-c50240e7d6cf
📥 Commits

Reviewing files that changed from the base of the PR and between b1ab94f and 484006f.

📒 Files selected for processing: 12
  • src/Database/Adapter/MariaDB.php
  • src/Database/Adapter/Memory.php
  • src/Database/Adapter/Mongo.php
  • src/Database/Adapter/MySQL.php
  • src/Database/Adapter/Postgres.php
  • src/Database/Adapter/Redis.php
  • src/Database/Adapter/SQLite.php
  • tests/e2e/Adapter/Scopes/DocumentTests.php
  • tests/e2e/Adapter/Scopes/MongoReadFilterTests.php
  • tests/unit/EngineErrorMappingTest.php
  • tests/unit/MemoryRegexTest.php
  • tests/unit/SQLiteRegexTest.php
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

…tern

# Conflicts:
#	src/Database/Adapter/MariaDB.php
#	src/Database/Adapter/MySQL.php
#	tests/unit/EngineErrorMappingTest.php
@abnegate
abnegate merged commit be63bd1 into main Oct 16, 2026
24 checks passed
@abnegate
abnegate deleted the fix/regex-invalid-pattern branch October 16, 2026 04:36
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