aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/misc/guc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/utils/misc/guc.c')
-rw-r--r--src/backend/utils/misc/guc.c23
1 files changed, 23 insertions, 0 deletions
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index f43aff2d2cb..8727ee3b744 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -5665,6 +5665,20 @@ set_config_option(const char *name, const char *value,
elevel = ERROR;
}
+ /*
+ * GUC_ACTION_SAVE changes are acceptable during a parallel operation,
+ * because the current worker will also pop the change. We're probably
+ * dealing with a function having a proconfig entry. Only the function's
+ * body should observe the change, and peer workers do not share in the
+ * execution of a function call started by this worker.
+ *
+ * Other changes might need to affect other workers, so forbid them.
+ */
+ if (IsInParallelMode() && changeVal && action != GUC_ACTION_SAVE)
+ ereport(elevel,
+ (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
+ errmsg("cannot set parameters during a parallel operation")));
+
record = find_option(name, true, elevel);
if (record == NULL)
{
@@ -6969,6 +6983,15 @@ ExecSetVariableStmt(VariableSetStmt *stmt, bool isTopLevel)
{
GucAction action = stmt->is_local ? GUC_ACTION_LOCAL : GUC_ACTION_SET;
+ /*
+ * Workers synchronize these parameters at the start of the parallel
+ * operation; then, we block SET during the operation.
+ */
+ if (IsInParallelMode())
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
+ errmsg("cannot set parameters during a parallel operation")));
+
switch (stmt->kind)
{
case VAR_SET_VALUE: