0001-fixup-publish_as_relid-20220310.patch

text/x-patch

Filename: 0001-fixup-publish_as_relid-20220310.patch
Type: text/x-patch
Part: 1
Message: Re: Column Filtering in Logical Replication

Patch

Same data as JSON: GET /api/v1/attachments/:id/patch the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes. API reference →
Format: format-patch
Series: patch 0001
Subject: fixup: publish_as_relid
File+
src/backend/replication/pgoutput/pgoutput.c 30 2
From 5070a26fb54b956557f4ba3a44b796ab4c232c93 Mon Sep 17 00:00:00 2001
From: Tomas Vondra <tomas@2ndquadrant.com>
Date: Wed, 9 Mar 2022 18:10:56 +0100
Subject: [PATCH 1/2] fixup: publish_as_relid

---
 src/backend/replication/pgoutput/pgoutput.c | 32 +++++++++++++++++++--
 1 file changed, 30 insertions(+), 2 deletions(-)

diff --git a/src/backend/replication/pgoutput/pgoutput.c b/src/backend/replication/pgoutput/pgoutput.c
index ea57a0477f0..dbac2690b7f 100644
--- a/src/backend/replication/pgoutput/pgoutput.c
+++ b/src/backend/replication/pgoutput/pgoutput.c
@@ -1815,11 +1815,17 @@ get_rel_sync_entry(PGOutputData *data, Relation relation)
 			Publication *pub = lfirst(lc);
 			bool		publish = false;
 
+			/*
+			 * Under what relid should we publish changes in this publication?
+			 * We'll use the top-most relid across all publications.
+			 */
+			Oid			pub_relid = relid;
+
 			if (pub->alltables)
 			{
 				publish = true;
 				if (pub->pubviaroot && am_partition)
-					publish_as_relid = llast_oid(get_partition_ancestors(relid));
+					pub_relid = llast_oid(get_partition_ancestors(relid));
 			}
 
 			if (!publish)
@@ -1844,7 +1850,7 @@ get_rel_sync_entry(PGOutputData *data, Relation relation)
 					{
 						ancestor_published = true;
 						if (pub->pubviaroot)
-							publish_as_relid = ancestor;
+							pub_relid = ancestor;
 					}
 				}
 
@@ -1862,12 +1868,34 @@ get_rel_sync_entry(PGOutputData *data, Relation relation)
 			if (publish &&
 				(relkind != RELKIND_PARTITIONED_TABLE || pub->pubviaroot))
 			{
+				List *ancestors;
+
 				entry->pubactions.pubinsert |= pub->pubactions.pubinsert;
 				entry->pubactions.pubupdate |= pub->pubactions.pubupdate;
 				entry->pubactions.pubdelete |= pub->pubactions.pubdelete;
 				entry->pubactions.pubtruncate |= pub->pubactions.pubtruncate;
 
 				rel_publications = lappend(rel_publications, pub);
+
+				/*
+				 * We want to publish the changes as the top-most ancestor
+				 * across all publications. So we fetch all ancestors of the
+				 * relid calculated for this publication, and check if the
+				 * already calculated value is in the list. If yes, we can
+				 * ignore the new value (as it's a child). Otherwise the new
+				 * value is an ancestor, so we keep it.
+				 */
+				ancestors = get_partition_ancestors(pub_relid);
+
+				/*
+				 * The new pub_relid is a child of the current publish_as_relid
+				 * value, so we can ignore it.
+				 */
+				if (list_member_oid(ancestors, publish_as_relid))
+					continue;
+
+				/* The new value is an ancestor, so let's keep it. */
+				publish_as_relid = pub_relid;
 			}
 		}
 
-- 
2.34.1