0003-doc-Improve-description-of-referential-actions.patch

text/plain

Filename: 0003-doc-Improve-description-of-referential-actions.patch
Type: text/plain
Part: 2
Message: Re: altering a column's collation leaves an invalid foreign key

Patch

Format: format-patch
Series: patch 0003
Subject: doc: Improve description of referential actions
File+
doc/src/sgml/ddl.sgml 33 8
doc/src/sgml/ref/create_table.sgml 11 9
From 64476388bb806352b96b64d13df5718af6ac8415 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <peter@eisentraut.org>
Date: Tue, 19 Nov 2024 17:18:39 +0100
Subject: [PATCH 3/3] doc: Improve description of referential actions

Some of the differences between NO ACTION and RESTRICT were not
explained fully.
---
 doc/src/sgml/ddl.sgml              | 41 ++++++++++++++++++++++++------
 doc/src/sgml/ref/create_table.sgml | 20 ++++++++-------
 2 files changed, 44 insertions(+), 17 deletions(-)

diff --git a/doc/src/sgml/ddl.sgml b/doc/src/sgml/ddl.sgml
index 3c56610d2ac..203d6ce0c30 100644
--- a/doc/src/sgml/ddl.sgml
+++ b/doc/src/sgml/ddl.sgml
@@ -1233,16 +1233,32 @@ <title>Foreign Keys</title>
    </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 @@ <title>Foreign Keys</title>
     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>
diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml
index 1a1adc5ae87..70fa929caa4 100644
--- a/doc/src/sgml/ref/create_table.sgml
+++ b/doc/src/sgml/ref/create_table.sgml
@@ -1248,17 +1248,16 @@ <title>Parameters</title>
       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 @@ <title>Parameters</title>
         <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>
-- 
2.47.0