diff --git a/doc/src/sgml/ref/alter_subscription.sgml b/doc/src/sgml/ref/alter_subscription.sgml
index 032ecbb..2a4eb58 100644
--- a/doc/src/sgml/ref/alter_subscription.sgml
+++ b/doc/src/sgml/ref/alter_subscription.sgml
@@ -48,6 +48,11 @@ ALTER SUBSCRIPTION name DISABLE
To alter the owner, you must also be a direct or indirect member of the
new owning role. The new owner has to be a superuser
+
+
+ ALTER SUBSCRIPTION cannot be executed inside a
+ transaciton block.
+
diff --git a/doc/src/sgml/ref/create_subscription.sgml b/doc/src/sgml/ref/create_subscription.sgml
index 59e5ad0..6480690 100644
--- a/doc/src/sgml/ref/create_subscription.sgml
+++ b/doc/src/sgml/ref/create_subscription.sgml
@@ -47,8 +47,9 @@ CREATE SUBSCRIPTION subscription_name
- A logical replication worker will be started to replicate data for the new
- subscription at the commit of the transaction where this command is run.
+ CREATE SUBSCRIPTION cannot be executed inside a
+ transaction block. A logical replication worker will be started to replicate
+ data for the new subscription at the end of this command.
diff --git a/doc/src/sgml/ref/drop_subscription.sgml b/doc/src/sgml/ref/drop_subscription.sgml
index 9f2fb93..17235ad 100644
--- a/doc/src/sgml/ref/drop_subscription.sgml
+++ b/doc/src/sgml/ref/drop_subscription.sgml
@@ -38,8 +38,8 @@ DROP SUBSCRIPTION [ IF EXISTS ] name
- The replication worker associated with the subscription will not stop until
- after the transaction that issued this command has committed.
+ DROP SUBSCRIPTION cannot be executed inside a
+ transaction block.
diff --git a/src/backend/commands/subscriptioncmds.c b/src/backend/commands/subscriptioncmds.c
index ab21e64..6903a15 100644
--- a/src/backend/commands/subscriptioncmds.c
+++ b/src/backend/commands/subscriptioncmds.c
@@ -18,6 +18,7 @@
#include "access/heapam.h"
#include "access/htup_details.h"
+#include "access/xact.h"
#include "catalog/indexing.h"
#include "catalog/objectaccess.h"
@@ -204,7 +205,7 @@ publicationListToArray(List *publist)
* Create new subscription.
*/
ObjectAddress
-CreateSubscription(CreateSubscriptionStmt *stmt)
+CreateSubscription(CreateSubscriptionStmt *stmt, bool isTopLevel)
{
Relation rel;
ObjectAddress myself;
@@ -221,6 +222,12 @@ CreateSubscription(CreateSubscriptionStmt *stmt)
bool create_slot;
List *publications;
+ /*
+ * We cannot run CREATE SUBSCRIPTION inside a user transaction
+ * block.
+ */
+ PreventTransactionChain(isTopLevel, "CREATE SUBSCRIPTION");
+
if (!superuser())
ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
@@ -335,7 +342,7 @@ CreateSubscription(CreateSubscriptionStmt *stmt)
* Alter the existing subscription.
*/
ObjectAddress
-AlterSubscription(AlterSubscriptionStmt *stmt)
+AlterSubscription(AlterSubscriptionStmt *stmt, bool isTopLevel)
{
Relation rel;
ObjectAddress myself;
@@ -350,6 +357,12 @@ AlterSubscription(AlterSubscriptionStmt *stmt)
char *slot_name;
List *publications;
+ /*
+ * We cannot run CREATE SUBSCRIPTION inside a user transaction
+ * block.
+ */
+ PreventTransactionChain(isTopLevel, "ALTER SUBSCRIPTION");
+
rel = heap_open(SubscriptionRelationId, RowExclusiveLock);
/* Fetch the existing tuple. */
@@ -424,7 +437,7 @@ AlterSubscription(AlterSubscriptionStmt *stmt)
* Drop a subscription
*/
void
-DropSubscription(DropSubscriptionStmt *stmt)
+DropSubscription(DropSubscriptionStmt *stmt, bool isTopLevel)
{
Relation rel;
ObjectAddress myself;
@@ -441,6 +454,12 @@ DropSubscription(DropSubscriptionStmt *stmt)
WalReceiverConn *wrconn = NULL;
StringInfoData cmd;
+ /*
+ * We cannot run DROP SUBSCRIPTION inside a user transaction
+ * block.
+ */
+ PreventTransactionChain(isTopLevel, "DROP SUBSCRIPTION");
+
rel = heap_open(SubscriptionRelationId, RowExclusiveLock);
tup = SearchSysCache2(SUBSCRIPTIONNAME, MyDatabaseId,
diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c
index 5d3be38..a9856ad 100644
--- a/src/backend/tcop/utility.c
+++ b/src/backend/tcop/utility.c
@@ -1608,15 +1608,17 @@ ProcessUtilitySlow(ParseState *pstate,
break;
case T_CreateSubscriptionStmt:
- address = CreateSubscription((CreateSubscriptionStmt *) parsetree);
+ address = CreateSubscription((CreateSubscriptionStmt *) parsetree,
+ isTopLevel);
break;
case T_AlterSubscriptionStmt:
- address = AlterSubscription((AlterSubscriptionStmt *) parsetree);
+ address = AlterSubscription((AlterSubscriptionStmt *) parsetree,
+ isTopLevel);
break;
case T_DropSubscriptionStmt:
- DropSubscription((DropSubscriptionStmt *) parsetree);
+ DropSubscription((DropSubscriptionStmt *) parsetree, isTopLevel);
/* no commands stashed for DROP */
commandCollected = true;
break;
diff --git a/src/include/commands/subscriptioncmds.h b/src/include/commands/subscriptioncmds.h
index 127696c..4d8470f 100644
--- a/src/include/commands/subscriptioncmds.h
+++ b/src/include/commands/subscriptioncmds.h
@@ -18,9 +18,11 @@
#include "catalog/objectaddress.h"
#include "nodes/parsenodes.h"
-extern ObjectAddress CreateSubscription(CreateSubscriptionStmt *stmt);
-extern ObjectAddress AlterSubscription(AlterSubscriptionStmt *stmt);
-extern void DropSubscription(DropSubscriptionStmt *stmt);
+extern ObjectAddress CreateSubscription(CreateSubscriptionStmt *stmt,
+ bool isTopLevel);
+extern ObjectAddress AlterSubscription(AlterSubscriptionStmt *stmt,
+ bool isTopLevel);
+extern void DropSubscription(DropSubscriptionStmt *stmt, bool isTopLevel);
extern ObjectAddress AlterSubscriptionOwner(const char *name, Oid newOwnerId);
extern void AlterSubscriptionOwner_oid(Oid subid, Oid newOwnerId);