manager, and the
product manager entry gets deleted, then setting the product's product
manager to null or a default might be useful.
</para>
<para>
The actions <literal>SET NULL</literal> and <literal>SET DEFAULT</literal>
can take a column list to specify which columns to set. Normally, all
columns of the foreign-key constraint are set; setting only a subset is
useful in some special cases. Consider the following example:
<programlisting>
CREATE TABLE tenants (
tenant_id integer PRIMARY KEY
);
CREATE TABLE users (
tenant_id integer REFERENCES tenants ON DELETE CASCADE,
user_id integer NOT NULL,
PRIMARY KEY (tenant_id, user_id)
);
CREATE TABLE posts (
tenant_id integer REFERENCES tenants ON DELETE CASCADE,
post_id integer NOT NULL,
author_id integer,
PRIMARY KEY (tenant_id, post_id),
FOREIGN KEY (tenant_id, author_id) REFERENCES users ON DELETE SET NULL <emphasis>(author_id)</emphasis>
);
</programlisting>
Without the specification of the column, the foreign key would also set
the column <literal>tenant_id</literal> to null, but that column is still
required as part of the primary key.
</para>
<para>
Analogous to <literal>ON DELETE</literal> there is also
<literal>ON UPDATE</literal> which is invoked when a referenced
column is changed (updated). The possible actions are the same,
except that column lists cannot be specified for <literal>SET
NULL</literal> and <literal>SET DEFAULT</literal>.
In this case, <literal>CASCADE</literal> means that the updated values of the
referenced column(s) should be copied into the referencing row(s).
There is also a noticeable difference between <literal>ON UPDATE NO
ACTION</literal> (the default) and <literal>ON UPDATE RESTRICT</literal>.
The former will allow the update to proceed and the foreign-key constraint
will be checked against the state after the update. The latter will
prevent the update to run even if the state after the update would still
satisfy the constraint. This prevents updating a referenced row to a
value that is distinct but compares as equal (for example, a character
string with a different case variant, if a character string type with a
case-insensitive collation is used).
</para>
<para>
Normally, a referencing row need not satisfy the foreign key constraint
if any of its referencing columns are null. If <literal>MATCH FULL</literal>
is added to the foreign key declaration, a referencing row escapes
satisfying the constraint only if all its referencing columns are null
(so a mix of null and non-null values is guaranteed to fail a
<literal>MATCH FULL</literal> constraint). If you don't want referencing rows
to be able to avoid satisfying the foreign key constraint, declare the
referencing column(s) as <literal>NOT NULL</literal>.
</para>
<para>
A foreign key must reference columns that either are a primary key or
form a unique constraint, or are columns from a non-partial unique index.
This means that the referenced columns always have an index to allow
efficient lookups on whether a referencing row has a match. Since a
<command>DELETE</command> of a row from the referenced table or an
<command>UPDATE</command> of a referenced column will require a scan of
the referencing table for rows matching the old value, it is often a good
idea to index the referencing columns too. Because this is not always
needed, and there are many choices available on how to index, the
declaration of a foreign key constraint does not automatically create an
index on the referencing columns.
</para>
<para>
More information about updating and deleting data is in <xref
linkend="dml"/>. Also see the description of foreign key constraint
syntax in the reference documentation for
<xref linkend="sql-createtable"/>.
</para>
</sect2>