diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index af25836..0a3367b 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -2568,15 +2568,13 @@ heap_prepare_insert(Relation relation, HeapTuple tup, TransactionId xid, CommandId cid, int options) { /* - * For now, parallel operations are required to be strictly read-only. - * Unlike heap_update() and heap_delete(), an insert should never create a - * combo CID, so it might be possible to relax this restriction, but not - * without more thought and testing. + * For now, parallel operations are required to be strictly read-only in + * parallel worker. */ - if (IsInParallelMode()) + if (IsParallelWorker()) ereport(ERROR, (errcode(ERRCODE_INVALID_TRANSACTION_STATE), - errmsg("cannot insert tuples during a parallel operation"))); + errmsg("cannot insert tuples in a parallel worker"))); if (relation->rd_rel->relhasoids) { @@ -3023,10 +3021,10 @@ heap_delete(Relation relation, ItemPointer tid, * Other workers might need that combocid for visibility checks, and we * have no provision for broadcasting it to them. */ - if (IsInParallelMode()) + if (IsParallelWorker()) ereport(ERROR, (errcode(ERRCODE_INVALID_TRANSACTION_STATE), - errmsg("cannot delete tuples during a parallel operation"))); + errmsg("cannot delete tuples in a parallel worker"))); block = ItemPointerGetBlockNumber(tid); buffer = ReadBuffer(relation, block); @@ -3495,10 +3493,10 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup, * Other workers might need that combocid for visibility checks, and we * have no provision for broadcasting it to them. */ - if (IsInParallelMode()) + if (IsParallelWorker()) ereport(ERROR, (errcode(ERRCODE_INVALID_TRANSACTION_STATE), - errmsg("cannot update tuples during a parallel operation"))); + errmsg("cannot update tuples in a parallel worker"))); /* * Fetch the list of attributes to be checked for HOT update. This is diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 42fc351..acd24ab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -15,6 +15,7 @@ #include "access/clog.h" #include "access/commit_ts.h" +#include "access/parallel.h" #include "access/subtrans.h" #include "access/transam.h" #include "access/xact.h" @@ -51,10 +52,10 @@ GetNewTransactionId(bool isSubXact) /* * Workers synchronize transaction state at the beginning of each parallel - * operation, so we can't account for new XIDs after that point. + * operation, so we can't account for new XIDs in a parallel worker. */ - if (IsInParallelMode()) - elog(ERROR, "cannot assign TransactionIds during a parallel operation"); + if (IsParallelWorker()) + elog(ERROR, "cannot assign TransactionIds in a parallel worker"); /* * During bootstrap initialization, we return the special bootstrap diff --git a/src/backend/access/transam/xact.c b/src/backend/access/transam/xact.c index 82f9a3c..cafe387 100644 --- a/src/backend/access/transam/xact.c +++ b/src/backend/access/transam/xact.c @@ -497,10 +497,10 @@ AssignTransactionId(TransactionState s) /* * Workers synchronize transaction state at the beginning of each parallel - * operation, so we can't account for new XIDs at this point. + * operation, so we can't account for new XIDs in parallel worker. */ - if (IsInParallelMode() || IsParallelWorker()) - elog(ERROR, "cannot assign XIDs during a parallel operation"); + if (IsParallelWorker()) + elog(ERROR, "cannot assign XIDs in a parallel worker"); /* * Ensure parent(s) have XIDs, so that a child always has an XID later diff --git a/src/backend/commands/copy.c b/src/backend/commands/copy.c index 949844d..5099cad 100644 --- a/src/backend/commands/copy.c +++ b/src/backend/commands/copy.c @@ -1524,7 +1524,7 @@ BeginCopy(ParseState *pstate, } /* plan the query */ - plan = pg_plan_query(query, 0, NULL); + plan = pg_plan_query(query, CURSOR_OPT_PARALLEL_OK, NULL); /* * With row level security and a user using "COPY relation TO", we diff --git a/src/backend/commands/explain.c b/src/backend/commands/explain.c index c9e0a3e..25e6e9e 100644 --- a/src/backend/commands/explain.c +++ b/src/backend/commands/explain.c @@ -397,7 +397,7 @@ ExplainOneUtility(Node *utilityStmt, IntoClause *into, ExplainState *es, rewritten = QueryRewrite(castNode(Query, copyObject(ctas->query))); Assert(list_length(rewritten) == 1); ExplainOneQuery(castNode(Query, linitial(rewritten)), - 0, ctas->into, es, + CURSOR_OPT_PARALLEL_OK, ctas->into, es, queryString, params); } else if (IsA(utilityStmt, DeclareCursorStmt)) diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c index a666391..97b50d9 100644 --- a/src/backend/executor/execMain.c +++ b/src/backend/executor/execMain.c @@ -1585,11 +1585,9 @@ ExecutePlan(EState *estate, /* * If a tuple count was supplied, we must force the plan to run without - * parallelism, because we might exit early. Also disable parallelism - * when writing into a relation, because no database changes are allowed - * in parallel mode. + * parallelism, because we might exit early. */ - if (numberTuples || dest->mydest == DestIntoRel) + if (numberTuples) use_parallel_mode = false; if (use_parallel_mode) diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c index 3d33d46..7deaba2 100644 --- a/src/backend/optimizer/plan/planner.c +++ b/src/backend/optimizer/plan/planner.c @@ -242,7 +242,7 @@ standard_planner(Query *parse, int cursorOptions, ParamListInfo boundParams) if ((cursorOptions & CURSOR_OPT_PARALLEL_OK) != 0 && IsUnderPostmaster && dynamic_shared_memory_type != DSM_IMPL_NONE && - parse->commandType == CMD_SELECT && + parse->commandType != CMD_UTILITY && !parse->hasModifyingCTE && max_parallel_workers_per_gather > 0 && !IsParallelWorker() &&