insist that parent and child columns
already match as to generation status, but it will not require their
generation expressions to match.
</para>
</listitem>
<listitem>
<para>
Similarly for partitioned tables, if you write a child column
definition without any <literal>GENERATED</literal> clause
in <command>CREATE TABLE ... PARTITION OF</command>, then
its <literal>GENERATED</literal> clause will automatically be copied
from the parent. <command>ALTER TABLE ... ATTACH PARTITION</command>
will insist that parent and child columns already match as to
generation status, but it will not require their generation
expressions to match.
</para>
</listitem>
<listitem>
<para>
In case of multiple inheritance, if one parent column is a generated
column, then all parent columns must be generated columns. If they
do not all have the same generation expression, then the desired
expression for the child must be specified explicitly.
</para>
</listitem>
</itemizedlist>
</listitem>
</itemizedlist>
</para>
<para>
Additional considerations apply to the use of generated columns.
<itemizedlist>
<listitem>
<para>
Generated columns maintain access privileges separately from their
underlying base columns. So, it is possible to arrange it so that a
particular role can read from a generated column but not from the
underlying base columns.
</para>
<para>
For virtual generated columns, this is only fully secure if the
generation expression uses only leakproof functions (see <xref
linkend="sql-createfunction"/>), but this is not enforced by the system.
</para>
</listitem>
<listitem>
<para>
Privileges of functions used in generation expressions are checked when
the expression is actually executed, on write or read respectively, as
if the generation expression had been called directly from the query
using the generated column. The user of a generated column must have
permissions to call all functions used by the generation expression.
Functions in the generation expression are executed with the privileges
of the user executing the query or the function owner, depending on
whether the functions are defined as <literal>SECURITY INVOKER</literal>
or <literal>SECURITY DEFINER</literal>.
<!-- matches create_view.sgml -->
</para>
</listitem>
<listitem>
<para>
Generated columns are, conceptually, updated after
<literal>BEFORE</literal> triggers have run. Therefore, changes made to
base columns in a <literal>BEFORE</literal> trigger will be reflected in
generated columns. But conversely, it is not allowed to access
generated columns in <literal>BEFORE</literal> triggers.
</para>
</listitem>
<listitem>
<para>
Generated columns are allowed to be replicated during logical replication
according to the <command>CREATE PUBLICATION</command> parameter
<link linkend="sql-createpublication-params-with-publish-generated-columns">
<literal>publish_generated_columns</literal></link> or by including them
in the column list of the <command>CREATE PUBLICATION</command> command.
This is currently only supported for stored generated columns.
See <xref linkend="logical-replication-gencols"/> for details.
</para>
</listitem>
</itemizedlist>
</para>
</sect1>
<sect1 id="ddl-constraints">
<title>Constraints</title>
<indexterm zone="ddl-constraints">
<primary>constraint</primary>
</indexterm>
<para>
Data types are a way to limit the kind of data that can be stored
in a table. For many applications, however, the constraint they
provide is too coarse. For example, a column containing a product
price should