aboutsummaryrefslogtreecommitdiff
path: root/src/backend/executor/execMain.c
diff options
context:
space:
mode:
authorRobert Haas <rhaas@postgresql.org>2017-08-18 13:01:05 -0400
committerRobert Haas <rhaas@postgresql.org>2017-08-18 13:01:05 -0400
commitc4b841ba6aa9252ab9dacd59d317aba8cfa9b31a (patch)
treef04bad7b7d401e1639c2fad616242dced8609c52 /src/backend/executor/execMain.c
parenta20aac890a89e6f88e841dedbbfa8d9d5f7309fc (diff)
downloadpostgresql-c4b841ba6aa9252ab9dacd59d317aba8cfa9b31a.tar.gz
postgresql-c4b841ba6aa9252ab9dacd59d317aba8cfa9b31a.zip
Fix interaction of triggers, partitioning, and EXPLAIN ANALYZE.
Add a new EState member es_leaf_result_relations, so that the trigger code knows about ResultRelInfos created by tuple routing. Also make sure ExplainPrintTriggers knows about partition-related ResultRelInfos. Etsuro Fujita, reviewed by Amit Langote Discussion: http://postgr.es/m/57163e18-8e56-da83-337a-22f2c0008051@lab.ntt.co.jp
Diffstat (limited to 'src/backend/executor/execMain.c')
-rw-r--r--src/backend/executor/execMain.c45
1 files changed, 34 insertions, 11 deletions
diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c
index 74071eede6e..4582a3caa00 100644
--- a/src/backend/executor/execMain.c
+++ b/src/backend/executor/execMain.c
@@ -1365,16 +1365,18 @@ InitResultRelInfo(ResultRelInfo *resultRelInfo,
*
* Get a ResultRelInfo for a trigger target relation. Most of the time,
* triggers are fired on one of the result relations of the query, and so
- * we can just return a member of the es_result_relations array. (Note: in
- * self-join situations there might be multiple members with the same OID;
- * if so it doesn't matter which one we pick.) However, it is sometimes
- * necessary to fire triggers on other relations; this happens mainly when an
- * RI update trigger queues additional triggers on other relations, which will
- * be processed in the context of the outer query. For efficiency's sake,
- * we want to have a ResultRelInfo for those triggers too; that can avoid
- * repeated re-opening of the relation. (It also provides a way for EXPLAIN
- * ANALYZE to report the runtimes of such triggers.) So we make additional
- * ResultRelInfo's as needed, and save them in es_trig_target_relations.
+ * we can just return a member of the es_result_relations array, the
+ * es_root_result_relations array (if any), or the es_leaf_result_relations
+ * list (if any). (Note: in self-join situations there might be multiple
+ * members with the same OID; if so it doesn't matter which one we pick.)
+ * However, it is sometimes necessary to fire triggers on other relations;
+ * this happens mainly when an RI update trigger queues additional triggers
+ * on other relations, which will be processed in the context of the outer
+ * query. For efficiency's sake, we want to have a ResultRelInfo for those
+ * triggers too; that can avoid repeated re-opening of the relation. (It
+ * also provides a way for EXPLAIN ANALYZE to report the runtimes of such
+ * triggers.) So we make additional ResultRelInfo's as needed, and save them
+ * in es_trig_target_relations.
*/
ResultRelInfo *
ExecGetTriggerResultRel(EState *estate, Oid relid)
@@ -1395,6 +1397,23 @@ ExecGetTriggerResultRel(EState *estate, Oid relid)
rInfo++;
nr--;
}
+ /* Second, search through the root result relations, if any */
+ rInfo = estate->es_root_result_relations;
+ nr = estate->es_num_root_result_relations;
+ while (nr > 0)
+ {
+ if (RelationGetRelid(rInfo->ri_RelationDesc) == relid)
+ return rInfo;
+ rInfo++;
+ nr--;
+ }
+ /* Third, search through the leaf result relations, if any */
+ foreach(l, estate->es_leaf_result_relations)
+ {
+ rInfo = (ResultRelInfo *) lfirst(l);
+ if (RelationGetRelid(rInfo->ri_RelationDesc) == relid)
+ return rInfo;
+ }
/* Nope, but maybe we already made an extra ResultRelInfo for it */
foreach(l, estate->es_trig_target_relations)
{
@@ -3238,6 +3257,7 @@ EvalPlanQualEnd(EPQState *epqstate)
void
ExecSetupPartitionTupleRouting(Relation rel,
Index resultRTindex,
+ EState *estate,
PartitionDispatch **pd,
ResultRelInfo **partitions,
TupleConversionMap ***tup_conv_maps,
@@ -3301,7 +3321,10 @@ ExecSetupPartitionTupleRouting(Relation rel,
partrel,
resultRTindex,
rel,
- 0);
+ estate->es_instrument);
+
+ estate->es_leaf_result_relations =
+ lappend(estate->es_leaf_result_relations, leaf_part_rri);
/*
* Open partition indices (remember we do not support ON CONFLICT in