From 652a04120a87359306b25d351d3208f3cf1e8896 Mon Sep 17 00:00:00 2001 From: Christian Winter Date: Wed, 7 Oct 2026 16:31:32 +0200 Subject: [PATCH 01/21] Add updated docs for tables to reflect new functionality --- content/compatibility/sql_features.md | 60 ++++++++++----------- content/references/objects/tables.md | 77 ++++++++++++++++++++++++--- 2 files changed, 99 insertions(+), 38 deletions(-) diff --git a/content/compatibility/sql_features.md b/content/compatibility/sql_features.md index d3d5dd9..d3c5961 100644 --- a/content/compatibility/sql_features.md +++ b/content/compatibility/sql_features.md @@ -40,39 +40,39 @@ the [system table compatibility](../system_table) page. | System Columns | Yes | Only meaningful for tableoid and ctid | | UNLOGGED TABLE | No | | | CREATE TABLE LIKE | Partial | Copies column names and types. `INCLUDING` options not supported | -| DROP TABLE CASCADE | No | | +| DROP TABLE CASCADE | Yes | [Documentation](/docs/references/objects/tables/#drop-table) | ### Table Modification (ALTER TABLE) -| **Feature** | **Support State** | **Details** | -|-----------------------------------|-------------------|---------------------------------------------------| -| ADD COLUMN | Yes | | -| ADD COLUMN IF NOT EXISTS | Yes | | -| DROP COLUMN | Yes | | -| DROP COLUMN IF EXISTS | Yes | | -| DROP COLUMN CASCADE | Yes | | -| RENAME COLUMN | Yes | | -| RENAME TO | Yes | | -| ADD CHECK | No | Only at CREATE TABLE time | -| ADD CONSTRAINT (PRIMARY KEY) | Yes | [Documentation](/docs/references/objects/tables/) | -| ADD CONSTRAINT (UNIQUE) | Yes | [Documentation](/docs/references/objects/tables/) | -| ADD CONSTRAINT (FOREIGN KEY) | Yes | [Documentation](/docs/references/objects/tables/) | -| DROP CONSTRAINT | Yes | [Documentation](/docs/references/objects/tables/) | -| DROP CONSTRAINT IF EXISTS | Yes | | -| DROP CONSTRAINT CASCADE | Yes | | -| RENAME CONSTRAINT | No | | -| ALTER COLUMN SET/DROP DEFAULT | No | | -| ALTER COLUMN SET/DROP NOT NULL | No | | -| ALTER COLUMN TYPE | No | | -| SET SCHEMA | No | | -| OWNER TO | Yes | | -| ENABLE/DISABLE ROW LEVEL SECURITY | Yes | CREATE POLICY requires an enterprise license | -| FORCE/NO FORCE ROW LEVEL SECURITY | Yes | | -| SET TABLESPACE | No | | -| CLUSTER ON / SET WITHOUT CLUSTER | No | | -| ATTACH / DETACH PARTITION | No | | -| ENABLE/DISABLE TRIGGER | No | Triggers are not implemented | -| VALIDATE CONSTRAINT | No | | +| **Feature** | **Support State** | **Details** | +|-----------------------------------|-------------------|---------------------------------------------------------------------| +| ADD COLUMN | Yes | | +| ADD COLUMN IF NOT EXISTS | Yes | | +| DROP COLUMN | Yes | | +| DROP COLUMN IF EXISTS | Yes | | +| DROP COLUMN CASCADE | Yes | | +| RENAME COLUMN | Yes | | +| RENAME TO | Yes | | +| ADD CHECK | No | Only at CREATE TABLE time | +| ADD CONSTRAINT (PRIMARY KEY) | Yes | [Documentation](/docs/references/objects/tables/) | +| ADD CONSTRAINT (UNIQUE) | Yes | [Documentation](/docs/references/objects/tables/) | +| ADD CONSTRAINT (FOREIGN KEY) | Yes | [Documentation](/docs/references/objects/tables/) | +| DROP CONSTRAINT | Yes | [Documentation](/docs/references/objects/tables/) | +| DROP CONSTRAINT IF EXISTS | Yes | | +| DROP CONSTRAINT CASCADE | Yes | | +| RENAME CONSTRAINT | Yes | [Documentation](/docs/references/objects/tables/#rename-constraint) | +| ALTER COLUMN SET/DROP DEFAULT | Yes | [Documentation](/docs/references/objects/tables/#set-default) | +| ALTER COLUMN SET/DROP NOT NULL | Yes | [Documentation](/docs/references/objects/tables/#set-not-null) | +| ALTER COLUMN TYPE | No | | +| SET SCHEMA | Yes | [Documentation](/docs/references/objects/tables/#set-schema) | +| OWNER TO | Yes | | +| ENABLE/DISABLE ROW LEVEL SECURITY | Yes | CREATE POLICY requires an enterprise license | +| FORCE/NO FORCE ROW LEVEL SECURITY | Yes | | +| SET TABLESPACE | No | | +| CLUSTER ON / SET WITHOUT CLUSTER | No | | +| ATTACH / DETACH PARTITION | No | | +| ENABLE/DISABLE TRIGGER | No | Triggers are not implemented | +| VALIDATE CONSTRAINT | No | | ### Privileges diff --git a/content/references/objects/tables.md b/content/references/objects/tables.md index fc82289..8e95e3c 100644 --- a/content/references/objects/tables.md +++ b/content/references/objects/tables.md @@ -74,8 +74,10 @@ CedarDB supports the following referential actions on foreign keys: * `ON DELETE RESTRICT`: prevents deletion if child rows exist. * `ON DELETE NO ACTION`: same as RESTRICT, and the default. * `ON UPDATE CASCADE`: updates child rows when the referenced key value changes. +* `ON UPDATE RESTRICT`: prevents updating the referenced key if child rows exist. +* `ON UPDATE NO ACTION`: same as RESTRICT, and the default. -`ON DELETE SET NULL` and `ON DELETE SET DEFAULT` are not yet implemented. +`ON DELETE SET NULL`, `ON DELETE SET DEFAULT`, and `ON UPDATE SET NULL` are not yet implemented. ### Options @@ -159,7 +161,8 @@ With `GENERATED ALWAYS AS IDENTITY`, you need to use `OVERRIDING SYSTEM VALUE` t ### Permissions To create a table, you need the `CREATE` privilege on the target schema. -By default, every role has the `CREATE` privilege on the `public` schema. +By default, only the database owner has the `CREATE` privilege on the [`public` schema](/docs/references/objects/schemas#schema-privileges). +Creating a `TEMPORARY` table instead requires the `TEMPORARY` privilege on the current database, which every role has by default. ## CREATE TABLE AS @@ -237,13 +240,24 @@ Drop multiple tables in one statement: DROP TABLE staging_data, temp_results; ``` -If another table has a foreign key referencing the table being dropped, the DROP fails with an error. -Drop the dependent table first. -`DROP TABLE CASCADE` is not yet supported. +By default, CedarDB refuses to drop a table that other objects depend on, such as a foreign key from another table or a view built on it. +Use `CASCADE` to drop the table together with all objects that depend on it: + +```sql +DROP TABLE species CASCADE; +``` + +Dependent foreign key constraints and views are removed along with the table. +`RESTRICT` is the default behavior and rejects the drop if any object still depends on the table: + +```sql +DROP TABLE species RESTRICT; +``` ### Permissions -To drop a table you must own it, own its schema, or be a database superuser. +To drop a table you must own it, own its schema, or own the database. +Superusers can drop any table. ## ALTER TABLE @@ -290,6 +304,35 @@ ALTER TABLE species RENAME COLUMN botanical_name TO scientific_name; Renaming a column does not rename any constraints whose default name was derived from the old column name. For example, a unique constraint with the default name `species_botanical_name_key` keeps that name after the column is renamed. +#### SET DEFAULT + +Set the default value applied to a column when no value is supplied on INSERT: + +```sql +ALTER TABLE species ALTER COLUMN iucn_status SET DEFAULT 'not evaluated'; +``` + +Remove an existing default: + +```sql +ALTER TABLE species ALTER COLUMN iucn_status DROP DEFAULT; +``` + +#### SET NOT NULL + +Add a not-null constraint to an existing column. +CedarDB validates the current rows and fails if the column already contains null values: + +```sql +ALTER TABLE species ALTER COLUMN botanical_name SET NOT NULL; +``` + +Remove a not-null constraint: + +```sql +ALTER TABLE species ALTER COLUMN botanical_name DROP NOT NULL; +``` + #### RENAME TABLE ```sql @@ -349,6 +392,14 @@ Drop a constraint and cascade to dependent constraints: ALTER TABLE child_table DROP CONSTRAINT fk_constraint CASCADE; ``` +#### RENAME CONSTRAINT + +Rename an existing constraint, using either its explicit name or its default name: + +```sql +ALTER TABLE orders RENAME CONSTRAINT orders_pkey TO orders_primary; +``` + ### Storage Options Change the general-purpose compression codec used for on-disk column data. @@ -360,6 +411,16 @@ ALTER TABLE species SET (compression = zstd); ALTER TABLE species SET (compression = none); ``` +### SET SCHEMA + +Move a table to a different schema: + +```sql +ALTER TABLE species SET SCHEMA taxonomy; +``` + +The target schema must already exist, and you need the `CREATE` privilege on it. + ### Ownership ```sql @@ -388,5 +449,5 @@ This feature requires an enterprise license. ### Permissions -To alter a table you must be its owner. -Superusers can alter any table. +To alter a table you must be its owner. Superusers can alter any table. +`SET SCHEMA` additionally requires the `CREATE` privilege on the destination schema, and `OWNER TO` requires the ability to set your role to the new owner. From 271bb6ca25409d0bfb2eb98571ef48948287b0e6 Mon Sep 17 00:00:00 2001 From: Christian Winter Date: Wed, 7 Oct 2026 16:31:33 +0200 Subject: [PATCH 02/21] Update docs for databases --- content/references/objects/databases.md | 187 +++++++++++++++++++++--- 1 file changed, 166 insertions(+), 21 deletions(-) diff --git a/content/references/objects/databases.md b/content/references/objects/databases.md index 10e8f43..9b1bbb3 100644 --- a/content/references/objects/databases.md +++ b/content/references/objects/databases.md @@ -4,43 +4,188 @@ linkTitle: "Databases" weight: 50 --- -Create database allows creating a new *logical* database. -Multiple databases can be used for logical separation of data. -When connection to CedarDB, you need to specify the database that you want to connect to. -All queries that execute in this connection can only read and write data in this database. - -Usage example: +A database is a named, logically separate collection of schemas, tables, and other objects on a CedarDB server. +When you connect to CedarDB, you choose the database to connect to. +All queries on that connection can only read and write objects in that database. +Roles are shared by all databases on the server. ```sql -create database newdb owner postgres; +CREATE DATABASE forestry; ``` -Afterward, you can connect to the freshly created database: +Afterward, connect to the new database: ```shell -psql -h localhost -U postgres -d newdb +psql -h localhost -U postgres -d forestry +``` + +## CREATE DATABASE + +`CREATE DATABASE` creates a new, empty database. + +```text +CREATE DATABASE + [ [ WITH ] [ OWNER [=] ] + [ ENCODING [=] 'UTF8' ] + [ TEMPLATE [=] { template0 | template1 | DEFAULT } ] ] ``` -## Session defaults +| Parameter | Description | +|------------|-----------------------------------------------------------------------------------------------------------------| +| `` | The name of the new database. | +| `OWNER` | The role that owns the new database. Defaults to the role that runs the statement. | +| `ENCODING` | The character encoding. CedarDB always stores text as UTF-8. | +| `TEMPLATE` | Accepted for compatibility with `template0`, `template1`, and `DEFAULT` only. The new database is always empty. | + +Create a database that belongs to another role: -`ALTER DATABASE ... SET` stores a default value for a [setting](/docs/references/sessions/settings). -Every new session connecting to this database starts with this value: +```sql +CREATE ROLE forester LOGIN; +CREATE DATABASE forestry_reports OWNER forester; +``` ```sql -alter database newdb set statement_timeout = '30s'; +SELECT datname, datdba::regrole AS owner FROM pg_database WHERE datname = 'forestry_reports'; +``` + +```text + datname | owner +------------------+---------- + forestry_reports | forester +``` + +### Permissions + +To create a database, you must be a superuser or have the `CREATEDB` attribute. +The creator owns the new database, unless you specify `OWNER`. +With `OWNER`, you must be able to `SET ROLE` to the new owner, i.e., be a member of that role with the `SET` option. + +## ALTER DATABASE + +`ALTER DATABASE` renames a database, changes its owner, or sets default values for configuration parameters. + +```text +ALTER DATABASE RENAME TO +ALTER DATABASE OWNER TO { | CURRENT_USER | CURRENT_ROLE | SESSION_USER } +ALTER DATABASE SET { TO | = } { | DEFAULT } +ALTER DATABASE RESET { | ALL } ``` -Note that this does not affect currently running sessions, for this use an explicit `SET`. -[Role defaults](/docs/references/objects/roles#session-defaults) for the same setting, override this default. +### Rename a database -`RESET` removes defaults again: +You cannot rename a database while any session, including your own, is connected to it: ```sql -alter database newdb reset statement_timeout; -alter database newdb reset all; +CREATE DATABASE forestry; +ALTER DATABASE forestry RENAME TO forestry_archive; ``` -## Permissions +### Set a default for a [configuration parameter](/docs/references/sessions/settings) + +The default applies to every new session that connects to the database. +It does not affect sessions that are already running. Use an explicit `SET` for those. +[Role defaults](/docs/references/objects/roles#session-defaults) for the same parameter override the database default: + +```sql +CREATE DATABASE forestry; +ALTER DATABASE forestry SET search_path = 'inventory'; +``` + +```sql +SELECT setconfig FROM pg_db_role_setting; +``` + +```text + setconfig +------------------------- + {search_path=inventory} +``` + +Remove the default again with `RESET`: + +```sql +ALTER DATABASE forestry RESET search_path; +ALTER DATABASE forestry RESET ALL; +``` + +### Permissions + +To alter a database, you must own it or be a superuser. +In addition: + +* `RENAME TO` requires the `CREATEDB` attribute. +* `OWNER TO` requires that you have the `CREATEDB` attribute and are a member of the new owner role with the `SET` option. + +Superusers can always rename a database and change its owner. + +## DROP DATABASE + +`DROP DATABASE` removes a database and all objects in it. +This cannot be undone after the transaction executing it commited. + +```text +DROP DATABASE [ IF EXISTS ] +``` + +```sql +CREATE DATABASE forestry; +DROP DATABASE forestry; +``` + +Use `IF EXISTS` to avoid an error if the database does not exist: + +```sql +DROP DATABASE IF EXISTS forestry; +``` + +You cannot drop the database you are connected to, or a database that other sessions are still connected to. + +### Permissions + +To drop a database, you must own it or be a superuser. + +## Database privileges + +Database privileges control who can connect to a database and what they can create in it. + +| Privilege | Allows | +|---------------------|--------------------------------------------------------------------------------| +| `CONNECT` | Connecting to the database. | +| `CREATE` | Creating schemas in the database. | +| `TEMPORARY`, `TEMP` | Creating temporary tables and other temporary objects in the database. | +| `ALL [PRIVILEGES]` | All of the above. | + +By default, every role can connect to a database and create temporary objects in it, because `PUBLIC` holds `CONNECT` and `TEMPORARY`. +Only the owner can create schemas in it. + +{{< callout type="info" >}} +`GRANT` and `REVOKE` require an enterprise license. +{{< /callout >}} + +Restrict a database to specific roles by revoking `CONNECT` from `PUBLIC` and granting it again to individual roles: + +```sql +CREATE DATABASE forestry; +CREATE ROLE forester LOGIN; + +REVOKE CONNECT ON DATABASE forestry FROM PUBLIC; +GRANT CONNECT ON DATABASE forestry TO forester; +``` + +Other roles now fail to connect with `FATAL: user not permitted to connect to database`. + +Without an enterprise license, CedarDB still enforces privileges that were granted earlier. + +For the full `GRANT` and `REVOKE` syntax, see [Roles](/docs/references/objects/roles). + +## PostgreSQL Differences -To create a database, you need to have superuser or `createdb` permissions. -To change the session defaults of a database, you need to be its owner or a superuser. +* CedarDB does not support the `LOCALE`, `LC_COLLATE`, `LC_CTYPE`, `LOCALE_PROVIDER`, `ICU_LOCALE`, `COLLATION_VERSION`, `STRATEGY`, `OID`, `TABLESPACE`, `CONNECTION LIMIT`, `IS_TEMPLATE`, and `ALLOW_CONNECTIONS` options of `CREATE DATABASE`. + Use the [`COLLATE`](/docs/references/datatypes/text/#unicode-collation-support) specifier for per-column collations. +* `TEMPLATE` only accepts `template0`, `template1`, and `DEFAULT`. CedarDB has no template databases, and new databases are always empty. Other template names fail with `database templates not supported`. +* `ENCODING` rejects encodings other than UTF-8, such as `LATIN1`. +* `ALTER DATABASE` does not support `SET TABLESPACE`, `SET FROM CURRENT`, `REFRESH COLLATION VERSION`, or the `WITH` options `CONNECTION LIMIT`, `ALLOW_CONNECTIONS`, and `IS_TEMPLATE`. +* Per-role defaults for a single database (`ALTER ROLE ... IN DATABASE ... SET`) are not supported. +* `DROP DATABASE` does not support `WITH (FORCE)`. +* `CREATE DATABASE` and `DROP DATABASE` are allowed inside a transaction block. A `ROLLBACK` undoes them. +* `COMMENT ON DATABASE` is not supported. From a5f18a5e649e5e8e15d3d7acaecaaf3fc466f2cb Mon Sep 17 00:00:00 2001 From: Christian Winter Date: Wed, 7 Oct 2026 16:31:35 +0200 Subject: [PATCH 03/21] Update docs for schemas --- content/compatibility/sql_features.md | 3 +- content/references/objects/schemas.md | 194 ++++++++++++++++++++++++-- 2 files changed, 181 insertions(+), 16 deletions(-) diff --git a/content/compatibility/sql_features.md b/content/compatibility/sql_features.md index d3c5961..2c56cac 100644 --- a/content/compatibility/sql_features.md +++ b/content/compatibility/sql_features.md @@ -105,7 +105,8 @@ the [system table compatibility](../system_table) page. | **Feature** | **Support State** | **Details** | |------------------------|-------------------|------------------------------------------------------------------------------------------------------------------------------| | CREATE SCHEMA | Yes | [Documentation](/docs/references/objects/schemas/) | -| DROP SCHEMA | Yes | Only if the schema is empty | +| ALTER SCHEMA | Yes | [Documentation](/docs/references/objects/schemas/#alter-schema) | +| DROP SCHEMA | Yes | [Documentation](/docs/references/objects/schemas/#drop-schema) | | search_path | Yes | [Documentation](/docs/references/objects/schemas/#using-schemas) | | Table Inheritance | No | | | Table Partitioning | Partial | Only hash partitioning, partitions are created automatically. [Documentation](/docs/references/objects/tables/#partitioning) | diff --git a/content/references/objects/schemas.md b/content/references/objects/schemas.md index d3b1e12..4cb7c08 100644 --- a/content/references/objects/schemas.md +++ b/content/references/objects/schemas.md @@ -4,33 +4,197 @@ linkTitle: "Schemas" weight: 40 --- -Create Schema allows creating a new schema within a database. -Schemas are essentially namespaces to avoid name collisions between objects in the database. +A schema is a namespace inside a database. +Tables, views, sequences, functions, and types always belong to exactly one schema. +Objects in different schemas can share a name without clashing. -Usage example: +```sql +CREATE SCHEMA inventory; +CREATE SCHEMA sales; + +CREATE TABLE inventory.trees (id integer, species text); +CREATE TABLE sales.trees (id integer, price numeric); +``` + +Every new database contains the schema `public`, where objects end up if you don't specify a schema. +The system schemas `pg_catalog` and `information_schema` contain the [system tables](/docs/compatibility/system_table). + +## Using Schemas + +You can always refer to an object by its schema-qualified name, such as `inventory.trees`. +For unqualified names, CedarDB searches the schemas listed in the [`search_path` setting](/docs/references/sessions/settings), in order. +It creates new unqualified objects in the first schema of the list that exists. ```sql -create schema sales; -create schema sorting; +SET search_path = inventory, public; + +SELECT * FROM trees; -- reads inventory.trees +CREATE TABLE saplings (id int); -- creates inventory.saplings ``` -Within these distinct schemas, you can create tables with now no longer clashing names: +The default `search_path` is `"$user", public`. +`"$user"` stands for a schema with the same name as the current role, if it exists. +`current_schema()` returns the schema CedarDB creates new objects in, and `current_schemas(true)` returns the effective search path including `pg_catalog`. + +If none of the schemas in the search path exists, creating an unqualified object fails. + +Each session that creates temporary objects gets its own temporary schema `pg_temp_`, which CedarDB searches before the schemas in `search_path`. +The name `pg_temp` always refers to the temporary schema of the current session (see [Temporary tables](/docs/references/objects/tables#temporary-tables)). + +## CREATE SCHEMA + +`CREATE SCHEMA` creates a new, empty schema in the current database. + +```text +CREATE SCHEMA [ IF NOT EXISTS ] + [ AUTHORIZATION { | CURRENT_USER | CURRENT_ROLE | SESSION_USER } ] +``` + +| Parameter | Description | +|-----------------|-----------------------------------------------------------------------------------------| +| `IF NOT EXISTS` | Do not throw an error if a schema with the same name already exists. | +| `` | The name of the schema. Names starting with `pg_` are reserved for system schemas. | +| `AUTHORIZATION` | The role that owns the schema. Defaults to the current role. | + +Create a schema that belongs to another role: ```sql -create table sales.orders(...); -create table sorting.orders(...); +CREATE ROLE forester LOGIN; +CREATE SCHEMA forestry AUTHORIZATION forester; ``` -## Using Schemas +```sql +SELECT nspname, nspowner::regrole FROM pg_namespace WHERE nspname = 'forestry'; +``` + +```text + nspname | nspowner +----------+---------- + forestry | forester +``` + +### Permissions -You can always refer to tables with their fully schema-qualified name. -However, if you only operate in certain schemas, you can explicitly [set the `search_path` setting](/docs/references/sessions/settings): +To create a schema, you need the `CREATE` privilege on the current database. +The owner of a database has this privilege by default. +With `AUTHORIZATION`, you must also be able to `SET ROLE` to the new owner, i.e., be a member of that role (see [Roles](/docs/references/objects/roles)). +Superusers can create any schema. + +## ALTER SCHEMA + +`ALTER SCHEMA` renames a schema or changes its owner. + +```text +ALTER SCHEMA RENAME TO +ALTER SCHEMA OWNER TO { | CURRENT_USER | CURRENT_ROLE | SESSION_USER } +``` ```sql -set search_path = 'sales'; -select * from orders; -- now equivalent to "sales.orders" +CREATE SCHEMA inventory; +ALTER SCHEMA inventory RENAME TO stock; ``` -## Permissions +Objects inside the schema move with it. +Queries that use the old name stop working. +As with `CREATE SCHEMA`, the new name must not start with `pg_`. + +```sql +CREATE ROLE forester LOGIN; +ALTER SCHEMA stock OWNER TO forester; +``` + +### Permissions + +To alter a schema, you must own it or be a superuser. +Members of the owning role count as owners. +In addition: + +* `RENAME TO` requires the `CREATE` privilege on the current database. +* `OWNER TO` requires that you can `SET ROLE` to the new owner, and that the new owner has the `CREATE` privilege on the current database. + +## DROP SCHEMA + +`DROP SCHEMA` removes a schema. + +```text +DROP SCHEMA [ IF EXISTS ] [, ...] [ CASCADE | RESTRICT ] +``` + +```sql +CREATE SCHEMA inventory; +DROP SCHEMA inventory; +``` + +By default (`RESTRICT`), you can only drop an empty schema. +Use `CASCADE` to also drop all objects in the schema: + +```sql +CREATE SCHEMA inventory; +CREATE TABLE inventory.trees (id integer, species text); + +DROP SCHEMA inventory; +-- ERROR: cannot drop schema inventory because other objects depend on it +-- DETAIL: table trees depends on it + +DROP SCHEMA inventory CASCADE; +``` + +Use `IF EXISTS` to avoid an error if the schema does not exist. + +### Permissions + +To drop a schema, you must own it, be a member of the owning role, or be a superuser. +The owner of a schema can drop it with `CASCADE`, even if it contains objects owned by other roles. +The owner of a schema can also drop any object in it. + +## Schema privileges + +Schema privileges control who can use and create objects in a schema. + +| Privilege | Allows | +|--------------------|------------------------------------------------------------------------------------------------| +| `USAGE` | Referring to objects in the schema. Each object additionally checks its own privileges. | +| `CREATE` | Creating objects in the schema. | +| `ALL [PRIVILEGES]` | Both of the above. | + +The owner of a schema has all privileges on it. +Other roles have no privileges on a new schema. + +The `public` schema is owned by the built-in role `pg_database_owner`, which always stands for the owner of the current database. +By default, every role has `USAGE` on `public`, but only the database owner can create objects in it. + +```sql +SELECT nspacl FROM pg_namespace WHERE nspname = 'public'; +``` + +```text + nspacl +--------------------------------------------------------------- + {=U/pg_database_owner,pg_database_owner=UC/pg_database_owner} +``` + +{{< callout type="info" >}} +Granting and revoking privileges on schemas requires an enterprise license. +{{< /callout >}} + +Let a role read tables in a schema. +The role needs both `USAGE` on the schema and `SELECT` on the table: + +```sql +CREATE SCHEMA inventory; +CREATE TABLE inventory.trees (id integer, species text); +CREATE ROLE forester LOGIN; + +GRANT USAGE ON SCHEMA inventory TO forester; +GRANT SELECT ON inventory.trees TO forester; +``` + +Without `USAGE`, queries fail with `permission denied for schema 'inventory'`, even if the role has `SELECT` on the table. + +For the full `GRANT` and `REVOKE` syntax, see [Roles](/docs/references/objects/roles). + +## PostgreSQL Differences -To create a schema, you need to have superuser or `createdb` permissions. +* `CREATE SCHEMA` does not support schema elements, such as `CREATE SCHEMA s CREATE TABLE ...`. Create the objects with separate statements. +* `CREATE SCHEMA AUTHORIZATION ` without a schema name is not supported. Specify the schema name. +* `COMMENT ON SCHEMA` is not supported. From 62a7e8f95015d683da831d18c64a2b32046bf88a Mon Sep 17 00:00:00 2001 From: Christian Winter Date: Wed, 7 Oct 2026 16:31:36 +0200 Subject: [PATCH 04/21] Update docs for roles --- content/compatibility/sql_features.md | 24 +- content/compatibility/system_table.md | 2 +- content/references/objects/roles.md | 390 +++++++++++++++++++++++--- 3 files changed, 361 insertions(+), 55 deletions(-) diff --git a/content/compatibility/sql_features.md b/content/compatibility/sql_features.md index 2c56cac..32a96a8 100644 --- a/content/compatibility/sql_features.md +++ b/content/compatibility/sql_features.md @@ -76,16 +76,20 @@ the [system table compatibility](../system_table) page. ### Privileges -| **Feature** | **Support State** | **Details** | -|-----------------------|-------------------|--------------------------------------------------| -| CREATE ROLE | Yes | [Documentation](/docs/references/objects/roles) | -| OWNER TO | Yes | | -| ALTER ROLE | Yes | [Documentation](/docs/references/objects/roles) | -| GRANT | Yes | Requires an enterprise license | -| REVOKE | Yes | Requires an enterprise license | -| SET ROLE | Yes | Requires an enterprise license | -| INHERIT | Yes | [Documentation](/docs/references/objects/roles/) | -| Row Security Policies | Yes | Requires an enterprise license | +| **Feature** | **Support State** | **Details** | +|---------------------------|-------------------|------------------------------------------------------------| +| CREATE ROLE | Yes | [Documentation](/docs/references/objects/roles) | +| OWNER TO | Yes | | +| ALTER ROLE | Yes | [Documentation](/docs/references/objects/roles) | +| DROP ROLE | Yes | [Documentation](/docs/references/objects/roles/#drop-role) | +| GRANT | Yes | Requires an enterprise license | +| REVOKE | Yes | Requires an enterprise license | +| SET ROLE | Yes | [Documentation](/docs/references/objects/roles/#set-role) | +| SET SESSION AUTHORIZATION | Yes | [Documentation](/docs/references/objects/roles/#set-role) | +| INHERIT | Yes | [Documentation](/docs/references/objects/roles/) | +| REASSIGN OWNED | No | | +| DROP OWNED | No | | +| Row Security Policies | Yes | Requires an enterprise license | ### Indexes diff --git a/content/compatibility/system_table.md b/content/compatibility/system_table.md index 7341419..cdb4d5e 100644 --- a/content/compatibility/system_table.md +++ b/content/compatibility/system_table.md @@ -36,7 +36,7 @@ built-in [system views](#system-views), or the SQL-standard [information schema] | [pg_attrdef](https://www.postgresql.org/docs/current/catalog-pg-attrdef.html) | 🟢 | Stores column default values. | | [pg_attribute](https://www.postgresql.org/docs/current/catalog-pg-attribute.html) | 🟢 | Contains information about table columns. | | [pg_authid](https://www.postgresql.org/docs/current/catalog-pg-authid.html) | 🟢 | Stores information about database roles. | -| [pg_auth_members](https://www.postgresql.org/docs/current/catalog-pg-auth-members.html) | 🟡 | Tracks role memberships. | +| [pg_auth_members](https://www.postgresql.org/docs/current/catalog-pg-auth-members.html) | 🟢 | Tracks role memberships. | | [pg_cast](https://www.postgresql.org/docs/current/catalog-pg-cast.html) | 🟡 | Contains information about type casts. | | [pg_class](https://www.postgresql.org/docs/current/catalog-pg-class.html) | 🟢 | Stores information about tables, indexes, sequences, and other relations. | | [pg_collation](https://www.postgresql.org/docs/current/catalog-pg-collation.html) | 🟢 | Contains information about collations. | diff --git a/content/references/objects/roles.md b/content/references/objects/roles.md index c9bc674..a9a376b 100644 --- a/content/references/objects/roles.md +++ b/content/references/objects/roles.md @@ -4,85 +4,387 @@ linkTitle: "Roles" weight: 60 --- -## CREATE ROLE +A role is a database identity that can own objects and hold privileges. +Roles with the `LOGIN` attribute act as *users* that can connect to CedarDB. +Roles without `LOGIN` usually act as *groups* that bundle privileges for their members. +Roles are shared by all databases on a server. -Create role allows adding new database *roles*. -A role in SQL is an abstraction over *users* (which can log in) and *groups* (which bundle permissions). +```sql +-- A group role that bundles read access +CREATE ROLE analysts; -Usage example: +-- A user that can log in and is a member of the group (IN ROLE requires an enterprise license) +CREATE ROLE maple LOGIN PASSWORD 'Leaf!2024x' IN ROLE analysts; +``` ```sql --- Create a new user -create role dbuser login with password 'CorrectHorseBatteryStaple'; --- Create user implies a "login" role -create user admin with createdb createrole password 'CorrectHorseBatteryStaple'; +SELECT rolname, rolcanlogin FROM pg_roles WHERE rolname IN ('analysts', 'maple'); +``` + +```text + rolname | rolcanlogin +----------+------------- + analysts | f + maple | t +``` + +## CREATE ROLE + +`CREATE ROLE` adds a new role. +`CREATE USER` is the same, but implies `LOGIN`. +`CREATE GROUP` is an alias for `CREATE ROLE`. + +```text +CREATE ROLE [ [ WITH ]