Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion packages/capability-matrix/capabilities/database.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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.
Expand Down Expand Up @@ -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
group: configuration
Original file line number Diff line number Diff line change
@@ -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)
23 changes: 23 additions & 0 deletions packages/capability-matrix/specs/database/mutate/count.md
Original file line number Diff line number Diff line change
@@ -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`
3 changes: 3 additions & 0 deletions packages/capability-matrix/specs/database/mutate/insert.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Original file line number Diff line number Diff line change
@@ -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)
3 changes: 3 additions & 0 deletions packages/capability-matrix/specs/database/mutate/upsert.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)