diff --git a/doc/src/sgml/ref/alter_subscription.sgml b/doc/src/sgml/ref/alter_subscription.sgml
index bead996..5f4d40a 100644
--- a/doc/src/sgml/ref/alter_subscription.sgml
+++ b/doc/src/sgml/ref/alter_subscription.sgml
@@ -48,6 +48,13 @@ ALTER SUBSCRIPTION name RENAME TO <
(Currently, all subscription owners must be superusers, so the owner checks
will be bypassed in practice. But this might change in the future.)
+
+
+ ALTER SUBSCRIPTION ... SET PUBLCIATION with
+ refresh option and
+ ALTER SUBSCRIPTION ... REFRESH PUBLICATION cannot be
+ executed inside a transaction block.
+
diff --git a/src/backend/commands/subscriptioncmds.c b/src/backend/commands/subscriptioncmds.c
index 5aae7b6..6f3f4a6 100644
--- a/src/backend/commands/subscriptioncmds.c
+++ b/src/backend/commands/subscriptioncmds.c
@@ -612,7 +612,7 @@ AlterSubscription_refresh(Subscription *sub, bool copy_data)
* Alter the existing subscription.
*/
ObjectAddress
-AlterSubscription(AlterSubscriptionStmt *stmt)
+AlterSubscription(AlterSubscriptionStmt *stmt, bool isTopLevel)
{
Relation rel;
ObjectAddress myself;
@@ -743,6 +743,15 @@ AlterSubscription(AlterSubscriptionStmt *stmt)
/* Refresh if user asked us to. */
if (refresh)
{
+ /*
+ * Since stopping table sync worker is not transactional, the table
+ * sync worker is stopped even if the transaction rolls back. So we
+ * cannot run ALTER SUBSCRIPTION SET PUBLICATION with refresh option
+ * and ALTER SUBSCRIPTION REFRESH PUBLICATION (see below) inside a
+ * transaction block if refresh option is specified.
+ */
+ PreventTransactionChain(isTopLevel, "ALTER SUBSCRIPTION ... SET PUBLICATION ... WITH (refresh = true)");
+
if (!sub->enabled)
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
@@ -762,6 +771,12 @@ AlterSubscription(AlterSubscriptionStmt *stmt)
{
bool copy_data;
+ /*
+ * As same resason as above description at ALTER_SUBSCRIPTION_PUBLICATION,
+ * we cannot run this command inside a transaction block
+ */
+ PreventTransactionChain(isTopLevel, "ALTER SUBSCRIPTION ... REFRESH PUBLICATION");
+
if (!sub->enabled)
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c
index a22fd53..db4e192 100644
--- a/src/backend/tcop/utility.c
+++ b/src/backend/tcop/utility.c
@@ -1626,7 +1626,7 @@ ProcessUtilitySlow(ParseState *pstate,
break;
case T_AlterSubscriptionStmt:
- address = AlterSubscription((AlterSubscriptionStmt *) parsetree);
+ address = AlterSubscription((AlterSubscriptionStmt *) parsetree, isTopLevel);
break;
case T_DropSubscriptionStmt:
diff --git a/src/include/commands/subscriptioncmds.h b/src/include/commands/subscriptioncmds.h
index 1e4428e..f5a9e28 100644
--- a/src/include/commands/subscriptioncmds.h
+++ b/src/include/commands/subscriptioncmds.h
@@ -20,7 +20,7 @@
extern ObjectAddress CreateSubscription(CreateSubscriptionStmt *stmt,
bool isTopLevel);
-extern ObjectAddress AlterSubscription(AlterSubscriptionStmt *stmt);
+extern ObjectAddress AlterSubscription(AlterSubscriptionStmt *stmt, bool isTopLevel);
extern void DropSubscription(DropSubscriptionStmt *stmt, bool isTopLevel);
extern ObjectAddress AlterSubscriptionOwner(const char *name, Oid newOwnerId);
diff --git a/src/test/regress/expected/subscription.out b/src/test/regress/expected/subscription.out
index 4fcbf7e..6cc33a1 100644
--- a/src/test/regress/expected/subscription.out
+++ b/src/test/regress/expected/subscription.out
@@ -141,6 +141,16 @@ HINT: The owner of a subscription must be a superuser.
ALTER ROLE regress_subscription_user2 SUPERUSER;
-- now it works
ALTER SUBSCRIPTION testsub OWNER TO regress_subscription_user2;
+-- fail - cannot do ALTER SUBSCRIPTION ... SET PUBLICATION inside transaction block with refreshing
+BEGIN;
+ALTER SUBSCRIPTION testsub SET PUBLICATION testpub WITH (refresh = true);
+ERROR: ALTER SUBSCRIPTION ... SET PUBLICATION ... WITH (refresh = true) cannot run inside a transaction block
+COMMIT;
+-- fail - cannot do ALTER SUBSCRIPTION ... REFRESH PUBLICATION inside transaction block
+BEGIN;
+ALTER SUBSCRIPTION testsub REFRESH PUBLICATION;
+ERROR: ALTER SUBSCRIPTION ... REFRESH PUBLICATION cannot run inside a transaction block
+COMMIT;
-- fail - cannot do DROP SUBSCRIPTION inside transaction block with slot name
BEGIN;
DROP SUBSCRIPTION testsub;
diff --git a/src/test/regress/sql/subscription.sql b/src/test/regress/sql/subscription.sql
index 36fa1bb..aa14cae 100644
--- a/src/test/regress/sql/subscription.sql
+++ b/src/test/regress/sql/subscription.sql
@@ -102,6 +102,16 @@ ALTER ROLE regress_subscription_user2 SUPERUSER;
-- now it works
ALTER SUBSCRIPTION testsub OWNER TO regress_subscription_user2;
+-- fail - cannot do ALTER SUBSCRIPTION ... SET PUBLICATION inside transaction block with refreshing
+BEGIN;
+ALTER SUBSCRIPTION testsub SET PUBLICATION testpub WITH (refresh = true);
+COMMIT;
+
+-- fail - cannot do ALTER SUBSCRIPTION ... REFRESH PUBLICATION inside transaction block
+BEGIN;
+ALTER SUBSCRIPTION testsub REFRESH PUBLICATION;
+COMMIT;
+
-- fail - cannot do DROP SUBSCRIPTION inside transaction block with slot name
BEGIN;
DROP SUBSCRIPTION testsub;