@@ -233,6 +233,124 @@ CREATE TABLE products (
233
233
</para>
234
234
</sect1>
235
235
236
+ <sect1 id="ddl-generated-columns">
237
+ <title>Generated Columns</title>
238
+
239
+ <indexterm zone="ddl-generated-columns">
240
+ <primary>generated column</primary>
241
+ </indexterm>
242
+
243
+ <para>
244
+ A generated column is a special column that is always computed from other
245
+ columns. Thus, it is for columns what a view is for tables. There are two
246
+ kinds of generated columns: stored and virtual. A stored generated column
247
+ is computed when it is written (inserted or updated) and occupies storage
248
+ as if it were a normal column. A virtual generated column occupies no
249
+ storage and is computed when it is read. Thus, a virtual generated column
250
+ is similar to a view and a stored generated column is similar to a
251
+ materialized view (except that it is always updated automatically).
252
+ PostgreSQL currently implements only stored generated columns.
253
+ </para>
254
+
255
+ <para>
256
+ To create a generated column, use the <literal>GENERATED ALWAYS
257
+ AS</literal> clause in <command>CREATE TABLE</command>, for example:
258
+ <programlisting>
259
+ CREATE TABLE people (
260
+ ...,
261
+ height_cm numeric,
262
+ height_in numeric <emphasis>GENERATED ALWAYS AS (height_cm * 2.54) STORED</emphasis>
263
+ );
264
+ </programlisting>
265
+ The keyword <literal>STORED</literal> must be specified to choose the
266
+ stored kind of generated column. See <xref linkend="sql-createtable"/> for
267
+ more details.
268
+ </para>
269
+
270
+ <para>
271
+ A generated column cannot be written to directly. In
272
+ <command>INSERT</command> or <command>UPDATE</command> commands, a value
273
+ cannot be specified for a generated column, but the keyword
274
+ <literal>DEFAULT</literal> may be specified.
275
+ </para>
276
+
277
+ <para>
278
+ Consider the differences between a column with a default and a generated
279
+ column. The column default is evaluated once when the row is first
280
+ inserted if no other value was provided; a generated column is updated
281
+ whenever the row changes and cannot be overridden. A column default may
282
+ not refer to other columns of the table; a generation expression would
283
+ normally do so. A column default can use volatile functions, for example
284
+ <literal>random()</literal> or functions referring to the current time;
285
+ this is not allowed for generated columns.
286
+ </para>
287
+
288
+ <para>
289
+ Several restrictions apply to the definition of generated columns and
290
+ tables involving generated columns:
291
+
292
+ <itemizedlist>
293
+ <listitem>
294
+ <para>
295
+ The generation expression can only use immutable functions and cannot
296
+ use subqueries or reference anything other than the current row in any
297
+ way.
298
+ </para>
299
+ </listitem>
300
+ <listitem>
301
+ <para>
302
+ A generation expression cannot reference another generated column.
303
+ </para>
304
+ </listitem>
305
+ <listitem>
306
+ <para>
307
+ A generation expression cannot reference a system column, except
308
+ <varname>tableoid</varname>.
309
+ </para>
310
+ </listitem>
311
+ <listitem>
312
+ <para>
313
+ A generated column cannot have a column default or an identity definition.
314
+ </para>
315
+ </listitem>
316
+ <listitem>
317
+ <para>
318
+ A generated column cannot be part of a partition key.
319
+ </para>
320
+ </listitem>
321
+ <listitem>
322
+ <para>
323
+ Foreign tables can have generated columns. See <xref
324
+ linkend="sql-createforeigntable"/> for details.
325
+ </para>
326
+ </listitem>
327
+ </itemizedlist>
328
+ </para>
329
+
330
+ <para>
331
+ Additional considerations apply to the use of generated columns.
332
+ <itemizedlist>
333
+ <listitem>
334
+ <para>
335
+ Generated columns maintain access privileges separately from their
336
+ underlying base columns. So, it is possible to arrange it so that a
337
+ particular role can read from a generated column but not from the
338
+ underlying base columns.
339
+ </para>
340
+ </listitem>
341
+ <listitem>
342
+ <para>
343
+ Generated columns are, conceptually, updated after
344
+ <literal>BEFORE</literal> triggers have run. Therefore, changes made to
345
+ base columns in a <literal>BEFORE</literal> trigger will be reflected in
346
+ generated columns. But conversely, it is not allowed to access
347
+ generated columns in <literal>BEFORE</literal> triggers.
348
+ </para>
349
+ </listitem>
350
+ </itemizedlist>
351
+ </para>
352
+ </sect1>
353
+
236
354
<sect1 id="ddl-constraints">
237
355
<title>Constraints</title>
238
356
0 commit comments