1
0
mirror of https://github.com/postgres/postgres.git synced 2025-06-14 18:42:34 +03:00

doc: Improve description of referential actions

Some of the differences between NO ACTION and RESTRICT were not
explained fully.

Discussion: https://www.postgresql.org/message-id/ea5b2777-266a-46fa-852f-6fca6ec480ad@eisentraut.org
This commit is contained in:
Peter Eisentraut
2024-11-29 08:52:28 +01:00
parent 4a2dbfc6be
commit 1e08905842
2 changed files with 44 additions and 17 deletions

View File

@ -1233,16 +1233,32 @@ CREATE TABLE order_items (
</para>
<para>
Restricting and cascading deletes are the two most common options.
<literal>RESTRICT</literal> prevents deletion of a
referenced row. <literal>NO ACTION</literal> means that if any
referencing rows still exist when the constraint is checked, an error
is raised; this is the default behavior if you do not specify anything.
(The essential difference between these two choices is that
<literal>NO ACTION</literal> allows the check to be deferred until
later in the transaction, whereas <literal>RESTRICT</literal> does not.)
The default <literal>ON DELETE</literal> action is <literal>ON DELETE NO
ACTION</literal>; this does not need to be specified. This means that the
deletion in the referenced table is allowed to proceed. But the
foreign-key constraint is still required to be satisfied, so this
operation will usually result in an error. But checking of foreign-key
constraints can also be deferred to later in the transaction (not covered
in this chapter). In that case, the <literal>NO ACTION</literal> setting
would allow other commands to <quote>fix</quote> the situation before the
constraint is checked, for example by inserting another suitable row into
the referenced table or by deleting the now-dangling rows from the
referencing table.
</para>
<para>
<literal>RESTRICT</literal> is a stricter setting than <literal>NO
ACTION</literal>. It prevents deletion of a referenced row.
<literal>RESTRICT</literal> does not allow the check to be deferred until
later in the transaction.
</para>
<para>
<literal>CASCADE</literal> specifies that when a referenced row is deleted,
row(s) referencing it should be automatically deleted as well.
</para>
<para>
There are two other options:
<literal>SET NULL</literal> and <literal>SET DEFAULT</literal>.
These cause the referencing column(s) in the referencing row(s)
@ -1312,6 +1328,15 @@ CREATE TABLE posts (
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>NO 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>

View File

@ -1248,17 +1248,16 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM
clause specifies the action to perform when a referenced column
in the referenced table is being updated to a new value. If the
row is updated, but the referenced column is not actually
changed, no action is done. Referential actions other than the
<literal>NO ACTION</literal> check cannot be deferred, even if
the constraint is declared deferrable. There are the following possible
actions for each clause:
changed, no action is done. Referential actions are executed as part of
the data changing command, even if the constraint is deferred. There
are the following possible actions for each clause:
<variablelist>
<varlistentry id="sql-createtable-parms-references-refact-no-action">
<term><literal>NO ACTION</literal></term>
<listitem>
<para>
Produce an error indicating that the deletion or update
Produce an error if the deletion or update
would create a foreign key constraint violation.
If the constraint is deferred, this
error will be produced at constraint check time if there still
@ -1271,10 +1270,13 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM
<term><literal>RESTRICT</literal></term>
<listitem>
<para>
Produce an error indicating that the deletion or update
would create a foreign key constraint violation.
This is the same as <literal>NO ACTION</literal> except that
the check is not deferrable.
Produce an error if a row to be deleted or updated matches a row in
the referencing table. This prevents the action even if the state
after the action would not violate the foreign key constraint. In
particular, it prevents updates of referenced rows to values that
are distinct but compare as equal. (But it does not prevent
<quote>no-op</quote> updates that update a column to the same
value.)
</para>
</listitem>
</varlistentry>