Skip to content

Support $count on navigation properties in $filter (#871)#878

Open
Remo wants to merge 1 commit into
flat3:5.xfrom
ortic:fix/issue-871-count-in-filter
Open

Support $count on navigation properties in $filter (#871)#878
Remo wants to merge 1 commit into
flat3:5.xfrom
ortic:fix/issue-871-count-in-filter

Conversation

@Remo

@Remo Remo commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

Using $count on a collection-valued navigation property within a filter expression (e.g. ?$filter=passengers/$count eq 0) previously threw a cryptic parser error ("Encountered an invalid symbol at: passengers/>$<count eq 0") because the filter parser had no tokenizer for the navigationProperty/$count syntax.

Add a Count expression node and a parser tokenizer that recognises navigationProperty/$count. On SQL drivers this compiles to a correlated ( SELECT COUNT(*) FROM <related> WHERE <constraints> ) subquery built from the navigation binding's referential constraints, so it can be compared like any other operand (eq, ne, gt, ge, lt, le) and combined with logical operators. This works on all SQL drivers including SQLite.

Drivers that cannot express it (in-memory collection drivers and MongoDB) now throw a clear NotImplementedException instead of a parser error.

Adds cross-dialect parser tests (generated SQL for MySQL, PostgreSQL, SQLite, SQLServer) and functional tests (Eloquent + SQL drivers).

Using `$count` on a collection-valued navigation property within a
filter expression (e.g. `?$filter=passengers/$count eq 0`) previously
threw a cryptic parser error ("Encountered an invalid symbol at:
passengers/>$<count eq 0") because the filter parser had no tokenizer
for the `navigationProperty/$count` syntax.

Add a Count expression node and a parser tokenizer that recognises
`navigationProperty/$count`. On SQL drivers this compiles to a
correlated `( SELECT COUNT(*) FROM <related> WHERE <constraints> )`
subquery built from the navigation binding's referential constraints,
so it can be compared like any other operand (eq, ne, gt, ge, lt, le)
and combined with logical operators. This works on all SQL drivers
including SQLite.

Drivers that cannot express it (in-memory collection drivers and
MongoDB) now throw a clear NotImplementedException instead of a parser
error.

Adds cross-dialect parser tests (generated SQL for MySQL, PostgreSQL,
SQLite, SQLServer) and functional tests (Eloquent + SQL drivers).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant