From 6e4200c2e4acfcf90a4aaa835259ae4843b2cdcc Mon Sep 17 00:00:00 2001
From: Hou Zhijie <houzj.fnst@cn.fujitsu.com>
Date: Tue, 11 Mar 2025 18:13:49 +0800
Subject: [PATCH] refactor

---
 src/backend/commands/alter.c           | 20 ++++++-
 src/backend/commands/publicationcmds.c | 83 +++-----------------------
 src/backend/parser/gram.y              |  2 +-
 src/include/commands/publicationcmds.h |  3 +-
 4 files changed, 29 insertions(+), 79 deletions(-)

diff --git a/src/backend/commands/alter.c b/src/backend/commands/alter.c
index a79329acc1f..838a264f474 100644
--- a/src/backend/commands/alter.c
+++ b/src/backend/commands/alter.c
@@ -306,6 +306,22 @@ AlterObjectRename_internal(Relation rel, Oid objectId, const char *new_name)
 		/* Wake up related replication workers to handle this change quickly */
 		LogicalRepWorkersWakeupAtCommit(objectId);
 	}
+	else if (classId == PublicationRelationId)
+	{
+		Form_pg_publication pub = (Form_pg_publication) GETSTRUCT(oldtup);
+
+		if (SearchSysCacheExists1(PUBLICATIONNAME, CStringGetDatum(new_name)))
+			report_name_conflict(classId, new_name);
+
+		/*
+		 * Unlike ALTER PUBLICATION ADD/SET/DROP commands, renaming a
+		 * publication does not impact the publication status of tables.
+		 * Therefore, we do not need to invalidate relcache to rebuild the
+		 * rd_pubdesc. Instead, we invalidate only the cache within the output
+		 * plugin to ensure its cache is rebuilt.
+		 */
+		InvalidatePubRelSyncCaches(pub->oid, pub->puballtables);
+	}
 	else if (nameCacheId >= 0)
 	{
 		if (OidIsValid(namespaceId))
@@ -400,9 +416,6 @@ ExecRenameStmt(RenameStmt *stmt)
 		case OBJECT_TYPE:
 			return RenameType(stmt);
 
-		case OBJECT_PUBLICATION:
-			return RenamePublication(stmt->subname, stmt->newname);
-
 		case OBJECT_AGGREGATE:
 		case OBJECT_COLLATION:
 		case OBJECT_CONVERSION:
@@ -420,6 +433,7 @@ ExecRenameStmt(RenameStmt *stmt)
 		case OBJECT_TSDICTIONARY:
 		case OBJECT_TSPARSER:
 		case OBJECT_TSTEMPLATE:
+		case OBJECT_PUBLICATION:
 		case OBJECT_SUBSCRIPTION:
 			{
 				ObjectAddress address;
diff --git a/src/backend/commands/publicationcmds.c b/src/backend/commands/publicationcmds.c
index b1e38ed7822..e18d2d06862 100644
--- a/src/backend/commands/publicationcmds.c
+++ b/src/backend/commands/publicationcmds.c
@@ -492,71 +492,15 @@ pub_contains_invalid_column(Oid pubid, Relation relation, List *ancestors,
 }
 
 /*
- * Execute ALTER PUBLICATION RENAME
+ * Invalidate entries in the RelationSyncCache for relations included in the
+ * specified publication, either via FOR TABLE or FOR TABLES IN SCHEMA.
+ *
+ * If 'puballtables' is true, invalidate all cache entries.
  */
-ObjectAddress
-RenamePublication(const char *oldname, const char *newname)
+void
+InvalidatePubRelSyncCaches(Oid pubid, bool puballtables)
 {
-	Relation			rel;
-	HeapTuple			tup;
-	ObjectAddress		address;
-	Form_pg_publication	pubform;
-	bool				replaces[Natts_pg_publication];
-	bool				nulls[Natts_pg_publication];
-	Datum				values[Natts_pg_publication];
-
-	rel = table_open(PublicationRelationId, RowExclusiveLock);
-
-	tup = SearchSysCacheCopy1(PUBLICATIONNAME,
-							  CStringGetDatum(oldname));
-
-	if (!HeapTupleIsValid(tup))
-		ereport(ERROR,
-				(errcode(ERRCODE_UNDEFINED_OBJECT),
-				 errmsg("publication \"%s\" does not exist",
-						oldname)));
-
-	pubform = (Form_pg_publication) GETSTRUCT(tup);
-
-	/* must be owner */
-	if (!object_ownercheck(PublicationRelationId, pubform->oid, GetUserId()))
-		aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_PUBLICATION,
-					   NameStr(pubform->pubname));
-
-	/* Check if name is used */
-	if (OidIsValid(GetSysCacheOid1(PUBLICATIONNAME, Anum_pg_publication_oid,
-								   CStringGetDatum(newname))))
-		ereport(ERROR,
-				(errcode(ERRCODE_DUPLICATE_OBJECT),
-				 errmsg("publication \"%s\" already exists",
-				 newname)));
-
-	/* Everything ok, form a new tuple. */
-	memset(values, 0, sizeof(values));
-	memset(nulls, false, sizeof(nulls));
-	memset(replaces, false, sizeof(replaces));
-
-	/* Only update the pubname */
-	values[Anum_pg_publication_pubname - 1] =
-		DirectFunctionCall1(namein, CStringGetDatum(newname));
-	replaces[Anum_pg_publication_pubname - 1] = true;
-
-	tup = heap_modify_tuple(tup, RelationGetDescr(rel), values, nulls,
-							replaces);
-
-	/* Update the catalog. */
-	CatalogTupleUpdate(rel, &tup->t_self, tup);
-
-	/*
-	 * Invalidate caches on the logical decoding output plugin.
-	 *
-	 * Apart from the ALTER PUBLICATION ADD/SET/DROP commands, we do not have
-	 * to invalidate relcaches. They are required to refresh the publication's
-	 * descriptor. The publication's name is not recorded in the attribute, so
-	 * the RENAME commands do not require a refresh. Instead, we only
-	 * invalidate a cache on the output plugin to rebuild its cache.
-	 */
-	if (pubform->puballtables)
+	if (puballtables)
 	{
 		CacheInvalidateRelSyncAll();
 	}
@@ -571,23 +515,14 @@ RenamePublication(const char *oldname, const char *newname)
 		 * tables as a target. However, WAL records for TRUNCATE specify
 		 * both a root and its leaves.
 		 */
-		relids = GetPublicationRelations(pubform->oid,
-										 PUBLICATION_PART_ALL);
-		schemarelids = GetAllSchemaPublicationRelations(pubform->oid,
+		relids = GetPublicationRelations(pubid, PUBLICATION_PART_ALL);
+		schemarelids = GetAllSchemaPublicationRelations(pubid,
 														PUBLICATION_PART_ALL);
 
 		relids = list_concat_unique_oid(relids, schemarelids);
 
 		InvalidateRelSyncCaches(relids);
 	}
-
-	ObjectAddressSet(address, PublicationRelationId, pubform->oid);
-
-	heap_freetuple(tup);
-
-	table_close(rel, RowExclusiveLock);
-
-	return address;
 }
 
 /* check_functions_in_node callback */
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index 0fb4041f15b..271ae26cbaf 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -9541,7 +9541,7 @@ RenameStmt: ALTER AGGREGATE aggregate_with_argtypes RENAME TO name
 					RenameStmt *n = makeNode(RenameStmt);
 
 					n->renameType = OBJECT_PUBLICATION;
-					n->subname = $3;
+					n->object = (Node *) makeString($3);
 					n->newname = $6;
 					n->missing_ok = false;
 					$$ = (Node *) n;
diff --git a/src/include/commands/publicationcmds.h b/src/include/commands/publicationcmds.h
index f130ea3090a..ca55d2fe315 100644
--- a/src/include/commands/publicationcmds.h
+++ b/src/include/commands/publicationcmds.h
@@ -38,7 +38,8 @@ extern bool pub_contains_invalid_column(Oid pubid, Relation relation,
 										char pubgencols_type,
 										bool *invalid_column_list,
 										bool *invalid_gen_col);
-extern ObjectAddress RenamePublication(const char *oldname, const char *newname);
+extern void InvalidatePubRelSyncCaches(Oid pubid, bool puballtables);
+
 extern void InvalidateRelSyncCaches(List *relids);
 
 #endif							/* PUBLICATIONCMDS_H */
-- 
2.30.0.windows.2

