Repository navigation
fix(query): refuse a nested path on an attribute that holds no nested values - #1022
Conversation
… values
The filter and select validators treated any dotted attribute as a
relationship path and checked only its first segment. On a plain attribute,
equal('name.x') or select(['name.x']) passed validation and reached the
engine, which named a column that does not exist: MySQL 1054 and
PostgreSQL 42703 surfaced as NotFound('Attribute not found'), so callers
answered 404 or 500 for a malformed query, and MongoDB silently matched
nothing.
A dotted path now passes only when its base is a relationship or an object
attribute, or a join alias, and is otherwise refused as an invalid query
before it reaches the adapter. Order already refused nested paths, and
aggregate and group-by accept only exact schema keys. Schemaless adapters
keep accepting any path.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Warning Review limit reachedYou'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 48 minutes. View limit details
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info
📝 Walkthrough
Merge Risk: ⚪ Minimal · up to
|
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
utopia-php/database#1022 refuses a filter or select on a dotted path under a plain attribute before the adapter runs, on every adapter. Before it the SQL engines answered 404 or 500 and MongoDB an empty 200. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Problem
FilterandSelecttreat any dotted attribute as a relationship path and validate only its first segment. On a plain attribute,equal('name.x', [...])orselect(['name.x'])passes validation and reaches the adapter, which names a column that does not exist:NotFound('Attribute not found'). Appwrite (fix(databases): answer bad query input with 4xx, not 500 or warnings appwrite/appwrite#14538) answers that as 404table_not_foundon the documents/rows list and 500 on/users.Which shapes reach the engine today, with a
stringattributes:equal('s.x')(and every filter,count)select(['s.x'])orderAsc('s.x')groupBy('s.x')equal('o.x')on an object,equal('rel.name')on a relationship,alias.columnon a joinFix
A dotted path passes only when its base is a relationship or object attribute, or a join alias. Otherwise the validator refuses it (
Cannot query nested attribute on: s/Cannot select nested attribute on: s), sofind/countthrowQueryExceptionbefore the adapter runs. Schemaless adapters (noDefinedAttributes) keep accepting any path. An aggregation select keeps its existing ungrouped-select message.Tests
FilterTest(plain attribute refused; relationship, object and schemaless accepted),SelectTest(plain refused, object accepted).DocumentQueriesTest::test_valid_queriesassertedselect(['price.relation'])on a double was valid; it now asserts the refusal. The new refusal cases fail without the fix.DocumentTests::testNestedPathOnAPlainAttributeIsAnInvalidQueryruns filter, count and select on every adapter with defined attributes (MariaDB, MySQL, Postgres, SQLite, MongoDB, and the shared-table/pool/mirror variants). Without the fix, the SQL adapters throwNotFoundand MongoDB returns an empty page.SwooleAbsentTest(no Redis extension) andBaseAdapterStateTest::testAKeyThePatternEngineCannotFilterIsAnError, both outside this change.🤖 Generated with Claude Code
Summary by CodeRabbit