From 0e94d7b00a215baeffd37730d230fd5220291dbc Mon Sep 17 00:00:00 2001
From: Robert Treat <rob@xzilla.net>
Date: Fri, 10 Jan 2025 13:56:11 -0500
Subject: [PATCH v3] Expand and clarify Replica Identity information

Based on discussion from James Coleman, Peter Smith, Laurenz Albe, and Amit Kapala.
---
 doc/src/sgml/logical-replication.sgml | 83 +++++++++++++++++----------
 doc/src/sgml/ref/alter_table.sgml     |  3 +-
 2 files changed, 56 insertions(+), 30 deletions(-)

diff --git a/doc/src/sgml/logical-replication.sgml b/doc/src/sgml/logical-replication.sgml
index 8290cd1a08..f8de6359d5 100644
--- a/doc/src/sgml/logical-replication.sgml
+++ b/doc/src/sgml/logical-replication.sgml
@@ -124,35 +124,6 @@
    <command>TRUNCATE</command>. See <xref linkend="logical-replication-row-filter"/>).
   </para>
 
-  <para>
-   A published table must have a <firstterm>replica identity</firstterm> configured in
-   order to be able to replicate <command>UPDATE</command>
-   and <command>DELETE</command> operations, so that appropriate rows to
-   update or delete can be identified on the subscriber side.  By default,
-   this is the primary key, if there is one.  Another unique index (with
-   certain additional requirements) can also be set to be the replica
-   identity.  If the table does not have any suitable key, then it can be set
-   to replica identity <literal>FULL</literal>, which means the entire row becomes
-   the key.  When replica identity <literal>FULL</literal> is specified,
-   indexes can be used on the subscriber side for searching the rows.  Candidate
-   indexes must be btree or hash, non-partial, and the leftmost index field must
-   be a column (not an expression) that references the published table column.
-   These restrictions on the non-unique index properties adhere to some of the
-   restrictions that are enforced for primary keys.  If there are no such
-   suitable indexes, the search on the subscriber side can be very inefficient,
-   therefore replica identity <literal>FULL</literal> should only be used as a
-   fallback if no other solution is possible.  If a replica identity other
-   than <literal>FULL</literal> is set on the publisher side, a replica identity
-   comprising the same or fewer columns must also be set on the subscriber
-   side.  See <xref linkend="sql-altertable-replica-identity"/> for details on
-   how to set the replica identity.  If a table without a replica identity is
-   added to a publication that replicates <command>UPDATE</command>
-   or <command>DELETE</command> operations then
-   subsequent <command>UPDATE</command> or <command>DELETE</command>
-   operations will cause an error on the publisher.  <command>INSERT</command>
-   operations can proceed regardless of any replica identity.
-  </para>
-
   <para>
    Every publication can have multiple subscribers.
   </para>
@@ -169,6 +140,60 @@
    transactional, so the table will start or stop replicating at the correct
    snapshot once the transaction has committed.
   </para>
+
+  <sect2 id="logical-replication-publication-replica-identity">
+   <title>Replica Identity</title>
+
+   <para>
+    A published table must have a <firstterm>replica identity</firstterm>
+    configured in order to be able to replicate <command>UPDATE</command>
+    and <command>DELETE</command> operations, so that appropriate rows to
+    update or delete can be identified on the subscriber side.
+   </para>
+
+   <para>
+    By default, this is the primary key, if there is one. Another unique index
+    (with certain additional requirements) can also be set to be the replica
+    identity.  If the table does not have any suitable key, then it can be set
+    to replica identity <literal>FULL</literal>, which means the entire row
+    becomes the key.  When replica identity <literal>FULL</literal> is
+    specified, indexes can be used on the subscriber side for searching the
+    rows.  Candidate indexes must be btree or hash, non-partial, and the
+    leftmost index field must be a column (not an expression) that references
+    the published table column.  These restrictions on the non-unique index
+    properties adhere to some of the restrictions that are enforced for
+    primary keys.  If there are no such suitable indexes, the search on the
+    subscriber side can be very inefficient, therefore replica identity
+    <literal>FULL</literal> should only be used as a fallback if no other
+    solution is possible.
+   </para>
+
+   <para>
+    If a replica identity other than <literal>FULL</literal> is set on the
+    publisher side, a replica identity comprising the same or fewer columns
+    must also be set on the subscriber side.
+   </para>
+
+   <para>
+    If a table with replica identity set to <literal>NOTHING</literal>
+    (or set <command>DEFAULT</command> but with no primary key, or set
+    <command>USING INDEX</command> but the index has been dropped) is
+    added to a publication that replicates <command>UPDATE</command>
+    or <command>DELETE</command> operations,
+    subsequent <command>UPDATE</command> or <command>DELETE</command>
+    operations will cause an error on the publisher.
+   </para>
+
+   <para>
+    <command>INSERT</command> operations can proceed regardless of any replica identity.
+   </para>
+
+   <para>
+    See <link linkend="sql-altertable-replica-identity"><literal>ALTER TABLE...REPLICA IDENTITY</literal></link>
+    for details on how to set the replica identity.
+   </para>
+  </sect2>
+
  </sect1>
 
  <sect1 id="logical-replication-subscription">
diff --git a/doc/src/sgml/ref/alter_table.sgml b/doc/src/sgml/ref/alter_table.sgml
index c8f7ab7d95..6fdfe05fdd 100644
--- a/doc/src/sgml/ref/alter_table.sgml
+++ b/doc/src/sgml/ref/alter_table.sgml
@@ -927,8 +927,9 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM
        <term><literal>DEFAULT</literal></term>
        <listitem>
         <para>
-         Records the old values of the columns of the primary key, if any.
+         Records the old values of the columns of the primary key.
          This is the default for non-system tables.
+         When there is no primary key, the behavior is the same as <literal>NOTHING</literal>.
         </para>
        </listitem>
       </varlistentry>
-- 
2.24.3 (Apple Git-128)

