aboutsummaryrefslogtreecommitdiff
path: root/src/backend/tcop/utility.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/tcop/utility.c')
-rw-r--r--src/backend/tcop/utility.c30
1 files changed, 27 insertions, 3 deletions
diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c
index 31e9d4cf8b4..59f09dc93af 100644
--- a/src/backend/tcop/utility.c
+++ b/src/backend/tcop/utility.c
@@ -128,14 +128,15 @@ CommandIsReadOnly(Node *parsetree)
static void
check_xact_readonly(Node *parsetree)
{
- if (!XactReadOnly)
+ /* Only perform the check if we have a reason to do so. */
+ if (!XactReadOnly && !IsInParallelMode())
return;
/*
* Note: Commands that need to do more complicated checking are handled
* elsewhere, in particular COPY and plannable statements do their own
- * checking. However they should all call PreventCommandIfReadOnly to
- * actually throw the error.
+ * checking. However they should all call PreventCommandIfReadOnly
+ * or PreventCommandIfParallelMode to actually throw the error.
*/
switch (nodeTag(parsetree))
@@ -208,6 +209,7 @@ check_xact_readonly(Node *parsetree)
case T_ImportForeignSchemaStmt:
case T_SecLabelStmt:
PreventCommandIfReadOnly(CreateCommandTag(parsetree));
+ PreventCommandIfParallelMode(CreateCommandTag(parsetree));
break;
default:
/* do nothing */
@@ -233,6 +235,24 @@ PreventCommandIfReadOnly(const char *cmdname)
}
/*
+ * PreventCommandIfParallelMode: throw error if current (sub)transaction is
+ * in parallel mode.
+ *
+ * This is useful mainly to ensure consistency of the error message wording;
+ * most callers have checked IsInParallelMode() for themselves.
+ */
+void
+PreventCommandIfParallelMode(const char *cmdname)
+{
+ if (IsInParallelMode())
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
+ /* translator: %s is name of a SQL command, eg CREATE */
+ errmsg("cannot execute %s during a parallel operation",
+ cmdname)));
+}
+
+/*
* PreventCommandDuringRecovery: throw error if RecoveryInProgress
*
* The majority of operations that are unsafe in a Hot Standby slave
@@ -618,6 +638,7 @@ standard_ProcessUtility(Node *parsetree,
case T_ClusterStmt:
/* we choose to allow this during "read only" transactions */
PreventCommandDuringRecovery("CLUSTER");
+ /* forbidden in parallel mode due to CommandIsReadOnly */
cluster((ClusterStmt *) parsetree, isTopLevel);
break;
@@ -628,6 +649,7 @@ standard_ProcessUtility(Node *parsetree,
/* we choose to allow this during "read only" transactions */
PreventCommandDuringRecovery((stmt->options & VACOPT_VACUUM) ?
"VACUUM" : "ANALYZE");
+ /* forbidden in parallel mode due to CommandIsReadOnly */
ExecVacuum(stmt, isTopLevel);
}
break;
@@ -704,6 +726,7 @@ standard_ProcessUtility(Node *parsetree,
* outside a transaction block is presumed to be user error.
*/
RequireTransactionChain(isTopLevel, "LOCK TABLE");
+ /* forbidden in parallel mode due to CommandIsReadOnly */
LockTableCommand((LockStmt *) parsetree);
break;
@@ -735,6 +758,7 @@ standard_ProcessUtility(Node *parsetree,
/* we choose to allow this during "read only" transactions */
PreventCommandDuringRecovery("REINDEX");
+ /* forbidden in parallel mode due to CommandIsReadOnly */
switch (stmt->kind)
{
case REINDEX_OBJECT_INDEX: