Skip to content

fix(validator): refuse filter values that are not a list - #1028

Merged
abnegate merged 2 commits into
mainfrom
fix/filter-values-list
Oct 16, 2026
Merged

abnegate merged 2 commits into
mainfrom
fix/filter-values-list

Conversation

@abnegate

Copy link
Copy Markdown
Member

What

Staging log scan found a PHP warning, Undefined array key 0 at Validator/Query/Filter.php:436 (isEmpty()), on list endpoints when a query's values arrive as a JSON object ({"a":1}) instead of a list.

Query::parse() accepts an object for values as readily as a list. Filter read the values by position, which raised the warning. In the library such a filter was then accepted: find() on main returns rows for {"method":"equal","attribute":"name","values":{"value":"a"}} on every adapter, and MongoDB raises a second warning in Mongo.php. A distance tuple given as an object warned the same way, and a vector query on an undeclared attribute of a schemaless collection read the schema by name and warned.

Filter now refuses:

  • values that are not a list, as <Method> query values must be a list;
  • a distance tuple that is not a list of [geometry, finite distance, boolean meters]. Without this, the builder's typed distance filter would reject it with a TypeError;
  • a vector value that is not a list.

This is ported from the unpushed qfix-overflow work (214f0fe0f), with an E2E test on every adapter added.

Regression tests

Test Adapters origin/main this PR
DocumentTests::testFilterValuesThatAreNotAListAreAnInvalidQuery: equal (string and numeric keys), notEqual, contains, lessThan, between, startsWith, exists; intersects, distanceLessThan (tuple as object, and geometry as object) where spatial; vectorDot where vectors; each on find() and count(); a list-valued equal still matches MySQL, MariaDB, Postgres, SQLite, Memory, Redis fail: find() refuses {"method":"equal",...,"values":{"value":"a"}} (accepted) plus PHP warning Undefined array key 0 at Filter.php:436 pass
MongoDB fail: same, plus a second warning at Mongo.php:3560 pass
Unit\Validator\Query\FilterMalformedValuesTest (9 object-valued methods, distance tuple as object, schemaless vector) n/a fail pass

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":"equal","attribute":"name","values":{"a":1}} → 400 general_query_invalid, message Invalid query: Equal query values must be a list, and no PHP warning in the logs. The same applies to queries[]={"method":"distanceLessThan","attribute":"pt","values":{"geometry":[[1,2],10,false]}}.

The spatial range PR is stacked on this one; merge this first.

🤖 Generated with Claude Code

abnegate and others added 2 commits October 16, 2026 14:32
A query parsed from JSON takes an object for its values as readily as a
list. Filter read such values by position, so isEmpty() raised "Undefined
array key 0" for an equal, contains, exists or spatial query, and a distance
tuple given as an object raised the same for its distance. A vector query
on an undeclared attribute of a schemaless collection read the schema by
its name and warned too. 7.4.2 reads the values the same way.

Filter refuses values that are not a list, and a distance tuple that is not
a list of geometry, finite distance and boolean meters flag, which the
builder's typed distance filter would otherwise reject with a TypeError. A
vector value has to be a list as well.

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

Covers find() and count() on each adapter for the values QA sent as a JSON
object, including spatial and vector filters where the adapter has them,
and fails on main with the "Undefined array key 0" warning.

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 30 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: b3240bdb-d130-4174-a9e0-465c7f02bdd6
📥 Commits

Reviewing files that changed from the base of the PR and between 1ca4d03 and ad1a9cb.

📒 Files selected for processing: 3
  • src/Database/Validator/Query/Filter.php
  • tests/e2e/Adapter/Scopes/DocumentTests.php
  • tests/unit/Validator/Query/FilterMalformedValuesTest.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.

@abnegate
abnegate merged commit 09a4729 into main Oct 16, 2026
24 checks passed
@abnegate
abnegate deleted the fix/filter-values-list branch October 16, 2026 03:31
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