diff --git a/packages/capability-matrix/capabilities/database.yaml b/packages/capability-matrix/capabilities/database.yaml index 52d8519..b1484e8 100644 --- a/packages/capability-matrix/capabilities/database.yaml +++ b/packages/capability-matrix/capabilities/database.yaml @@ -14,6 +14,14 @@ groups: - id: configuration title: Client Configuration features: + - id: database.mutate.bulk_rows_with_differing_fields + name: Bulk Write Rows with Differing Fields + description: Insert or upsert multiple rows with different field sets in one request, without requiring callers to fill every omitted field explicitly. + group: mutate + - id: database.mutate.count + name: Count Mutated Rows + description: Request the number of rows affected by an insert, update, upsert, or delete operation. + group: mutate - id: database.mutate.delete name: Delete Rows description: Delete rows from a table or view that match a filter. @@ -22,6 +30,10 @@ features: name: Insert Rows description: Insert one or more rows into a table or view. group: mutate + - id: database.mutate.missing_defaults + name: Use Defaults for Missing Fields + description: Use database column defaults instead of null for fields omitted from bulk insert or upsert rows. + group: mutate - id: database.mutate.select_after_mutation name: Select After Mutation description: Chain a column selection onto an insert, update, upsert, or delete to return the affected rows in the response. @@ -241,4 +253,4 @@ features: - id: database.configuration.request_timeout name: Request Timeout description: Set a global request timeout in milliseconds at construction time; in-flight requests are cancelled once the deadline is reached. - group: configuration \ No newline at end of file + group: configuration diff --git a/packages/capability-matrix/specs/database/mutate/bulk_rows_with_differing_fields.md b/packages/capability-matrix/specs/database/mutate/bulk_rows_with_differing_fields.md new file mode 100644 index 0000000..d067c3d --- /dev/null +++ b/packages/capability-matrix/specs/database/mutate/bulk_rows_with_differing_fields.md @@ -0,0 +1,28 @@ +# Bulk Write Rows with Differing Fields + +Insert or upsert multiple rows with different field sets in one request. + +## API + +Spec: [PostgREST Documentation: Specifying Columns](https://docs.postgrest.org/en/latest/references/api/tables_views.html#specifying-columns) + +- `POST /{relation}?columns={union-of-fields}` + +## Behavior + +The SDK accepts a collection whose rows do not all contain the same fields and sends it as one bulk insert or upsert. It identifies the union of fields across the non-empty collection and supplies that set through PostgREST's `columns` query parameter. + +The SDK must not require callers to add placeholder values for omitted fields. Their values follow the missing-field behavior selected for the request. + +An empty collection writes nothing and must not produce an empty `columns` parameter. + +## Errors + +- `PGRST204` when a field named by `columns` does not exist +- Database constraint errors still apply to every row in the bulk operation + +## Related + +- [Insert Rows](insert.md) +- [Upsert Rows](upsert.md) +- [Use Defaults for Missing Fields](missing_defaults.md) diff --git a/packages/capability-matrix/specs/database/mutate/count.md b/packages/capability-matrix/specs/database/mutate/count.md new file mode 100644 index 0000000..26b89cf --- /dev/null +++ b/packages/capability-matrix/specs/database/mutate/count.md @@ -0,0 +1,23 @@ +# Count Mutated Rows + +Request the number of rows affected by an insert, update, upsert, or delete operation. + +## API + +Spec: [PostgREST Documentation: Counting](https://docs.postgrest.org/en/latest/references/api/pagination_count.html#counting) + +- `POST`, `PATCH`, or `DELETE` with `Prefer: count=exact|planned|estimated` + +## Behavior + +The caller chooses a supported count strategy when starting a mutation. The response exposes the resulting affected-row count separately from any returned row representation. + +Counting is optional. Omitting it avoids requesting a total, and selecting it must not implicitly request the mutated rows themselves. + +The count preference is independent of other `Prefer` entries, including `return`, `resolution`, and `missing`. An SDK must preserve those entries when adding the count preference. + +## Related + +- [Insert Rows](insert.md) +- [Upsert Rows](upsert.md) +- `database.mutate.select_after_mutation` diff --git a/packages/capability-matrix/specs/database/mutate/insert.md b/packages/capability-matrix/specs/database/mutate/insert.md index afe237b..67c99bc 100644 --- a/packages/capability-matrix/specs/database/mutate/insert.md +++ b/packages/capability-matrix/specs/database/mutate/insert.md @@ -48,3 +48,6 @@ whole header. ## Related - [Upsert Rows](upsert.md) — insert, but resolve a conflict instead of failing +- [Bulk Write Rows with Differing Fields](bulk_rows_with_differing_fields.md) +- [Use Defaults for Missing Fields](missing_defaults.md) +- [Count Mutated Rows](count.md) diff --git a/packages/capability-matrix/specs/database/mutate/missing_defaults.md b/packages/capability-matrix/specs/database/mutate/missing_defaults.md new file mode 100644 index 0000000..cb9b1fc --- /dev/null +++ b/packages/capability-matrix/specs/database/mutate/missing_defaults.md @@ -0,0 +1,27 @@ +# Use Defaults for Missing Fields + +Use database column defaults instead of null for fields omitted from bulk insert or upsert rows. + +## API + +Spec: [PostgREST Documentation: Missing](https://docs.postgrest.org/en/latest/references/api/preferences.html#missing) + +- `POST /{relation}?columns={union-of-fields}` with `Prefer: missing=default` + +## Behavior + +When rows in a bulk insert or upsert omit different fields, the caller can choose whether each omitted value becomes SQL `NULL` or uses the column's database `DEFAULT`. + +Using database defaults sends `missing=default`. The alternative omits that preference or sends `missing=null`. The choice only affects omitted fields. An explicitly supplied null remains null. + +The missing preference is independent of other `Prefer` entries, including `return`, `resolution`, and `count`. An SDK must preserve those entries when changing the missing-field behavior. + +## Prerequisites + +The request must supply a `columns` parameter containing the union of fields across the rows. Without it, a bulk payload must carry an identical key set on every row (see [Insert Rows](insert.md)), and a field omitted from every row is left out of the statement entirely, so the database applies its default regardless of this preference. + +## Related + +- [Bulk Write Rows with Differing Fields](bulk_rows_with_differing_fields.md) +- [Insert Rows](insert.md) +- [Upsert Rows](upsert.md) diff --git a/packages/capability-matrix/specs/database/mutate/upsert.md b/packages/capability-matrix/specs/database/mutate/upsert.md index 18e0d3c..2c072c6 100644 --- a/packages/capability-matrix/specs/database/mutate/upsert.md +++ b/packages/capability-matrix/specs/database/mutate/upsert.md @@ -45,3 +45,6 @@ the whole header drops `resolution=` and silently turns the upsert into an inser ## Related - [Insert Rows](insert.md) — the same write without conflict resolution +- [Bulk Write Rows with Differing Fields](bulk_rows_with_differing_fields.md) +- [Use Defaults for Missing Fields](missing_defaults.md) +- [Count Mutated Rows](count.md)