fix_patch

application/octet-stream

Filename: fix_patch
Type: application/octet-stream
Part: 0
Message: RE: Added schema level support for publication.
From 7232e70d85dc4f34f99d68035ad36922c176771f Mon Sep 17 00:00:00 2001
From: houzj <houzj.fnst@cn.fujitsu.com>
Date: Fri, 9 Jul 2021 08:49:25 +0800
Subject: [PATCH] fixdiff

---
 src/backend/catalog/pg_publication.c   | 43 ++++++++++++++++++++++++++++++----
 src/backend/commands/publicationcmds.c | 10 ++++++--
 src/backend/utils/cache/relcache.c     |  4 ++++
 src/include/commands/publicationcmds.h |  3 ++-
 4 files changed, 53 insertions(+), 7 deletions(-)

diff --git a/src/backend/catalog/pg_publication.c b/src/backend/catalog/pg_publication.c
index ee4ecfd..b1acc7a 100644
--- a/src/backend/catalog/pg_publication.c
+++ b/src/backend/catalog/pg_publication.c
@@ -416,6 +416,40 @@ GetPublicationSchemas(Oid pubid)
 	return result;
 }
 
+List *
+GetSchemaPublications(Oid schemaid)
+{
+	List	   *result = NIL;
+	Relation	pubschsrel;
+	ScanKeyData scankey;
+	SysScanDesc scan;
+	HeapTuple	tup;
+
+	/* Find all publications associated with the schema. */
+	pubschsrel = table_open(PublicationSchemaRelationId, AccessShareLock);
+
+	ScanKeyInit(&scankey,
+				Anum_pg_publication_schema_psnspcid,
+				BTEqualStrategyNumber, F_OIDEQ,
+				ObjectIdGetDatum(schemaid));
+
+	scan = systable_beginscan(pubschsrel, PublicationSchemaPsnspcidPspubidIndexId,
+							  true, NULL, 1, &scankey);
+	while (HeapTupleIsValid(tup = systable_getnext(scan)))
+	{
+		Form_pg_publication_schema pubsch;
+
+		pubsch = (Form_pg_publication_schema) GETSTRUCT(tup);
+
+		result = lappend_oid(result, pubsch->pspubid);
+	}
+
+	systable_endscan(scan);
+	table_close(pubschsrel, AccessShareLock);
+
+	return result;
+}
+
 /*
  * Gets list of publication oids for publications marked as FOR ALL TABLES.
  */
@@ -530,10 +564,10 @@ GetAllTablesPublicationRelations(bool pubviaroot, Oid schemaOid)
  * Gets the list of all relations published by FOR SCHEMA publication(s).
  */
 List *
-GetAllSchemasPublicationRelations(Publication *publication)
+GetAllSchemasPublicationRelations(bool pubviaroot, Oid puboid)
 {
 	List	   *result = NIL;
-	List	   *pubschemalist = GetPublicationSchemas(publication->oid);
+	List	   *pubschemalist = GetPublicationSchemas(puboid);
 	ListCell   *cell;
 
 	foreach(cell, pubschemalist)
@@ -541,7 +575,7 @@ GetAllSchemasPublicationRelations(Publication *publication)
 		Oid			schemaOid = lfirst_oid(cell);
 		List	   *schemaRels = NIL;
 
-		schemaRels = GetAllTablesPublicationRelations(publication->pubviaroot,
+		schemaRels = GetAllTablesPublicationRelations(pubviaroot,
 													  schemaOid);
 		result = list_concat(result, schemaRels);
 	}
@@ -685,7 +719,8 @@ pg_get_publication_tables(PG_FUNCTION_ARGS)
 											 PUBLICATION_PART_ROOT :
 											 PUBLICATION_PART_LEAF);
 		else if (publication->pubtype == PUBTYPE_SCHEMA)
-			tables = GetAllSchemasPublicationRelations(publication);
+			tables = GetAllSchemasPublicationRelations(publication->pubviaroot,
+													   publication->oid);
 		else
 			tables = NIL;
 		funcctx->user_fctx = (void *) tables;
diff --git a/src/backend/commands/publicationcmds.c b/src/backend/commands/publicationcmds.c
index 9f96b8b..8e5d180 100644
--- a/src/backend/commands/publicationcmds.c
+++ b/src/backend/commands/publicationcmds.c
@@ -419,13 +419,19 @@ AlterPublicationOptions(AlterPublicationStmt *stmt, Relation rel,
 	}
 	else
 	{
+		List	   *relids = NIL;
+
 		/*
 		 * For any partitioned tables contained in the publication, we must
 		 * invalidate all partitions contained in the respective partition
 		 * trees, not just those explicitly mentioned in the publication.
 		 */
-		List	   *relids = GetPublicationRelations(pubform->oid,
-													 PUBLICATION_PART_ALL);
+		if (pubform->pubtype == PUBTYPE_TABLE)
+			relids = GetPublicationRelations(pubform->oid,
+											 PUBLICATION_PART_ALL);
+		else if (pubform->pubtype == PUBTYPE_SCHEMA)
+			relids = GetAllSchemasPublicationRelations(pubform->pubviaroot,
+													   pubform->oid);
 
 		/*
 		 * We don't want to send too many individual messages, at some point
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index e964aea..e610357 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -5449,6 +5449,7 @@ GetRelationPublicationActions(Relation relation)
 	List	   *puboids;
 	ListCell   *lc;
 	MemoryContext oldcxt;
+	Oid			schemaid;
 	PublicationActions *pubactions = palloc0(sizeof(PublicationActions));
 
 	/*
@@ -5480,6 +5481,9 @@ GetRelationPublicationActions(Relation relation)
 	}
 	puboids = list_concat_unique_oid(puboids, GetAllTablesPublications());
 
+	schemaid = RelationGetNamespace(relation);
+	puboids = list_concat_unique_oid(puboids, GetSchemaPublications(schemaid));
+
 	foreach(lc, puboids)
 	{
 		Oid			pubid = lfirst_oid(lc);
diff --git a/src/include/commands/publicationcmds.h b/src/include/commands/publicationcmds.h
index 3c2a77d..b34efab 100644
--- a/src/include/commands/publicationcmds.h
+++ b/src/include/commands/publicationcmds.h
@@ -33,9 +33,10 @@ extern List *GetRelationPublications(Oid relid);
 
 extern List *GetPublicationRelations(Oid pubid, PublicationPartOpt pub_partopt);
 extern List *GetPublicationSchemas(Oid pubid);
+extern List *GetSchemaPublications(Oid schemaid);
 extern List *GetAllTablesPublications(void);
 extern List *GetAllTablesPublicationRelations(bool pubviaroot, Oid schemaOid);
-extern List *GetAllSchemasPublicationRelations(Publication *publication);
+extern List *GetAllSchemasPublicationRelations(bool pubviaroot, Oid puboid);
 
 extern bool is_publishable_relation(Relation rel);
 extern ObjectAddress publication_add_relation(Oid pubid, Relation targetrel,
-- 
2.7.2.windows.1