From 37966d29319d61736e74ee42fac0d7a9507fea9b Mon Sep 17 00:00:00 2001
From: Hou Zhijie <houzj.fnst@cn.fujitsu.com>
Date: Tue, 21 Jan 2025 16:18:34 +0800
Subject: [PATCH v6 1/2] Improve logging for data origin discrepancies in table
 synchronization

Previously, a WARNING was issued during initial table synchronization with
origin=NONE only when the publisher subscribed to the same table from
other publishers, indicating potential data origination from different origins.
However, it's possible for the publisher to subscribe to the partition
ancestors or partition children of the table from other publishers, which could
also result in mixed-origin data inclusion.

This patch expands the check to consider both the subscribed table's ancestors
and children. A WARNING will now be logged if any of these related tables could
contain data originating from different sources.
---
 doc/src/sgml/ref/create_subscription.sgml | 14 ++++++++------
 src/backend/commands/subscriptioncmds.c   | 15 +++++++++------
 2 files changed, 17 insertions(+), 12 deletions(-)

diff --git a/doc/src/sgml/ref/create_subscription.sgml b/doc/src/sgml/ref/create_subscription.sgml
index 6cf7d4f9a1..8bee9f88a4 100644
--- a/doc/src/sgml/ref/create_subscription.sgml
+++ b/doc/src/sgml/ref/create_subscription.sgml
@@ -534,13 +534,15 @@ CREATE SUBSCRIPTION <replaceable class="parameter">subscription_name</replaceabl
 <programlisting>
 # substitute &lt;pub-names&gt; below with your publication name(s) to be queried
 SELECT DISTINCT PT.schemaname, PT.tablename
-FROM pg_publication_tables PT,
+FROM pg_publication_tables PT
+     JOIN pg_class C ON (C.relname = PT.tablename)
+     JOIN pg_namespace N ON (N.nspname = PT.schemaname),
      pg_subscription_rel PS
-     JOIN pg_class C ON (C.oid = PS.srrelid)
-     JOIN pg_namespace N ON (N.oid = C.relnamespace)
-WHERE N.nspname = PT.schemaname AND
-      C.relname = PT.tablename AND
-      PT.pubname IN (&lt;pub-names&gt;);
+WHERE C.relnamespace = N.oid AND
+      PT.pubname IN (&lt;pub-names&gt;) AND
+      (PS.srrelid = C.oid OR
+      C.oid IN (SELECT relid FROM pg_partition_ancestors(PS.srrelid) UNION
+                SELECT relid FROM pg_partition_tree(PS.srrelid)));
 </programlisting></para>
 
  </refsect1>
diff --git a/src/backend/commands/subscriptioncmds.c b/src/backend/commands/subscriptioncmds.c
index 2d8a71ca1e..4aec73bcc6 100644
--- a/src/backend/commands/subscriptioncmds.c
+++ b/src/backend/commands/subscriptioncmds.c
@@ -2083,11 +2083,12 @@ AlterSubscriptionOwner_oid(Oid subid, Oid newOwnerId)
 }
 
 /*
- * Check and log a warning if the publisher has subscribed to the same table
- * from some other publisher. This check is required only if "copy_data = true"
- * and "origin = none" for CREATE SUBSCRIPTION and
- * ALTER SUBSCRIPTION ... REFRESH statements to notify the user that data
- * having origin might have been copied.
+ * Check and log a warning if the publisher has subscribed to the same table,
+ * its partition ancestors (if it's a partition), or its partition children (if
+ * it's a partitioned table), from some other publishers. This check is
+ * required only if "copy_data = true" and "origin = none" for CREATE
+ * SUBSCRIPTION and ALTER SUBSCRIPTION ... REFRESH statements to notify the
+ * user that data having origin might have been copied.
  *
  * This check need not be performed on the tables that are already added
  * because incremental sync for those tables will happen through WAL and the
@@ -2117,7 +2118,9 @@ check_publications_origin(WalReceiverConn *wrconn, List *publications,
 						   "SELECT DISTINCT P.pubname AS pubname\n"
 						   "FROM pg_publication P,\n"
 						   "     LATERAL pg_get_publication_tables(P.pubname) GPT\n"
-						   "     JOIN pg_subscription_rel PS ON (GPT.relid = PS.srrelid),\n"
+						   "     JOIN pg_subscription_rel PS ON (GPT.relid = PS.srrelid OR"
+						   "     GPT.relid IN (SELECT relid FROM pg_partition_ancestors(PS.srrelid) UNION"
+						   "                   SELECT relid FROM pg_partition_tree(PS.srrelid))),\n"
 						   "     pg_class C JOIN pg_namespace N ON (N.oid = C.relnamespace)\n"
 						   "WHERE C.oid = GPT.relid AND P.pubname IN (");
 	GetPublicationsStr(publications, &cmd, true);
-- 
2.34.1

