aboutsummaryrefslogtreecommitdiff
path: root/src/backend/executor/execMain.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/executor/execMain.c')
-rw-r--r--src/backend/executor/execMain.c55
1 files changed, 50 insertions, 5 deletions
diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c
index 5c12fb457d5..cdb1a6a5f5d 100644
--- a/src/backend/executor/execMain.c
+++ b/src/backend/executor/execMain.c
@@ -861,17 +861,52 @@ InitPlan(QueryDesc *queryDesc, int eflags)
/*
* In the partitioned result relation case, lock the non-leaf result
- * relations too. We don't however need ResultRelInfos for them.
+ * relations too. A subset of these are the roots of respective
+ * partitioned tables, for which we also allocate ResulRelInfos.
*/
+ estate->es_root_result_relations = NULL;
+ estate->es_num_root_result_relations = 0;
if (plannedstmt->nonleafResultRelations)
{
+ int num_roots = list_length(plannedstmt->rootResultRelations);
+
+ /*
+ * Firstly, build ResultRelInfos for all the partitioned table
+ * roots, because we will need them to fire the statement-level
+ * triggers, if any.
+ */
+ resultRelInfos = (ResultRelInfo *)
+ palloc(num_roots * sizeof(ResultRelInfo));
+ resultRelInfo = resultRelInfos;
+ foreach(l, plannedstmt->rootResultRelations)
+ {
+ Index resultRelIndex = lfirst_int(l);
+ Oid resultRelOid;
+ Relation resultRelDesc;
+
+ resultRelOid = getrelid(resultRelIndex, rangeTable);
+ resultRelDesc = heap_open(resultRelOid, RowExclusiveLock);
+ InitResultRelInfo(resultRelInfo,
+ resultRelDesc,
+ lfirst_int(l),
+ NULL,
+ estate->es_instrument);
+ resultRelInfo++;
+ }
+
+ estate->es_root_result_relations = resultRelInfos;
+ estate->es_num_root_result_relations = num_roots;
+
+ /* Simply lock the rest of them. */
foreach(l, plannedstmt->nonleafResultRelations)
{
- Index resultRelationIndex = lfirst_int(l);
- Oid resultRelationOid;
+ Index resultRelIndex = lfirst_int(l);
- resultRelationOid = getrelid(resultRelationIndex, rangeTable);
- LockRelationOid(resultRelationOid, RowExclusiveLock);
+ /* We locked the roots above. */
+ if (!list_member_int(plannedstmt->rootResultRelations,
+ resultRelIndex))
+ LockRelationOid(getrelid(resultRelIndex, rangeTable),
+ RowExclusiveLock);
}
}
}
@@ -883,6 +918,8 @@ InitPlan(QueryDesc *queryDesc, int eflags)
estate->es_result_relations = NULL;
estate->es_num_result_relations = 0;
estate->es_result_relation_info = NULL;
+ estate->es_root_result_relations = NULL;
+ estate->es_num_root_result_relations = 0;
}
/*
@@ -1565,6 +1602,14 @@ ExecEndPlan(PlanState *planstate, EState *estate)
resultRelInfo++;
}
+ /* Close the root target relation(s). */
+ resultRelInfo = estate->es_root_result_relations;
+ for (i = estate->es_num_root_result_relations; i > 0; i--)
+ {
+ heap_close(resultRelInfo->ri_RelationDesc, NoLock);
+ resultRelInfo++;
+ }
+
/*
* likewise close any trigger target relations
*/