v2-0001-rewrite-is_table_publication.patch
application/octet-stream
Filename: v2-0001-rewrite-is_table_publication.patch
Type: application/octet-stream
Part: 0
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 v2-0001
Subject: rewrite is_table_publication
| File | + | − |
|---|---|---|
| src/backend/catalog/pg_publication.c | 23 | 21 |
| src/backend/commands/publicationcmds.c | 3 | 4 |
| src/include/catalog/pg_publication.h | 2 | 2 |
From f09ebae190716e440a6ce7dd135056a6343cd9d0 Mon Sep 17 00:00:00 2001
From: Peter Smith <peter.b.smith@fujitsu.com>
Date: Wed, 8 Apr 2026 16:22:37 +1000
Subject: [PATCH v2] rewrite is_table_publication
---
src/backend/catalog/pg_publication.c | 44 ++++++++++++++------------
src/backend/commands/publicationcmds.c | 7 ++--
src/include/catalog/pg_publication.h | 4 +--
3 files changed, 28 insertions(+), 27 deletions(-)
diff --git a/src/backend/catalog/pg_publication.c b/src/backend/catalog/pg_publication.c
index a43d385c605..e2003cd9203 100644
--- a/src/backend/catalog/pg_publication.c
+++ b/src/backend/catalog/pg_publication.c
@@ -275,19 +275,26 @@ filter_partitions(List *table_infos)
* schema is associated with the publication.
*/
bool
-is_schema_publication(Oid pubid)
+is_schema_publication(Form_pg_publication pubform)
{
Relation pubschsrel;
ScanKeyData scankey;
SysScanDesc scan;
HeapTuple tup;
- bool result = false;
+ bool result;
+
+ /*
+ * FOR TABLES IN SCHEMA cannot coexist with FOR ALL TABLES.
+ * FOR TABLES IN SCHEMA cannot coexist with FOR ALL SEQUENCES.
+ */
+ if (pubform->puballtables || pubform->puballsequences)
+ return false;
pubschsrel = table_open(PublicationNamespaceRelationId, AccessShareLock);
ScanKeyInit(&scankey,
Anum_pg_publication_namespace_pnpubid,
BTEqualStrategyNumber, F_OIDEQ,
- ObjectIdGetDatum(pubid));
+ ObjectIdGetDatum(pubform->oid));
scan = systable_beginscan(pubschsrel,
PublicationNamespacePnnspidPnpubidIndexId,
@@ -302,41 +309,36 @@ is_schema_publication(Oid pubid)
}
/*
- * Returns true if the publication has explicitly included relation (i.e.,
- * not marked as EXCEPT).
+ * Returns true if the publication has explicitly included relations (e.g.,
+ * FOR TABLE).
*/
bool
-is_table_publication(Oid pubid)
+is_table_publication(Form_pg_publication pubform)
{
Relation pubrelsrel;
ScanKeyData scankey;
SysScanDesc scan;
HeapTuple tup;
- bool result = false;
+ bool result;
+
+ /*
+ * FOR TABLE cannot coexist with FOR ALL TABLES.
+ * FOR TABLE cannot coexist with FOR ALL SEQUENCES.
+ */
+ if (pubform->puballtables || pubform->puballsequences)
+ return false;
pubrelsrel = table_open(PublicationRelRelationId, AccessShareLock);
ScanKeyInit(&scankey,
Anum_pg_publication_rel_prpubid,
BTEqualStrategyNumber, F_OIDEQ,
- ObjectIdGetDatum(pubid));
+ ObjectIdGetDatum(pubform->oid));
scan = systable_beginscan(pubrelsrel,
PublicationRelPrpubidIndexId,
true, NULL, 1, &scankey);
tup = systable_getnext(scan);
- if (HeapTupleIsValid(tup))
- {
- Form_pg_publication_rel pubrel;
-
- pubrel = (Form_pg_publication_rel) GETSTRUCT(tup);
-
- /*
- * For any publication, pg_publication_rel contains either only EXCEPT
- * entries or only explicitly included tables. Therefore, examining
- * the first tuple is sufficient to determine table inclusion.
- */
- result = !pubrel->prexcept;
- }
+ result = HeapTupleIsValid(tup);
systable_endscan(scan);
table_close(pubrelsrel, AccessShareLock);
diff --git a/src/backend/commands/publicationcmds.c b/src/backend/commands/publicationcmds.c
index 440adb356ad..3685c711c49 100644
--- a/src/backend/commands/publicationcmds.c
+++ b/src/backend/commands/publicationcmds.c
@@ -1261,7 +1261,7 @@ AlterPublicationTables(AlterPublicationStmt *stmt, HeapTuple tup,
{
TransformPubWhereClauses(rels, queryString, pubform->pubviaroot);
- publish_schema |= is_schema_publication(pubid);
+ publish_schema |= is_schema_publication(pubform);
CheckPubRelationColumnList(stmt->pubname, rels, publish_schema,
pubform->pubviaroot);
@@ -1585,8 +1585,7 @@ CheckAlterPublication(AlterPublicationStmt *stmt, HeapTuple tup,
* If the publication already contains specific tables or schemas, we
* prevent switching to a ALL state.
*/
- if (is_table_publication(pubform->oid) ||
- is_schema_publication(pubform->oid))
+ if (is_table_publication(pubform) || is_schema_publication(pubform))
{
ereport(ERROR,
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
@@ -2202,7 +2201,7 @@ AlterPublicationOwner_internal(Relation rel, HeapTuple tup, Oid newOwnerId)
if (!superuser_arg(newOwnerId))
{
if (form->puballtables || form->puballsequences ||
- is_schema_publication(form->oid))
+ is_schema_publication(form))
ereport(ERROR,
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
errmsg("permission denied to change owner of publication \"%s\"",
diff --git a/src/include/catalog/pg_publication.h b/src/include/catalog/pg_publication.h
index 89b4bb14f62..448373363fc 100644
--- a/src/include/catalog/pg_publication.h
+++ b/src/include/catalog/pg_publication.h
@@ -194,8 +194,8 @@ extern Oid GetTopMostAncestorInPublication(Oid puboid, List *ancestors,
int *ancestor_level);
extern bool is_publishable_relation(Relation rel);
-extern bool is_schema_publication(Oid pubid);
-extern bool is_table_publication(Oid pubid);
+extern bool is_schema_publication(Form_pg_publication pubform);
+extern bool is_table_publication(Form_pg_publication pubform);
extern bool check_and_fetch_column_list(Publication *pub, Oid relid,
MemoryContext mcxt, Bitmapset **cols);
extern ObjectAddress publication_add_relation(Oid pubid, PublicationRelInfo *pri,
--
2.47.3