Generated columns

It is possible to define columns whose value is computed by applying a generation expression in the context of the current row. The generation expression can reference the values of other columns.

Table of contents

Generation expressions

Generated columns are defined by providing a generation expression. Providing a data type is optional. It is inferred by the return type of the supplied expression if omitted:

  1. cr> CREATE TABLE computed (
  2. ... dividend double precision,
  3. ... divisor double precision,
  4. ... quotient GENERATED ALWAYS AS (dividend / divisor)
  5. ... );
  6. CREATE OK, 1 row affected (... sec)

See also

For a full syntax description, see CREATE TABLE.

Generated columns are read-only. Their values are computed as needed for every INSERT and UPDATE operation.

For example:

  1. cr> INSERT INTO computed (dividend, divisor)
  2. ... VALUES (1.7, 1.5), (0.0, 10.0);
  3. INSERT OK, 2 rows affected (... sec)

The generated column is now filled with the computed value:

  1. cr> SELECT dividend, divisor, quotient
  2. ... FROM computed
  3. ... ORDER BY quotient;
  4. +----------+---------+--------------------+
  5. | dividend | divisor | quotient |
  6. +----------+---------+--------------------+
  7. | 0.0 | 10.0 | 0.0 |
  8. | 1.7 | 1.5 | 1.1333333333333333 |
  9. +----------+---------+--------------------+
  10. SELECT 2 rows in set (... sec)

The generation expression is evaluated in the context of the current row. This means that you can compute a generated value from the values of base columns in the same row. However, it is not possible to reference other generated columns from within a generation expression.

Note

If the generated expression is deterministic, its value will not be recomputed unless the value of a referenced column has changed.

If values are supplied for generated columns, these values are validated against the result of applying the generation expression:

  1. cr> INSERT INTO computed (dividend, divisor, quotient)
  2. ... VALUES (100.0, 2.0, 12.0);
  3. SQLParseException[Given value 12.0 for generated column quotient does not match calculation (dividend / divisor) = 50.0]

Warning

Supplied values for generated columns are not validated when they are imported using COPY FROM.

Last modified dates

Because CURRENT_TIMESTAMP is non-deterministic, you can use this expression to record a last modified date that is set when the row is first inserted, and subsequently updated every time the row is updated:

  1. cr> CREATE TABLE computed_non_deterministic (
  2. ... id LONG,
  3. ... last_modified TIMESTAMP WITH TIME ZONE GENERATED ALWAYS AS CURRENT_TIMESTAMP
  4. ... );
  5. CREATE OK, 1 row affected (... sec)

Partitioning

Generated columns can be used with the PARTITIONED BY clause to compute the partition column value from existing columns in the table:

  1. cr> CREATE TABLE computed_and_partitioned (
  2. ... huge_cardinality bigint,
  3. ... big_data text,
  4. ... partition_value GENERATED ALWAYS AS (huge_cardinality % 10)
  5. ... ) PARTITIONED BY (partition_value);
  6. CREATE OK, 1 row affected (... sec)

See also

Partitioned tables: Generated columns