/
generated-columns.rst
127 lines (89 loc) · 3.89 KB
/
generated-columns.rst
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
.. highlight:: psql
.. _ddl-generated-columns:
=================
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
:ref:`expression <gloss-expression>` can reference the values of other columns.
.. rubric:: Table of contents
.. contents::
:local:
.. _ddl-generated-columns-expressions:
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::
cr> CREATE TABLE computed (
... dividend double precision,
... divisor double precision,
... quotient GENERATED ALWAYS AS (dividend / divisor)
... );
CREATE OK, 1 row affected (... sec)
.. SEEALSO::
For a full syntax description, see :ref:`sql-create-table`.
Generated columns are read-only. Their values are computed as needed for every
``INSERT`` and ``UPDATE`` operation.
For example::
cr> INSERT INTO computed (dividend, divisor)
... VALUES (1.7, 1.5), (0.0, 10.0);
INSERT OK, 2 rows affected (... sec)
.. Hidden: Refresh::
cr> refresh table computed;
REFRESH OK, 1 row affected (... sec)
The generated column is now filled with the computed value::
cr> SELECT dividend, divisor, quotient
... FROM computed
... ORDER BY quotient;
+----------+---------+--------------------+
| dividend | divisor | quotient |
+----------+---------+--------------------+
| 0.0 | 10.0 | 0.0 |
| 1.7 | 1.5 | 1.1333333333333333 |
+----------+---------+--------------------+
SELECT 2 rows in set (... sec)
The generation expression is :ref:`evaluated <gloss-evaluation>` 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::
cr> INSERT INTO computed (dividend, divisor, quotient)
... VALUES (100.0, 2.0, 12.0);
SQLParseException[Given value 12.0 for generated column quotient does not match calculation (dividend / divisor) = 50.0]
.. _ddl-generated-columns-last-modified:
Last modified dates
===================
Because :ref:`scalar-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::
cr> CREATE TABLE computed_non_deterministic (
... id LONG,
... last_modified TIMESTAMP WITH TIME ZONE GENERATED ALWAYS AS CURRENT_TIMESTAMP
... );
CREATE OK, 1 row affected (... sec)
.. _ddl-generated-columns-partitioning:
Partitioning
============
Generated columns can be used with the :ref:`sql-create-table-partitioned-by`
clause to compute the :ref:`partition column <gloss-partition-column>` value
from existing columns in the table::
cr> CREATE TABLE computed_and_partitioned (
... huge_cardinality bigint,
... big_data text,
... partition_value GENERATED ALWAYS AS (huge_cardinality % 10)
... ) PARTITIONED BY (partition_value);
CREATE OK, 1 row affected (... sec)
.. SEEALSO::
:ref:`Partitioned tables: Generated columns <partitioned-generated>`
.. Hidden: drop tables::
cr> DROP TABLE computed;
DROP OK, 1 row affected (... sec)
cr> DROP TABLE computed_non_deterministic;
DROP OK, 1 row affected (... sec)
cr> DROP TABLE computed_and_partitioned;
DROP OK, 1 row affected (... sec)