Repository navigation
feat(postgrest)!: order and limit inside a to-many embed on the typed surface - #1960
Conversation
… surface
Adds `embedded()` to the typed transform builder. It takes a to-many
relation and a callback that receives a scope typed against the embedded
table, offering `order`, `limit`, `range` and nested `embedded` calls:
.embedded(
Authors.books,
(books) => books.order(Books.createdAt.desc()).limit(1),
)
// books.order=created_at.desc&books.limit=1
The typed `limit()` and `range()` drop their untyped `referencedTable`
parameter in favor of the scope.
Fixes SDK-1758
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info
📝 Walkthrough
Merge Risk: ⚪ Minimal · up to
|
…select list (#1962) ## Summary Follow-up to #1960, from a review of that PR. A relation with a foreign key hint and no alias, such as a hand-written `PostgrestToOneRelation('users!messages_username_fkey', ...)`, was addressed by its hinted name everywhere outside the `select` list. PostgREST matches those paths against the alias or the table name only. Checked against the local stack: | Request | Result | |---|---| | `messages.limit=1` | applied, 1 row | | `messages!username.limit=1` | silently ignored, every row | | `order=users(username).desc` | applied | | `order=users!username(username).desc` | PGRST100 parse error | Outside the `select` list, the embed is now addressed by its alias, or by the table name without the hint. This fixes `embedded()` scopes, and also the to-one `order` keys and `embeddedFilterName`, which had the same bug before #1960. Typegen always pairs a hint with an alias, so generated tables were not affected. ## Other changes - The `embedded()` dartdoc now says exactly what a repeated call does: a later limit replaces only the limit, and a later range replaces both the offset and the limit. - The untyped `order()` merges its key through `appendOrderKey` instead of duplicating the merge logic. - In `MIGRATION.md`, the foreign key paragraph is back next to the relation text it explains, and the snippet is wrapped to 80 characters. ## Testing - New unit tests cover a hinted embed with no alias in a scope, in an order key and in a filter name. - The full postgrest suite passes against the local stack (623 tests). `melos analyze` and `dcm analyze` are clean. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Embedded ordering and filters now correctly use the referenced table name when a foreign-key hint is present without an alias, while preserving the hint in the select expression. * **Documentation** * Clarified how to address embedded relations when multiple foreign keys point to the same table. * Updated guidance on how repeated embedded sort keys, limits, and ranges are applied. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
Summary
The typed
order()had no way to address an embed, and the typedlimit()andrange()still took an untypedString? referencedTable. Sorting the rows inside a to-many embed was therefore impossible on the typed surface, solimit(1, referencedTable: 'books')trimmed an unsorted embed and returned an arbitrary row.This adds
embedded()to the typed transform builder, following the scope Swift shipped in supabase/supabase-swift#1458:embedded()takes aPostgrestToManyRelation<Row, Target>. The callback receives aPostgrestEmbeddedScope<Target>, so ordering by a column of another table does not compile.order,limit,rangeandembedded. Nested scopes render dotted paths, such asbooks.reviews.limit=3.Breaking
The typed
limit()andrange()no longer takereferencedTable. The typed surface is experimental, so the change is covered in the "Moving fromfrom()to the typed table API" section ofMIGRATION.mdand not as its own breaking section.Out of scope
Filtering inside an embed and the
requiring(!inner) counterpart will ship together in a follow-up. An embedded filter withoutrequiringsilently keeps every parent row.Other changes
PostgrestTableRequestis now@internal. It was already hidden from the package export, and the annotation keeps its fields out of the compliance symbol check.PostgrestEmbeddedPage. It was internal, and the scope replaces it.database.using_modifiers.relationship_embedinsdk-compliance.yaml.Testing
typed_query_test.dartcover rendering, nesting, aliases, repeated scopes and mutations.resource_embedding_test.dartchecks ordering, limit and range against the local stack.melos analyze,dcm analyzeand the local compliance symbol check are clean.Summary by CodeRabbit
New Features
PostgrestEmbeddedPageis now available through the public library exports.Changes
limit()andrange()now apply to top-level results only; use embedded options to paginate embedded rows.