From 9c4b0d3151636ead880e52d4e7b06565d8a6525d Mon Sep 17 00:00:00 2001
From: Tomas Vondra <tomas@2ndquadrant.com>
Date: Sun, 2 Apr 2023 19:02:13 +0200
Subject: [PATCH 6/8] Support LOCK for sequences, instead of function

---
 src/backend/commands/lockcmds.c             |  4 ++--
 src/backend/commands/sequence.c             | 19 -------------------
 src/backend/replication/logical/tablesync.c | 11 +++++------
 src/include/catalog/pg_proc.dat             |  4 ----
 4 files changed, 7 insertions(+), 31 deletions(-)

diff --git a/src/backend/commands/lockcmds.c b/src/backend/commands/lockcmds.c
index 43c7d7f4bb2..38b4a66693e 100644
--- a/src/backend/commands/lockcmds.c
+++ b/src/backend/commands/lockcmds.c
@@ -85,9 +85,9 @@ RangeVarCallbackForLockTable(const RangeVar *rv, Oid relid, Oid oldrelid,
 		return;					/* woops, concurrently dropped; no permissions
 								 * check */
 
-	/* Currently, we only allow plain tables or views to be locked */
+	/* Currently, we only allow plain tables, views or sequences to be locked */
 	if (relkind != RELKIND_RELATION && relkind != RELKIND_PARTITIONED_TABLE &&
-		relkind != RELKIND_VIEW)
+		relkind != RELKIND_VIEW && relkind != RELKIND_SEQUENCE)
 		ereport(ERROR,
 				(errcode(ERRCODE_WRONG_OBJECT_TYPE),
 				 errmsg("cannot lock relation \"%s\"",
diff --git a/src/backend/commands/sequence.c b/src/backend/commands/sequence.c
index ee041a6e5c0..be13991eb75 100644
--- a/src/backend/commands/sequence.c
+++ b/src/backend/commands/sequence.c
@@ -2027,25 +2027,6 @@ pg_sequence_last_value(PG_FUNCTION_ARGS)
 		PG_RETURN_NULL();
 }
 
-Datum
-pg_sequence_lock_for_sync(PG_FUNCTION_ARGS)
-{
-	Oid			relid = PG_GETARG_OID(0);
-	Relation	seqrel;
-
-	seqrel = relation_open(relid, RowExclusiveLock);
-
-	if (seqrel->rd_rel->relkind != RELKIND_SEQUENCE)
-		ereport(ERROR,
-				(errcode(ERRCODE_WRONG_OBJECT_TYPE),
-				 errmsg("\"%s\" is not a sequence",
-						RelationGetRelationName(seqrel))));
-
-	/* close the relation, but keep the lock */
-	relation_close(seqrel, NoLock);
-
-	PG_RETURN_VOID();
-}
 
 void
 seq_redo(XLogReaderState *record)
diff --git a/src/backend/replication/logical/tablesync.c b/src/backend/replication/logical/tablesync.c
index 85ae8f5a32e..89c0c94159b 100644
--- a/src/backend/replication/logical/tablesync.c
+++ b/src/backend/replication/logical/tablesync.c
@@ -1527,7 +1527,6 @@ LogicalRepSyncTableStart(XLogRecPtr *origin_startpos)
 	if (get_rel_relkind(RelationGetRelid(rel)) == RELKIND_SEQUENCE)
 	{
 		StringInfoData	cmd;
-		Oid				lockRow[] = {VOIDOID};
 
 		initStringInfo(&cmd);
 
@@ -1535,13 +1534,13 @@ LogicalRepSyncTableStart(XLogRecPtr *origin_startpos)
 		 * XXX maybe this should do fetch_remote_table_info and use the relation
 		 * and namespace names from the result?
 		 */
-		appendStringInfo(&cmd, "SELECT pg_catalog.pg_sequence_lock_for_sync('%s')",
+		appendStringInfo(&cmd, "LOCK %s IN ROW EXCLUSIVE MODE",
 						 quote_qualified_identifier(get_namespace_name(RelationGetNamespace(rel)),
 													RelationGetRelationName(rel)));
-		elog(LOG, "locking: %s", cmd.data);
-		res = walrcv_exec(LogRepWorkerWalRcvConn,
-						  cmd.data, 1, lockRow);
-		if (res->status != WALRCV_OK_TUPLES)
+
+		res = walrcv_exec(LogRepWorkerWalRcvConn, cmd.data, 0, NULL);
+
+		if (res->status != WALRCV_OK_COMMAND)
 			ereport(ERROR,
 					(errcode(ERRCODE_CONNECTION_FAILURE),
 					 errmsg("sequence copy failed to lock on publisher: %s",
diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat
index 7957c028487..49251b0b7b4 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -12058,8 +12058,4 @@
   proname => 'any_value_transfn', prorettype => 'anyelement',
   proargtypes => 'anyelement anyelement', prosrc => 'any_value_transfn' },
 
-{ oid => '8003', descr => 'lock sequence for logical replication sync',
-  proname => 'pg_sequence_lock_for_sync', prorettype => 'void',
-  proargtypes => 'regclass', prosrc => 'pg_sequence_lock_for_sync' },
-
 ]
-- 
2.39.2

