From 9e16a68ebc5a7a875e141d2fb9495a262d95992c Mon Sep 17 00:00:00 2001 From: Eric Harmeling Date: Wed, 20 Oct 2021 15:15:29 -0400 Subject: [PATCH 1/6] ON UPDATE expressions --- v20.2/add-column.md | 6 ++-- v21.1/add-column.md | 6 ++-- v21.2/add-column.md | 80 ++++++++++++++++++++++++++++++++++++++++--- v21.2/alter-column.md | 3 +- v21.2/create-table.md | 2 +- 5 files changed, 84 insertions(+), 13 deletions(-) diff --git a/v20.2/add-column.md b/v20.2/add-column.md index e5ca32c8cc6..cf66161a82a 100644 --- a/v20.2/add-column.md +++ b/v20.2/add-column.md @@ -224,7 +224,7 @@ $ cockroach demo bank {% include copy-clipboard.html %} ~~~ sql -> SHOW CREATE TABLE FROM bank; +> SHOW CREATE TABLE bank; ~~~ ~~~ table_name | create_statement @@ -259,7 +259,7 @@ $ cockroach demo bank {% include copy-clipboard.html %} ~~~ sql -> SHOW CREATE TABLE FROM bank; +> SHOW CREATE TABLE bank; ~~~ ~~~ table_name | create_statement @@ -295,7 +295,7 @@ $ cockroach demo bank {% include copy-clipboard.html %} ~~~ sql -> SHOW CREATE TABLE FROM bank; +> SHOW CREATE TABLE bank; ~~~ ~~~ table_name | create_statement diff --git a/v21.1/add-column.md b/v21.1/add-column.md index 7915419a874..e48bf7cc89d 100644 --- a/v21.1/add-column.md +++ b/v21.1/add-column.md @@ -224,7 +224,7 @@ $ cockroach demo bank {% include copy-clipboard.html %} ~~~ sql -> SHOW CREATE TABLE FROM bank; +> SHOW CREATE TABLE bank; ~~~ ~~~ table_name | create_statement @@ -259,7 +259,7 @@ $ cockroach demo bank {% include copy-clipboard.html %} ~~~ sql -> SHOW CREATE TABLE FROM bank; +> SHOW CREATE TABLE bank; ~~~ ~~~ table_name | create_statement @@ -295,7 +295,7 @@ $ cockroach demo bank {% include copy-clipboard.html %} ~~~ sql -> SHOW CREATE TABLE FROM bank; +> SHOW CREATE TABLE bank; ~~~ ~~~ table_name | create_statement diff --git a/v21.2/add-column.md b/v21.2/add-column.md index fb292068c7a..041f2caef51 100644 --- a/v21.2/add-column.md +++ b/v21.2/add-column.md @@ -4,7 +4,7 @@ summary: Use the ADD COLUMN statement to add columns to tables. toc: true --- -The `ADD COLUMN` [statement](sql-statements.html) is part of `ALTER TABLE` and adds columns to tables. +`ADD COLUMN` is a subcommand of [`ALTER TABLE`](alter-table.html). Use `ADD COLUMN` to add columns to existing tables. {% include {{ page.version.version }}/sql/combine-alter-table-commands.md %} @@ -26,7 +26,27 @@ The user must have the `CREATE` [privilege](authorization.html#assign-privileges `table_name` | The name of the table to which you want to add the column. `column_name` | The name of the column you want to add. The column name must follow these [identifier rules](keywords-and-identifiers.html#identifiers) and must be unique within the table but can have the same name as indexes or constraints. `typename` | The [data type](data-types.html) of the new column. - `col_qualification` | An optional list of column definitions, which may include [column-level constraints](constraints.html), [collation](collate.html), or [column family assignments](column-families.html).

If the column family is not specified, the column will be added to the first column family. For more information about how column families are assigned, see [Column Families](column-families.html#assign-column-families-when-adding-columns). + `col_qualification` | An optional list of [column qualifications](#column-qualifications). + +## Column qualifications + +CockroachDB supports the following column qualifications: + +- [Column-level constraints](constraints.html) +- [Collations](collate.html) +- [Column family assignments](column-families.html) +- New in v21.2: [`ON UPDATE` expressions](#on-update-expressions) + +### ON UPDATE expressions + +New in v21.2: `ON UPDATE` expressions set a row value for a particular column when any other value in the row is updated. + +Note the following limitations of `ON UPDATE` expressions: + +- You cannot add a [foreign key constraint](foreign-key.html) and an `ON UPDATE` expression to the same column. +- Values populated by [`DEFAULT` constraints](default-value.html) do not trigger an `ON UPDATE` change. + +For an example of `ON UPDATE`, see [Add a column with an `ON UPDATE` expression](#add-a-column-with-an-on-update-expression). ## Viewing schema changes @@ -225,7 +245,7 @@ $ cockroach demo bank {% include copy-clipboard.html %} ~~~ sql -> SHOW CREATE TABLE FROM bank; +> SHOW CREATE TABLE bank; ~~~ ~~~ table_name | create_statement @@ -260,7 +280,7 @@ $ cockroach demo bank {% include copy-clipboard.html %} ~~~ sql -> SHOW CREATE TABLE FROM bank; +> SHOW CREATE TABLE bank; ~~~ ~~~ table_name | create_statement @@ -296,7 +316,7 @@ $ cockroach demo bank {% include copy-clipboard.html %} ~~~ sql -> SHOW CREATE TABLE FROM bank; +> SHOW CREATE TABLE bank; ~~~ ~~~ table_name | create_statement @@ -325,6 +345,56 @@ $ cockroach demo bank (1 row) ~~~ +### Add a column with an `ON UPDATE` expression + +New in v21.2: `ON UPDATE` expressions set the value for a column when other values in a row are updated. + +For example, suppose you add a new column to the `bank` table: + +{% include copy-clipboard.html %} +~~~ sql +> ALTER TABLE bank ADD COLUMN last_updated TIMESTAMPTZ DEFAULT now() ON UPDATE now(); +~~~ + +{% include copy-clipboard.html %} +~~~ sql +> SELECT id, balance, last_updated FROM bank LIMIT 5; +~~~ + +~~~ + id | balance | last_updated +-----+---------+-------------------------------- + 0 | 0 | 2021-10-21 17:03:41.213557+00 + 1 | 0 | 2021-10-21 17:03:41.213557+00 + 2 | 0 | 2021-10-21 17:03:41.213557+00 + 3 | 0 | 2021-10-21 17:03:41.213557+00 + 4 | 0 | 2021-10-21 17:03:41.213557+00 +(5 rows) +~~~ + +When any value in any row of the `bank` table is updated, CockroachDB re-evaluates the `ON UPDATE` expression and updates the `last_updated` column with the result. + +{% include copy-clipboard.html %} +~~~ sql +> UPDATE bank SET balance = 500 WHERE id = 0; +~~~ + +{% include copy-clipboard.html %} +~~~ sql +> SELECT id, balance, last_updated FROM bank LIMIT 5; +~~~ + +~~~ + id | balance | last_updated +-----+---------+-------------------------------- + 0 | 500 | 2021-10-21 17:06:42.211261+00 + 1 | 0 | 2021-10-21 17:03:41.213557+00 + 2 | 0 | 2021-10-21 17:03:41.213557+00 + 3 | 0 | 2021-10-21 17:03:41.213557+00 + 4 | 0 | 2021-10-21 17:03:41.213557+00 +(5 rows) +~~~ + ## See also - [`ALTER TABLE`](alter-table.html) diff --git a/v21.2/alter-column.md b/v21.2/alter-column.md index e1bb938f77e..a7d6cc9c1d8 100644 --- a/v21.2/alter-column.md +++ b/v21.2/alter-column.md @@ -4,10 +4,11 @@ summary: Use the ALTER COLUMN statement to set, change, or drop a column's DEFAU toc: true --- -The `ALTER COLUMN` [statement](sql-statements.html) is part of `ALTER TABLE` and can be used to: +`ALTER COLUMN` is a subcommand of [`ALTER TABLE`](alter-table.html). You can use `ALTER COLUMN` to do the following: - Set, change, or drop a column's [`DEFAULT` constraint](default-value.html). - Set or drop a column's [`NOT NULL` constraint](not-null.html). +- New in v21.2: Set, change, or drop an [`ON UPDATE` expression](add-column.html#on-update-expressions). - Change a column's [data type](data-types.html). {{site.data.alerts.callout_info}} diff --git a/v21.2/create-table.md b/v21.2/create-table.md index 31e03bc4afb..88fb1354c97 100644 --- a/v21.2/create-table.md +++ b/v21.2/create-table.md @@ -99,7 +99,7 @@ Parameter | Description `opt_persistence_temp_table` | Defines the table as a session-scoped temporary table. For more information, see [Temporary Tables](temporary-tables.html).

Note that the `LOCAL`, `GLOBAL`, and `UNLOGGED` options are no-ops, allowed by the parser for PostgresSQL compatibility.

**Support for temporary tables is [experimental](experimental-features.html#temporary-objects)**. `IF NOT EXISTS` | Create a new table only if a table of the same name does not already exist in the database; if one does exist, do not return an error.

Note that `IF NOT EXISTS` checks the table name only; it does not check if an existing table has the same columns, indexes, constraints, etc., of the new table. `table_name` | The name of the table to create, which must be unique within its database and follow these [identifier rules](keywords-and-identifiers.html#identifiers). When the parent database is not set as the default, the name must be formatted as `database.name`.

The [`UPSERT`](upsert.html) and [`INSERT ON CONFLICT`](insert.html) statements use a temporary table called `excluded` to handle uniqueness conflicts during execution. It's therefore not recommended to use the name `excluded` for any of your tables. -`column_def` | A comma-separated list of column definitions. Each column requires a [name/identifier](keywords-and-identifiers.html#identifiers) and [data type](data-types.html); optionally, a [column-level constraint](constraints.html) or other column qualification (e.g., [computed columns](computed-columns.html)) can be specified. Column names must be unique within the table but can have the same name as indexes or constraints.

Any `PRIMARY KEY`, `UNIQUE`, and `CHECK` [constraints](constraints.html) defined at the column level are moved to the table-level as part of the table's creation. Use the [`SHOW CREATE`](show-create.html) statement to view them at the table level. +`column_def` | A comma-separated list of column definitions. Each column requires a [name/identifier](keywords-and-identifiers.html#identifiers) and [data type](data-types.html). Column names must be unique within the table but can have the same name as indexes or constraints.

You can optionally specify a [column qualification](add-column.html#column-constraints) (e.g., a [column-level constraint](constraints.html)). Any `PRIMARY KEY`, `UNIQUE`, and `CHECK` [constraints](constraints.html) defined at the column level are moved to the table-level as part of the table's creation. Use the [`SHOW CREATE`](show-create.html) statement to view them at the table level. `index_def` | An optional, comma-separated list of [index definitions](indexes.html). For each index, the column(s) to index must be specified; optionally, a name can be specified. Index names must be unique within the table and follow these [identifier rules](keywords-and-identifiers.html#identifiers). See the [Create a Table with Secondary Indexes and Inverted Indexes](#create-a-table-with-secondary-and-inverted-indexes) example below.

To enable [hash-sharded indexes](hash-sharded-indexes.html), set the `experimental_enable_hash_sharded_indexes` [session variable](set-vars.html) to `on`. For examples, see [Create a table with hash-sharded indexes](#create-a-table-with-a-hash-sharded-primary-index) below.

The [`CREATE INDEX`](create-index.html) statement can be used to create an index separate from table creation. `family_def` | An optional, comma-separated list of [column family definitions](column-families.html). Column family names must be unique within the table but can have the same name as columns, constraints, or indexes.

A column family is a group of columns that are stored as a single key-value pair in the underlying key-value store. CockroachDB automatically groups columns into families to ensure efficient storage and performance. However, there are cases when you may want to manually assign columns to families. For more details, see [Column Families](column-families.html). `table_constraint` | An optional, comma-separated list of [table-level constraints](constraints.html). Constraint names must be unique within the table but can have the same name as columns, column families, or indexes. From d85b58351f63471e9ecbb7762af2c3e123b7c149 Mon Sep 17 00:00:00 2001 From: Eric Harmeling Date: Thu, 21 Oct 2021 13:53:21 -0400 Subject: [PATCH 2/6] link fix --- v21.2/create-table.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/v21.2/create-table.md b/v21.2/create-table.md index 88fb1354c97..0dfccd38ad6 100644 --- a/v21.2/create-table.md +++ b/v21.2/create-table.md @@ -99,7 +99,7 @@ Parameter | Description `opt_persistence_temp_table` | Defines the table as a session-scoped temporary table. For more information, see [Temporary Tables](temporary-tables.html).

Note that the `LOCAL`, `GLOBAL`, and `UNLOGGED` options are no-ops, allowed by the parser for PostgresSQL compatibility.

**Support for temporary tables is [experimental](experimental-features.html#temporary-objects)**. `IF NOT EXISTS` | Create a new table only if a table of the same name does not already exist in the database; if one does exist, do not return an error.

Note that `IF NOT EXISTS` checks the table name only; it does not check if an existing table has the same columns, indexes, constraints, etc., of the new table. `table_name` | The name of the table to create, which must be unique within its database and follow these [identifier rules](keywords-and-identifiers.html#identifiers). When the parent database is not set as the default, the name must be formatted as `database.name`.

The [`UPSERT`](upsert.html) and [`INSERT ON CONFLICT`](insert.html) statements use a temporary table called `excluded` to handle uniqueness conflicts during execution. It's therefore not recommended to use the name `excluded` for any of your tables. -`column_def` | A comma-separated list of column definitions. Each column requires a [name/identifier](keywords-and-identifiers.html#identifiers) and [data type](data-types.html). Column names must be unique within the table but can have the same name as indexes or constraints.

You can optionally specify a [column qualification](add-column.html#column-constraints) (e.g., a [column-level constraint](constraints.html)). Any `PRIMARY KEY`, `UNIQUE`, and `CHECK` [constraints](constraints.html) defined at the column level are moved to the table-level as part of the table's creation. Use the [`SHOW CREATE`](show-create.html) statement to view them at the table level. +`column_def` | A comma-separated list of column definitions. Each column requires a [name/identifier](keywords-and-identifiers.html#identifiers) and [data type](data-types.html). Column names must be unique within the table but can have the same name as indexes or constraints.

You can optionally specify a [column qualification](add-column.html#column-qualifications) (e.g., a [column-level constraint](constraints.html)). Any `PRIMARY KEY`, `UNIQUE`, and `CHECK` [constraints](constraints.html) defined at the column level are moved to the table-level as part of the table's creation. Use the [`SHOW CREATE`](show-create.html) statement to view them at the table level. `index_def` | An optional, comma-separated list of [index definitions](indexes.html). For each index, the column(s) to index must be specified; optionally, a name can be specified. Index names must be unique within the table and follow these [identifier rules](keywords-and-identifiers.html#identifiers). See the [Create a Table with Secondary Indexes and Inverted Indexes](#create-a-table-with-secondary-and-inverted-indexes) example below.

To enable [hash-sharded indexes](hash-sharded-indexes.html), set the `experimental_enable_hash_sharded_indexes` [session variable](set-vars.html) to `on`. For examples, see [Create a table with hash-sharded indexes](#create-a-table-with-a-hash-sharded-primary-index) below.

The [`CREATE INDEX`](create-index.html) statement can be used to create an index separate from table creation. `family_def` | An optional, comma-separated list of [column family definitions](column-families.html). Column family names must be unique within the table but can have the same name as columns, constraints, or indexes.

A column family is a group of columns that are stored as a single key-value pair in the underlying key-value store. CockroachDB automatically groups columns into families to ensure efficient storage and performance. However, there are cases when you may want to manually assign columns to families. For more details, see [Column Families](column-families.html). `table_constraint` | An optional, comma-separated list of [table-level constraints](constraints.html). Constraint names must be unique within the table but can have the same name as columns, column families, or indexes. From a8ce763603cdac930a1eaafc6c682bcca946fbc4 Mon Sep 17 00:00:00 2001 From: Eric Harmeling Date: Tue, 26 Oct 2021 12:46:54 -0400 Subject: [PATCH 3/6] Added ON UPDATE to computed column considerations --- v21.2/computed-columns.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/v21.2/computed-columns.md b/v21.2/computed-columns.md index 2c7ff34ad3e..dd9eeeaf41d 100644 --- a/v21.2/computed-columns.md +++ b/v21.2/computed-columns.md @@ -21,7 +21,7 @@ Computed columns: - Cannot be used to generate other computed columns. - Cannot reference a [foreign key](foreign-key.html). - Behave like any other column, with the exception that they cannot be written to directly. -- Are mutually exclusive with [`DEFAULT`](default-value.html). +- Are mutually exclusive with [`DEFAULT` constraints](default-value.html) and [`ON UPDATE` expressions](add-column.html#on-update-expressions). Virtual computed columns: From 3a9c18b89636f247d2b907be95deb64132bf45a1 Mon Sep 17 00:00:00 2001 From: Eric Harmeling Date: Thu, 28 Oct 2021 11:16:00 -0400 Subject: [PATCH 4/6] rafiss feedback --- v21.1/default-value.md | 4 +++- v21.2/add-column.md | 3 ++- v21.2/computed-columns.md | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/v21.1/default-value.md b/v21.1/default-value.md index 183bb292e9d..63ff242be9f 100644 --- a/v21.1/default-value.md +++ b/v21.1/default-value.md @@ -20,7 +20,9 @@ You can only apply the `DEFAULT` value constraint to individual columns. You can also add the `DEFAULT` value constraint to an existing table through [`ALTER COLUMN`](alter-column.html#set-or-change-a-default-value). {{site.data.alerts.end}} -
{% include {{ page.version.version }}/sql/generated/diagrams/default_value_column_level.html %} +
+{% include {{ page.version.version }}/sql/generated/diagrams/default_value_column_level.html %} +
Parameter | Description -----------|------------- diff --git a/v21.2/add-column.md b/v21.2/add-column.md index 041f2caef51..ce33bdc19b0 100644 --- a/v21.2/add-column.md +++ b/v21.2/add-column.md @@ -35,6 +35,7 @@ CockroachDB supports the following column qualifications: - [Column-level constraints](constraints.html) - [Collations](collate.html) - [Column family assignments](column-families.html) +- [`DEFAULT` expressions](default-value.html) - New in v21.2: [`ON UPDATE` expressions](#on-update-expressions) ### ON UPDATE expressions @@ -44,7 +45,7 @@ CockroachDB supports the following column qualifications: Note the following limitations of `ON UPDATE` expressions: - You cannot add a [foreign key constraint](foreign-key.html) and an `ON UPDATE` expression to the same column. -- Values populated by [`DEFAULT` constraints](default-value.html) do not trigger an `ON UPDATE` change. +- Values populated by [`DEFAULT` expressions](default-value.html) do not trigger an `ON UPDATE` change. For an example of `ON UPDATE`, see [Add a column with an `ON UPDATE` expression](#add-a-column-with-an-on-update-expression). diff --git a/v21.2/computed-columns.md b/v21.2/computed-columns.md index dd9eeeaf41d..0141a309835 100644 --- a/v21.2/computed-columns.md +++ b/v21.2/computed-columns.md @@ -21,7 +21,7 @@ Computed columns: - Cannot be used to generate other computed columns. - Cannot reference a [foreign key](foreign-key.html). - Behave like any other column, with the exception that they cannot be written to directly. -- Are mutually exclusive with [`DEFAULT` constraints](default-value.html) and [`ON UPDATE` expressions](add-column.html#on-update-expressions). +- Are mutually exclusive with [`DEFAULT`](default-value.html) and [`ON UPDATE`](add-column.html#on-update-expressions) expressions. Virtual computed columns: From f564e2bd40099833c3ca04f80d0ae4d1c18cef99 Mon Sep 17 00:00:00 2001 From: Eric Harmeling Date: Tue, 2 Nov 2021 16:45:19 -0400 Subject: [PATCH 5/6] pawalt feedback --- v21.2/add-column.md | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/v21.2/add-column.md b/v21.2/add-column.md index ce33bdc19b0..ccf25cfcc9d 100644 --- a/v21.2/add-column.md +++ b/v21.2/add-column.md @@ -40,12 +40,21 @@ CockroachDB supports the following column qualifications: ### ON UPDATE expressions -New in v21.2: `ON UPDATE` expressions set a row value for a particular column when any other value in the row is updated. +New in v21.2: `ON UPDATE` expressions update column values in the following cases: + +- An [`UPDATE`](update.html) or [`UPSERT`](upsert.html) statement modifies a different column value in the same row. +- An `ON UPDATE CASCADE` expression on a different column modifies an existing value in the same row. + +`ON UPDATE` expressions **do not** update column values in the following cases: + +- An `UPDATE` or `UPSERT` statement directly modifies the value of a column with an `ON UPDATE` expression. +- An `UPSERT` statement creates a new row. +- A new column is backfilled with values (e.g., by a `DEFAULT` expression). Note the following limitations of `ON UPDATE` expressions: +- `ON UPDATE` expressions allow context-dependent expressions, but not expressions that reference other columns. For example, the `current_timestamp()` [built-in function](functions-and-operators.html) is allowed, but `CONCAT(, )` is not. - You cannot add a [foreign key constraint](foreign-key.html) and an `ON UPDATE` expression to the same column. -- Values populated by [`DEFAULT` expressions](default-value.html) do not trigger an `ON UPDATE` change. For an example of `ON UPDATE`, see [Add a column with an `ON UPDATE` expression](#add-a-column-with-an-on-update-expression). From 4da219e89eaf1956b47928304b2e20181f72f568 Mon Sep 17 00:00:00 2001 From: Eric Harmeling Date: Wed, 3 Nov 2021 07:40:55 -0400 Subject: [PATCH 6/6] stbof feedback --- v21.2/add-column.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/v21.2/add-column.md b/v21.2/add-column.md index ccf25cfcc9d..d44efe97bc7 100644 --- a/v21.2/add-column.md +++ b/v21.2/add-column.md @@ -38,7 +38,7 @@ CockroachDB supports the following column qualifications: - [`DEFAULT` expressions](default-value.html) - New in v21.2: [`ON UPDATE` expressions](#on-update-expressions) -### ON UPDATE expressions +### `ON UPDATE` expressions New in v21.2: `ON UPDATE` expressions update column values in the following cases: