From 29823a029fb9b74e3b5414f7bbccd29c94ba0dd7 Mon Sep 17 00:00:00 2001 From: Dilip Kumar Date: Wed, 12 Nov 2025 14:30:39 +0530 Subject: [PATCH v4 2/3] Don't add conflict history tables to publishable relation When all table option is used with publication don't publish the conflict history tables. --- src/backend/catalog/pg_publication.c | 16 ++++++++-- src/backend/commands/subscriptioncmds.c | 40 +++++++++++++++++++++++++ src/include/commands/subscriptioncmds.h | 2 ++ 3 files changed, 56 insertions(+), 2 deletions(-) diff --git a/src/backend/catalog/pg_publication.c b/src/backend/catalog/pg_publication.c index ac2f4ee3561..cab1776e78c 100644 --- a/src/backend/catalog/pg_publication.c +++ b/src/backend/catalog/pg_publication.c @@ -31,6 +31,7 @@ #include "catalog/pg_publication_rel.h" #include "catalog/pg_type.h" #include "commands/publicationcmds.h" +#include "commands/subscriptioncmds.h" #include "funcapi.h" #include "utils/array.h" #include "utils/builtins.h" @@ -72,6 +73,14 @@ check_publication_add_relation(Relation targetrel) RelationGetRelationName(targetrel)), errdetail("This operation is not supported for system tables."))); + /* Can't be created as conflict log table */ + if (IsConflictLogRelid(RelationGetRelid(targetrel))) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("cannot add relation \"%s\" to publication", + RelationGetRelationName(targetrel)), + errdetail("This operation is not supported for conflict log tables."))); + /* UNLOGGED and TEMP relations cannot be part of publication. */ if (targetrel->rd_rel->relpersistence == RELPERSISTENCE_TEMP) ereport(ERROR, @@ -153,7 +162,7 @@ is_publishable_relation(Relation rel) } /* - * SQL-callable variant of the above + * SQL-callable variant of the above and this should not be a conflict log rel * * This returns null when the relation does not exist. This is intended to be * used for example in psql to avoid gratuitous errors when there are @@ -169,7 +178,8 @@ pg_relation_is_publishable(PG_FUNCTION_ARGS) tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(relid)); if (!HeapTupleIsValid(tuple)) PG_RETURN_NULL(); - result = is_publishable_class(relid, (Form_pg_class) GETSTRUCT(tuple)); + result = is_publishable_class(relid, (Form_pg_class) GETSTRUCT(tuple)) && + !IsConflictLogRelid(relid); ReleaseSysCache(tuple); PG_RETURN_BOOL(result); } @@ -890,7 +900,9 @@ GetAllPublicationRelations(char relkind, bool pubviaroot) Form_pg_class relForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid = relForm->oid; + /* conflict history tables are not published. */ if (is_publishable_class(relid, relForm) && + !IsConflictLogRelid(relid) && !(relForm->relispartition && pubviaroot)) result = lappend_oid(result, relid); } diff --git a/src/backend/commands/subscriptioncmds.c b/src/backend/commands/subscriptioncmds.c index e48728dec07..7dc04917aa3 100644 --- a/src/backend/commands/subscriptioncmds.c +++ b/src/backend/commands/subscriptioncmds.c @@ -15,6 +15,7 @@ #include "postgres.h" #include "access/commit_ts.h" +#include "access/heapam.h" #include "access/htup_details.h" #include "access/table.h" #include "access/twophase.h" @@ -3357,3 +3358,42 @@ DropConflictLogTable(Oid namespaceId, char *conflictrel) pfree(querybuf.data); } + +/* + * Is relation used as a conflict log table + * + * Scan all the subscription and check whether the relation is used as + * conflict log table. + */ +bool +IsConflictLogRelid(Oid relid) +{ + Relation rel; + TableScanDesc scan; + HeapTuple tup; + bool found = false; + + rel = table_open(SubscriptionRelationId, AccessShareLock); + scan = table_beginscan_catalog(rel, 0, NULL); + + while (HeapTupleIsValid(tup = heap_getnext(scan, ForwardScanDirection))) + { + Form_pg_subscription subform = (Form_pg_subscription) GETSTRUCT(tup); + Oid nspid; + char *relname; + + relname = get_subscription_conflictrel(subform->oid, &nspid); + if (relname == NULL) + continue; + if (relid == get_relname_relid(relname, nspid)) + { + found = true; + break; + } + } + + table_endscan(scan); + table_close(rel, AccessShareLock); + + return found; +} diff --git a/src/include/commands/subscriptioncmds.h b/src/include/commands/subscriptioncmds.h index fb4e26a51a4..b5e9cbf8bfe 100644 --- a/src/include/commands/subscriptioncmds.h +++ b/src/include/commands/subscriptioncmds.h @@ -36,4 +36,6 @@ extern void CheckSubDeadTupleRetention(bool check_guc, bool sub_disabled, bool retention_active, bool max_retention_set); +extern bool IsConflictLogRelid(Oid relid); + #endif /* SUBSCRIPTIONCMDS_H */ -- 2.49.0