Skip to content

Commit 1e08905

Browse files
committed
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/[email protected]
1 parent 4a2dbfc commit 1e08905

File tree

2 files changed

+44
-17
lines changed

2 files changed

+44
-17
lines changed

doc/src/sgml/ddl.sgml

+33-8
Original file line numberDiff line numberDiff line change
@@ -1233,16 +1233,32 @@ CREATE TABLE order_items (
12331233
</para>
12341234

12351235
<para>
1236-
Restricting and cascading deletes are the two most common options.
1237-
<literal>RESTRICT</literal> prevents deletion of a
1238-
referenced row. <literal>NO ACTION</literal> means that if any
1239-
referencing rows still exist when the constraint is checked, an error
1240-
is raised; this is the default behavior if you do not specify anything.
1241-
(The essential difference between these two choices is that
1242-
<literal>NO ACTION</literal> allows the check to be deferred until
1243-
later in the transaction, whereas <literal>RESTRICT</literal> does not.)
1236+
The default <literal>ON DELETE</literal> action is <literal>ON DELETE NO
1237+
ACTION</literal>; this does not need to be specified. This means that the
1238+
deletion in the referenced table is allowed to proceed. But the
1239+
foreign-key constraint is still required to be satisfied, so this
1240+
operation will usually result in an error. But checking of foreign-key
1241+
constraints can also be deferred to later in the transaction (not covered
1242+
in this chapter). In that case, the <literal>NO ACTION</literal> setting
1243+
would allow other commands to <quote>fix</quote> the situation before the
1244+
constraint is checked, for example by inserting another suitable row into
1245+
the referenced table or by deleting the now-dangling rows from the
1246+
referencing table.
1247+
</para>
1248+
1249+
<para>
1250+
<literal>RESTRICT</literal> is a stricter setting than <literal>NO
1251+
ACTION</literal>. It prevents deletion of a referenced row.
1252+
<literal>RESTRICT</literal> does not allow the check to be deferred until
1253+
later in the transaction.
1254+
</para>
1255+
1256+
<para>
12441257
<literal>CASCADE</literal> specifies that when a referenced row is deleted,
12451258
row(s) referencing it should be automatically deleted as well.
1259+
</para>
1260+
1261+
<para>
12461262
There are two other options:
12471263
<literal>SET NULL</literal> and <literal>SET DEFAULT</literal>.
12481264
These cause the referencing column(s) in the referencing row(s)
@@ -1312,6 +1328,15 @@ CREATE TABLE posts (
13121328
NULL</literal> and <literal>SET DEFAULT</literal>.
13131329
In this case, <literal>CASCADE</literal> means that the updated values of the
13141330
referenced column(s) should be copied into the referencing row(s).
1331+
There is also a noticeable difference between <literal>ON UPDATE NO
1332+
ACTION</literal> (the default) and <literal>NO UPDATE RESTRICT</literal>.
1333+
The former will allow the update to proceed and the foreign-key constraint
1334+
will be checked against the state after the update. The latter will
1335+
prevent the update to run even if the state after the update would still
1336+
satisfy the constraint. This prevents updating a referenced row to a
1337+
value that is distinct but compares as equal (for example, a character
1338+
string with a different case variant, if a character string type with a
1339+
case-insensitive collation is used).
13151340
</para>
13161341

13171342
<para>

doc/src/sgml/ref/create_table.sgml

+11-9
Original file line numberDiff line numberDiff line change
@@ -1248,17 +1248,16 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM
12481248
clause specifies the action to perform when a referenced column
12491249
in the referenced table is being updated to a new value. If the
12501250
row is updated, but the referenced column is not actually
1251-
changed, no action is done. Referential actions other than the
1252-
<literal>NO ACTION</literal> check cannot be deferred, even if
1253-
the constraint is declared deferrable. There are the following possible
1254-
actions for each clause:
1251+
changed, no action is done. Referential actions are executed as part of
1252+
the data changing command, even if the constraint is deferred. There
1253+
are the following possible actions for each clause:
12551254

12561255
<variablelist>
12571256
<varlistentry id="sql-createtable-parms-references-refact-no-action">
12581257
<term><literal>NO ACTION</literal></term>
12591258
<listitem>
12601259
<para>
1261-
Produce an error indicating that the deletion or update
1260+
Produce an error if the deletion or update
12621261
would create a foreign key constraint violation.
12631262
If the constraint is deferred, this
12641263
error will be produced at constraint check time if there still
@@ -1271,10 +1270,13 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM
12711270
<term><literal>RESTRICT</literal></term>
12721271
<listitem>
12731272
<para>
1274-
Produce an error indicating that the deletion or update
1275-
would create a foreign key constraint violation.
1276-
This is the same as <literal>NO ACTION</literal> except that
1277-
the check is not deferrable.
1273+
Produce an error if a row to be deleted or updated matches a row in
1274+
the referencing table. This prevents the action even if the state
1275+
after the action would not violate the foreign key constraint. In
1276+
particular, it prevents updates of referenced rows to values that
1277+
are distinct but compare as equal. (But it does not prevent
1278+
<quote>no-op</quote> updates that update a column to the same
1279+
value.)
12781280
</para>
12791281
</listitem>
12801282
</varlistentry>

0 commit comments

Comments
 (0)