From 7fe5c8a1854747ce3e14cb9ab0a5a3dc730ae166 Mon Sep 17 00:00:00 2001
From: Hayato Kuroda <kuroda.hayato@fujitsu.com>
Date: Wed, 19 Feb 2025 11:37:26 +0900
Subject: [PATCH v2] Prohibit slot operations while in the single user mode

---
 src/backend/replication/slotfuncs.c | 31 +++++++++++++++++++++++++++++
 1 file changed, 31 insertions(+)

diff --git a/src/backend/replication/slotfuncs.c b/src/backend/replication/slotfuncs.c
index f652ec8a73..70c01db891 100644
--- a/src/backend/replication/slotfuncs.c
+++ b/src/backend/replication/slotfuncs.c
@@ -17,6 +17,7 @@
 #include "access/xlogrecovery.h"
 #include "access/xlogutils.h"
 #include "funcapi.h"
+#include "miscadmin.h"
 #include "replication/logical.h"
 #include "replication/slot.h"
 #include "replication/slotsync.h"
@@ -73,6 +74,12 @@ pg_create_physical_replication_slot(PG_FUNCTION_ARGS)
 	HeapTuple	tuple;
 	Datum		result;
 
+	if (!IsUnderPostmaster)
+		ereport(ERROR,
+				(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
+				 errmsg("cannot use %s in single-user mode",
+						"pg_create_physical_replication_slot")));
+
 	if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
 		elog(ERROR, "return type must be a row type");
 
@@ -179,6 +186,12 @@ pg_create_logical_replication_slot(PG_FUNCTION_ARGS)
 	Datum		values[2];
 	bool		nulls[2];
 
+	if (!IsUnderPostmaster)
+		ereport(ERROR,
+				(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
+				 errmsg("cannot use %s in single-user mode",
+						"pg_create_logical_replication_slot")));
+
 	if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
 		elog(ERROR, "return type must be a row type");
 
@@ -515,6 +528,12 @@ pg_replication_slot_advance(PG_FUNCTION_ARGS)
 
 	Assert(!MyReplicationSlot);
 
+	if (!IsUnderPostmaster)
+		ereport(ERROR,
+				(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
+				 errmsg("cannot use %s in single-user mode",
+						"pg_replication_slot_advance")));
+
 	CheckSlotPermissions();
 
 	if (XLogRecPtrIsInvalid(moveto))
@@ -612,6 +631,12 @@ copy_replication_slot(FunctionCallInfo fcinfo, bool logical_slot)
 	TupleDesc	tupdesc;
 	HeapTuple	tuple;
 
+	if (!IsUnderPostmaster)
+		ereport(ERROR,
+				(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
+				 errmsg("cannot use %s in single-user mode",
+						"pg_copy_replication_slot")));
+
 	if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
 		elog(ERROR, "return type must be a row type");
 
@@ -866,6 +891,12 @@ pg_sync_replication_slots(PG_FUNCTION_ARGS)
 	char	   *err;
 	StringInfoData app_name;
 
+	if (!IsUnderPostmaster)
+		ereport(ERROR,
+				(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
+				 errmsg("cannot use %s in single-user mode",
+						"pg_sync_replication_slots")));
+
 	CheckSlotPermissions();
 
 	if (!RecoveryInProgress())
-- 
2.43.5

