From da591c9c967c693fd507d52a79357ca17aa0034a Mon Sep 17 00:00:00 2001
From: "Vigneshwaran C" <vignesh21@gmail.com>
Date: Mon, 6 Sep 2021 13:37:11 +0800
Subject: [PATCH 1/2] refactor relation cache invalidation code

Made the existing relation cache invalidation code into a function. Also
made getting the relations based on the publication partition option for a
specified relation into a function. This will be used in the later
"FOR ALL TABLES IN SCHEMA" implementation patch.
---
 src/backend/catalog/pg_publication.c   | 66 ++++++++++++++++++++--------------
 src/backend/commands/publicationcmds.c | 42 +++++++++++-----------
 src/include/commands/publicationcmds.h |  5 +++
 3 files changed, 66 insertions(+), 47 deletions(-)

diff --git a/src/backend/catalog/pg_publication.c b/src/backend/catalog/pg_publication.c
index 2a2fe03..a587e09 100644
--- a/src/backend/catalog/pg_publication.c
+++ b/src/backend/catalog/pg_publication.c
@@ -136,6 +136,42 @@ pg_relation_is_publishable(PG_FUNCTION_ARGS)
 	PG_RETURN_BOOL(result);
 }
 
+/*
+ * Gets the relations based on the publication partition option for a specified
+ * relation.
+ */
+static List *
+GetPubPartitionOptionRelations(List *result, PublicationPartOpt pub_partopt,
+							   Oid relid)
+{
+	if (get_rel_relkind(relid) == RELKIND_PARTITIONED_TABLE &&
+		pub_partopt != PUBLICATION_PART_ROOT)
+	{
+		List	   *all_parts = find_all_inheritors(relid, NoLock,
+													NULL);
+
+		if (pub_partopt == PUBLICATION_PART_ALL)
+			result = list_concat(result, all_parts);
+		else if (pub_partopt == PUBLICATION_PART_LEAF)
+		{
+			ListCell   *lc;
+
+			foreach(lc, all_parts)
+			{
+				Oid			partOid = lfirst_oid(lc);
+
+				if (get_rel_relkind(partOid) != RELKIND_PARTITIONED_TABLE)
+					result = lappend_oid(result, partOid);
+			}
+		}
+		else
+			Assert(false);
+	}
+	else
+		result = lappend_oid(result, relid);
+
+	return result;
+}
 
 /*
  * Insert new publication / relation mapping.
@@ -241,7 +277,7 @@ GetRelationPublications(Oid relid)
 /*
  * Gets list of relation oids for a publication.
  *
- * This should only be used for normal publications, the FOR ALL TABLES
+ * This should only be used FOR TABLE publications, the FOR ALL TABLES
  * should use GetAllTablesPublicationRelations().
  */
 List *
@@ -270,32 +306,8 @@ GetPublicationRelations(Oid pubid, PublicationPartOpt pub_partopt)
 		Form_pg_publication_rel pubrel;
 
 		pubrel = (Form_pg_publication_rel) GETSTRUCT(tup);
-
-		if (get_rel_relkind(pubrel->prrelid) == RELKIND_PARTITIONED_TABLE &&
-			pub_partopt != PUBLICATION_PART_ROOT)
-		{
-			List	   *all_parts = find_all_inheritors(pubrel->prrelid, NoLock,
-														NULL);
-
-			if (pub_partopt == PUBLICATION_PART_ALL)
-				result = list_concat(result, all_parts);
-			else if (pub_partopt == PUBLICATION_PART_LEAF)
-			{
-				ListCell   *lc;
-
-				foreach(lc, all_parts)
-				{
-					Oid			partOid = lfirst_oid(lc);
-
-					if (get_rel_relkind(partOid) != RELKIND_PARTITIONED_TABLE)
-						result = lappend_oid(result, partOid);
-				}
-			}
-			else
-				Assert(false);
-		}
-		else
-			result = lappend_oid(result, pubrel->prrelid);
+		result = GetPubPartitionOptionRelations(result, pub_partopt,
+												pubrel->prrelid);
 	}
 
 	systable_endscan(scan);
diff --git a/src/backend/commands/publicationcmds.c b/src/backend/commands/publicationcmds.c
index 8487eeb..e1d17f6 100644
--- a/src/backend/commands/publicationcmds.c
+++ b/src/backend/commands/publicationcmds.c
@@ -45,9 +45,6 @@
 #include "utils/syscache.h"
 #include "utils/varlena.h"
 
-/* Same as MAXNUMMESSAGES in sinvaladt.c */
-#define MAX_RELCACHE_INVAL_MSGS 4096
-
 static List *OpenTableList(List *tables);
 static void CloseTableList(List *rels);
 static void PublicationAddTables(Oid pubid, List *rels, bool if_not_exists,
@@ -324,23 +321,7 @@ AlterPublicationOptions(ParseState *pstate, AlterPublicationStmt *stmt,
 		List	   *relids = GetPublicationRelations(pubform->oid,
 													 PUBLICATION_PART_ALL);
 
-		/*
-		 * We don't want to send too many individual messages, at some point
-		 * it's cheaper to just reset whole relcache.
-		 */
-		if (list_length(relids) < MAX_RELCACHE_INVAL_MSGS)
-		{
-			ListCell   *lc;
-
-			foreach(lc, relids)
-			{
-				Oid			relid = lfirst_oid(lc);
-
-				CacheInvalidateRelcacheByRelid(relid);
-			}
-		}
-		else
-			CacheInvalidateRelcacheAll();
+		InvalidatePublicationRels(relids);
 	}
 
 	ObjectAddressSet(obj, PublicationRelationId, pubform->oid);
@@ -351,6 +332,27 @@ AlterPublicationOptions(ParseState *pstate, AlterPublicationStmt *stmt,
 }
 
 /*
+ * Invalidate the relations.
+ */
+void
+InvalidatePublicationRels(List *relids)
+{
+	/*
+	 * We don't want to send too many individual messages, at some point it's
+	 * cheaper to just reset whole relcache.
+	 */
+	if (list_length(relids) < MAX_RELCACHE_INVAL_MSGS)
+	{
+		ListCell   *lc;
+
+		foreach(lc, relids)
+			CacheInvalidateRelcacheByRelid(lfirst_oid(lc));
+	}
+	else
+		CacheInvalidateRelcacheAll();
+}
+
+/*
  * Add or remove table to/from publication.
  */
 static void
diff --git a/src/include/commands/publicationcmds.h b/src/include/commands/publicationcmds.h
index a3fa2ac..fa47d6d 100644
--- a/src/include/commands/publicationcmds.h
+++ b/src/include/commands/publicationcmds.h
@@ -17,6 +17,10 @@
 
 #include "catalog/objectaddress.h"
 #include "parser/parse_node.h"
+#include "utils/inval.h"
+
+/* Same as MAXNUMMESSAGES in sinvaladt.c */
+#define MAX_RELCACHE_INVAL_MSGS 4096
 
 extern ObjectAddress CreatePublication(ParseState *pstate, CreatePublicationStmt *stmt);
 extern void AlterPublication(ParseState *pstate, AlterPublicationStmt *stmt);
@@ -24,5 +28,6 @@ extern void RemovePublicationRelById(Oid proid);
 
 extern ObjectAddress AlterPublicationOwner(const char *name, Oid newOwnerId);
 extern void AlterPublicationOwner_oid(Oid pubid, Oid newOwnerId);
+extern void InvalidatePublicationRels(List *relids);
 
 #endif							/* PUBLICATIONCMDS_H */
-- 
2.7.2.windows.1

