diff options
author | Robert Haas <rhaas@postgresql.org> | 2017-08-18 13:01:05 -0400 |
---|---|---|
committer | Robert Haas <rhaas@postgresql.org> | 2017-08-18 13:01:05 -0400 |
commit | c4b841ba6aa9252ab9dacd59d317aba8cfa9b31a (patch) | |
tree | f04bad7b7d401e1639c2fad616242dced8609c52 /src/backend/executor/execMain.c | |
parent | a20aac890a89e6f88e841dedbbfa8d9d5f7309fc (diff) | |
download | postgresql-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.c | 45 |
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 |