summaryrefslogtreecommitdiff
path: root/src/backend/executor/execPartition.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/executor/execPartition.c')
-rw-r--r--src/backend/executor/execPartition.c31
1 files changed, 30 insertions, 1 deletions
diff --git a/src/backend/executor/execPartition.c b/src/backend/executor/execPartition.c
index 5cd5e2eeb80..84ccd7d457d 100644
--- a/src/backend/executor/execPartition.c
+++ b/src/backend/executor/execPartition.c
@@ -1819,6 +1819,7 @@ adjust_partition_colnos_using_map(List *colnos, AttrMap *attrMap)
void
ExecDoInitialPruning(EState *estate)
{
+ PlannedStmt *stmt = estate->es_plannedstmt;
ListCell *lc;
List *locked_relids = NIL;
@@ -1868,6 +1869,34 @@ ExecDoInitialPruning(EState *estate)
}
/*
+ * Lock the first result relation of each ModifyTable node, even if it was
+ * pruned. This is required for ExecInitModifyTable(), which keeps its
+ * first result relation if all other result relations have been pruned,
+ * because some executor paths (e.g., in nodeModifyTable.c and
+ * execPartition.c) rely on there being at least one result relation.
+ *
+ * There's room for improvement here --- we actually only need to do this
+ * if all other result relations of the ModifyTable node were pruned, but
+ * we don't have an easy way to tell that here.
+ */
+ if (stmt->resultRelations && ExecShouldLockRelations(estate))
+ {
+ foreach(lc, stmt->firstResultRels)
+ {
+ Index firstResultRel = lfirst_int(lc);
+
+ if (!bms_is_member(firstResultRel, estate->es_unpruned_relids))
+ {
+ RangeTblEntry *rte = exec_rt_fetch(firstResultRel, estate);
+
+ Assert(rte->rtekind == RTE_RELATION && rte->rellockmode != NoLock);
+ LockRelationOid(rte->relid, rte->rellockmode);
+ locked_relids = lappend_int(locked_relids, firstResultRel);
+ }
+ }
+ }
+
+ /*
* Release the useless locks if the plan won't be executed. This is the
* same as what CheckCachedPlan() in plancache.c does.
*/
@@ -2076,7 +2105,7 @@ CreatePartitionPruneState(EState *estate, PartitionPruneInfo *pruneinfo,
* because that entry will be held open and locked for the
* duration of this executor run.
*/
- partrel = ExecGetRangeTableRelation(estate, pinfo->rtindex);
+ partrel = ExecGetRangeTableRelation(estate, pinfo->rtindex, false);
/* Remember for InitExecPartitionPruneContext(). */
pprune->partrel = partrel;