Chelabase
ManagementTables

Change tables, columns, constraints, indexes, policies, grants and enums

POST
/v1/databases/{id}/branches/{branch_id}/schema-changes

Renders the operations to SQL (names quoted, expressions as given, each exactly one SQL expression) and runs them on one of the branch's Postgres databases as the owner (Admin only) or, with role, as that role (the SQL editor's session: your member role, then SET ROLE), in one transaction with lock_timeout (lock_timeout_ms, default 5000) and statement_timeout (60 s; 15 s for a dry run). A dry run runs the same statements and always rolls back; it evaluates your expressions (defaults, checks, USING), so their non-transactional side effects (e.g. nextval) remain. A statement that may rewrite a table over CHELABASE_TABLE_API_DRY_RUN_MAX_BYTES (default 256 MiB), and every one after it, is only rendered in a dry run (skipped), and then would_succeed is null. A table the request names that doesn't exist (and no earlier operation creates) is 404 with its op_index. Drops end RESTRICT and a request with drops returns dependents: what CASCADE would also remove beyond the request's own drop targets and their parts, and their hash. When something depends on a drop and the request confirms no cascade, the dry run and the real run alike answer 409 has_dependents with dependents, and change nothing. To cascade, send that hash as cascade.dependents_hash: the run (dry or real) locks the drop targets' tables, reads the dependents again, and refuses with 409 dependents_changed when they differ or when Postgres reports dropping anything but them and the parts of the request's other drop targets (drops that reach each other, e.g. a parent table and its child, need the hash of no dependents); a drop whose target an earlier drop of the request already removed is skipped (already_dropped). A CONCURRENTLY index operation must be the request's only operation: it runs outside a transaction (statement_timeout 900 s; a dry run only checks it), can't cascade, and when its build fails after creating its index, that INVALID index is dropped (another index of the same name never is). Postgres errors keep their fields (op_index, sqlstate, message, detail, hint, position; dry_run: true on a dry run). Each request is logged with its operation count, never its SQL.

Authorization

bearer
AuthorizationBearer <token>

In: header

Path Parameters

id*string

Database id

Formatuuid
branch_id*string

Branch id

Formatuuid

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

cascade?|null
database?string|null
dry_run?boolean
expect_acl?array<>
lock_timeout_ms?|
Formatint64
Range0 <= value
operations?array<||||||||||||||||||||||||||||||||||||>
role?string|null

Response Body

application/json

application/json

application/json

application/json

application/json

application/json

application/json

application/json

application/json

application/json

curl -X POST "https://example.com/v1/databases/497f6eca-6276-4993-bfeb-53cbbbba6f08/branches/497f6eca-6276-4993-bfeb-53cbbbba6f08/schema-changes" \  -H "Content-Type: application/json" \  -d '{}'
{  "committed": true,  "data_api_exposure": [    {      "chain": [        "string"      ],      "grantee": "string",      "op_index": 0    }  ],  "dependents": {    "hash": "string",    "objects": [      {        "description": "string",        "kind": "string",        "name": "string",        "parent": "string",        "schema": "string"      }    ]  },  "dry_run": true,  "statements": [    {      "executed": true,      "lock": "none",      "notices": [        "string"      ],      "op_index": 0,      "rewrites_table": true,      "skipped": "large_table_rewrite",      "sql": "string"    }  ],  "would_succeed": true}

One role's privileges in a Postgres database GET

The privileges `role` holds in one Postgres database of a branch (one of the branch's recorded databases), read as the database owner, a page at a time. Without `schema`: the schemas (paged by name) with the role's schema entries, and the default privileges of those schemas. With `schema`: every table, view, materialized view, partitioned or foreign table, sequence, function and procedure of it (paged), with the role's entries on it and on its columns, the hub's "all rows" policy for the role, its owner and whether an owner run can act as that owner (`owner_settable`). Every entry carries its grantor and grant option. Each schema, object and default-privileges row carries `acl_hash`, a hash over its whole ACL (every grantee; a relation's covers its columns): send it back as `expect_acl` with a schema change. `role=public` reads PUBLIC's entries. Member logins and personal logins aren't listed.

One table's or other relation's structure GET

Any relation the object list shows, with its `kind`. An ordinary table (`kind: table`) carries its columns, constraints, indexes, policies, privileges, options and comment, as the schema merge reads them; a table that inherits from another is read the same way. A view, materialized view, foreign table or partitioned table is read-only: its columns (in `attnum` order, with `format_type`'s text and `not_null`) and comment, every other list empty; a view's definition and a foreign table's options are never returned. A partition, an index, a sequence, a composite type, a relation in a schema the object list leaves out, or a missing one is 404.