v1-0001-Disallow-alter-subscription-s-failover-option-ins.patch

application/octet-stream

Filename: v1-0001-Disallow-alter-subscription-s-failover-option-ins.patch
Type: application/octet-stream
Part: 0
Message: Disallow changing slot's failover option in transaction block

Patch

Format: format-patch
Series: patch v1-0001
Subject: Disallow alter subscription's failover option inside a transaction block
File+
src/backend/commands/subscriptioncmds.c 9 0
src/test/regress/expected/subscription.out 5 0
src/test/regress/sql/subscription.sql 5 0
From d792ab2fa2aefb8842774aa44478eebd35851abf Mon Sep 17 00:00:00 2001
From: Hou Zhijie <houzj.fnst@cn.fujitsu.com>
Date: Tue, 16 Apr 2024 11:31:32 +0800
Subject: [PATCH v1] Disallow alter subscription's failover option inside a
 transaction block

Disallow ALTER SUBSCRIPTION in a transaction block when the replication slot is
to be altered, since that cannot be rolled back.
---
 src/backend/commands/subscriptioncmds.c    | 9 +++++++++
 src/test/regress/expected/subscription.out | 5 +++++
 src/test/regress/sql/subscription.sql      | 5 +++++
 3 files changed, 19 insertions(+)

diff --git a/src/backend/commands/subscriptioncmds.c b/src/backend/commands/subscriptioncmds.c
index 5a47fa984d..9fa5f4e5b4 100644
--- a/src/backend/commands/subscriptioncmds.c
+++ b/src/backend/commands/subscriptioncmds.c
@@ -1267,6 +1267,15 @@ AlterSubscription(ParseState *pstate, AlterSubscriptionStmt *stmt,
 								 errmsg("cannot set %s for enabled subscription",
 										"failover")));
 
+					/*
+					 * Since altering a replication slot is not transactional,
+					 * rolling back the transaction leaves the altered
+					 * replication slot.  So we cannot run ALTER SUBSCRIPTION
+					 * inside a transaction block if altering a replication
+					 * slot's failover option.
+					 */
+					PreventInTransactionBlock(isTopLevel, "ALTER SUBSCRIPTION ... SET (failover)");
+
 					values[Anum_pg_subscription_subfailover - 1] =
 						BoolGetDatum(opts.failover);
 					replaces[Anum_pg_subscription_subfailover - 1] = true;
diff --git a/src/test/regress/expected/subscription.out b/src/test/regress/expected/subscription.out
index 1eee6b17b8..0e6c408be3 100644
--- a/src/test/regress/expected/subscription.out
+++ b/src/test/regress/expected/subscription.out
@@ -472,6 +472,11 @@ REVOKE CREATE ON DATABASE REGRESSION FROM regress_subscription_user3;
 SET SESSION AUTHORIZATION regress_subscription_user3;
 ALTER SUBSCRIPTION regress_testsub RENAME TO regress_testsub2;
 ERROR:  permission denied for database regression
+-- fail - cannot do ALTER SUBSCRIPTION SET (failover) inside transaction block
+BEGIN;
+ALTER SUBSCRIPTION regress_testsub SET (failover);
+ERROR:  ALTER SUBSCRIPTION ... SET (failover) cannot run inside a transaction block
+COMMIT;
 -- ok, owning it is enough for this stuff
 ALTER SUBSCRIPTION regress_testsub SET (slot_name = NONE);
 DROP SUBSCRIPTION regress_testsub;
diff --git a/src/test/regress/sql/subscription.sql b/src/test/regress/sql/subscription.sql
index 1b2a23ba7b..07413d7e81 100644
--- a/src/test/regress/sql/subscription.sql
+++ b/src/test/regress/sql/subscription.sql
@@ -333,6 +333,11 @@ REVOKE CREATE ON DATABASE REGRESSION FROM regress_subscription_user3;
 SET SESSION AUTHORIZATION regress_subscription_user3;
 ALTER SUBSCRIPTION regress_testsub RENAME TO regress_testsub2;
 
+-- fail - cannot do ALTER SUBSCRIPTION SET (failover) inside transaction block
+BEGIN;
+ALTER SUBSCRIPTION regress_testsub SET (failover);
+COMMIT;
+
 -- ok, owning it is enough for this stuff
 ALTER SUBSCRIPTION regress_testsub SET (slot_name = NONE);
 DROP SUBSCRIPTION regress_testsub;
-- 
2.31.1