aboutsummaryrefslogtreecommitdiff
path: root/src/backend
diff options
context:
space:
mode:
authorAmit Kapila <akapila@postgresql.org>2021-12-09 08:36:59 +0530
committerAmit Kapila <akapila@postgresql.org>2021-12-09 08:36:59 +0530
commit5e97905a2c764d4ca36f5c6cccd0ebbf157b9df4 (patch)
tree1986ebb09cd6971ef900ca6a1c15bf6c8bd6172e /src/backend
parentbcf60585e6e0e95f0b9e5d64c7a6edca99ec6e86 (diff)
downloadpostgresql-5e97905a2c764d4ca36f5c6cccd0ebbf157b9df4.tar.gz
postgresql-5e97905a2c764d4ca36f5c6cccd0ebbf157b9df4.zip
Fix double publish of child table's data.
We publish the child table's data twice for a publication that has both child and parent tables and is published with publish_via_partition_root as true. This happens because subscribers will initiate synchronization using both parent and child tables, since it gets both as separate tables in the initial table list. Ensure that pg_publication_tables returns only parent tables in such cases. Author: Hou Zhijie Reviewed-by: Greg Nancarrow, Amit Langote, Vignesh C, Amit Kapila Backpatch-through: 13 Discussion: https://postgr.es/m/OS0PR01MB57167F45D481F78CDC5986F794B99@OS0PR01MB5716.jpnprd01.prod.outlook.com
Diffstat (limited to 'src/backend')
-rw-r--r--src/backend/catalog/pg_publication.c41
1 files changed, 14 insertions, 27 deletions
diff --git a/src/backend/catalog/pg_publication.c b/src/backend/catalog/pg_publication.c
index 65db07f6024..62f10bcbd28 100644
--- a/src/backend/catalog/pg_publication.c
+++ b/src/backend/catalog/pg_publication.c
@@ -142,7 +142,7 @@ is_publishable_class(Oid relid, Form_pg_class reltuple)
* the publication.
*/
static List *
-filter_partitions(List *relids, List *schemarelids)
+filter_partitions(List *relids)
{
List *result = NIL;
ListCell *lc;
@@ -161,16 +161,8 @@ filter_partitions(List *relids, List *schemarelids)
{
Oid ancestor = lfirst_oid(lc2);
- /*
- * Check if the parent table exists in the published table list.
- *
- * XXX As of now, we do this if the partition relation or the
- * partition relation's ancestor is present in schema publication
- * relations.
- */
- if (list_member_oid(relids, ancestor) &&
- (list_member_oid(schemarelids, relid) ||
- list_member_oid(schemarelids, ancestor)))
+ /* Check if the parent table exists in the published table list. */
+ if (list_member_oid(relids, ancestor))
{
skip = true;
break;
@@ -913,22 +905,17 @@ pg_get_publication_tables(PG_FUNCTION_ARGS)
PUBLICATION_PART_ROOT :
PUBLICATION_PART_LEAF);
tables = list_concat_unique_oid(relids, schemarelids);
- if (schemarelids && publication->pubviaroot)
- {
- /*
- * If the publication publishes partition changes via their
- * respective root partitioned tables, we must exclude
- * partitions in favor of including the root partitioned
- * tables. Otherwise, the function could return both the child
- * and parent tables which could cause data of the child table
- * to be double-published on the subscriber side.
- *
- * XXX As of now, we do this when a publication has associated
- * schema or for all tables publication. See
- * GetAllTablesPublicationRelations().
- */
- tables = filter_partitions(tables, schemarelids);
- }
+
+ /*
+ * If the publication publishes partition changes via their
+ * respective root partitioned tables, we must exclude partitions
+ * in favor of including the root partitioned tables. Otherwise,
+ * the function could return both the child and parent tables
+ * which could cause data of the child table to be
+ * double-published on the subscriber side.
+ */
+ if (publication->pubviaroot)
+ tables = filter_partitions(tables);
}
funcctx->user_fctx = (void *) tables;