Avoid listing the same ResultRelInfo in more than one EState list.
authorRobert Haas <rhaas@postgresql.org>
Thu, 8 Feb 2018 19:29:05 +0000 (14:29 -0500)
committerRobert Haas <rhaas@postgresql.org>
Thu, 8 Feb 2018 19:29:05 +0000 (14:29 -0500)
Doing so causes EXPLAIN ANALYZE to show trigger statistics multiple
times.  Commit 2f178441044be430f6b4d626e4dae68a9a6f6cec seems to
be to blame for this.

Amit Langote, revieed by Amit Khandekar, Etsuro Fujita, and me.

src/backend/commands/explain.c
src/backend/executor/execMain.c
src/backend/executor/execPartition.c
src/backend/executor/execUtils.c
src/include/nodes/execnodes.h

index 41cd47e8bcddd44ade423df0cb6cf16a6a55e0d0..900fa74e85e8b90700422b4a32411111b8e9a019 100644 (file)
@@ -652,15 +652,18 @@ ExplainPrintTriggers(ExplainState *es, QueryDesc *queryDesc)
    bool        show_relname;
    int         numrels = queryDesc->estate->es_num_result_relations;
    int         numrootrels = queryDesc->estate->es_num_root_result_relations;
-   List       *leafrels = queryDesc->estate->es_leaf_result_relations;
-   List       *targrels = queryDesc->estate->es_trig_target_relations;
+   List       *routerels;
+   List       *targrels;
    int         nr;
    ListCell   *l;
 
+   routerels = queryDesc->estate->es_tuple_routing_result_relations;
+   targrels = queryDesc->estate->es_trig_target_relations;
+
    ExplainOpenGroup("Triggers", "Triggers", false, es);
 
    show_relname = (numrels > 1 || numrootrels > 0 ||
-                   leafrels != NIL || targrels != NIL);
+                   routerels != NIL || targrels != NIL);
    rInfo = queryDesc->estate->es_result_relations;
    for (nr = 0; nr < numrels; rInfo++, nr++)
        report_triggers(rInfo, show_relname, es);
@@ -669,7 +672,7 @@ ExplainPrintTriggers(ExplainState *es, QueryDesc *queryDesc)
    for (nr = 0; nr < numrootrels; rInfo++, nr++)
        report_triggers(rInfo, show_relname, es);
 
-   foreach(l, leafrels)
+   foreach(l, routerels)
    {
        rInfo = (ResultRelInfo *) lfirst(l);
        report_triggers(rInfo, show_relname, es);
index 410921cc4084a96c607263b8f9f58516740022fa..5d3e923cca3294fcee58ce84f43c30c21e12025f 100644 (file)
@@ -1413,8 +1413,11 @@ ExecGetTriggerResultRel(EState *estate, Oid relid)
        rInfo++;
        nr--;
    }
-   /* Third, search through the leaf result relations, if any */
-   foreach(l, estate->es_leaf_result_relations)
+   /*
+    * Third, search through the result relations that were created during
+    * tuple routing, if any.
+    */
+   foreach(l, estate->es_tuple_routing_result_relations)
    {
        rInfo = (ResultRelInfo *) lfirst(l);
        if (RelationGetRelid(rInfo->ri_RelationDesc) == relid)
index ba6b52c32cd8c60061dca3912cd933060bb16ac6..4048c3ebc613184cf71ac43ec3936eb13d8286a1 100644 (file)
@@ -178,6 +178,15 @@ ExecSetupPartitionTupleRouting(ModifyTableState *mtstate,
                              resultRTindex,
                              rel,
                              estate->es_instrument);
+
+           /*
+            * Since we've just initialized this ResultRelInfo, it's not in
+            * any list attached to the estate as yet.  Add it, so that it can
+            * be found later.
+            */
+           estate->es_tuple_routing_result_relations =
+                       lappend(estate->es_tuple_routing_result_relations,
+                               leaf_part_rri);
        }
 
        part_tupdesc = RelationGetDescr(partrel);
@@ -210,9 +219,6 @@ ExecSetupPartitionTupleRouting(ModifyTableState *mtstate,
                            mtstate != NULL &&
                            mtstate->mt_onconflict != ONCONFLICT_NONE);
 
-       estate->es_leaf_result_relations =
-           lappend(estate->es_leaf_result_relations, leaf_part_rri);
-
        proute->partitions[i] = leaf_part_rri;
        i++;
    }
index e29f7aaf7b7c65cb6e772f3cfb8a2f6dc7f42d47..50b6edce63d7e5b587735ba92e066833580d2baa 100644 (file)
@@ -119,7 +119,7 @@ CreateExecutorState(void)
    estate->es_root_result_relations = NULL;
    estate->es_num_root_result_relations = 0;
 
-   estate->es_leaf_result_relations = NIL;
+   estate->es_tuple_routing_result_relations = NIL;
 
    estate->es_trig_target_relations = NIL;
    estate->es_trig_tuple_slot = NULL;
index 54ce63f14771e27408a4b14b8a3ecdafe9cec1c2..286d55be033232aa6b88f4544ceeec2b6643ad2e 100644 (file)
@@ -466,8 +466,11 @@ typedef struct EState
    ResultRelInfo *es_root_result_relations;    /* array of ResultRelInfos */
    int         es_num_root_result_relations;   /* length of the array */
 
-   /* Info about leaf partitions of partitioned table(s) for insert queries: */
-   List       *es_leaf_result_relations;   /* List of ResultRelInfos */
+   /*
+    * The following list contains ResultRelInfos created by the tuple
+    * routing code for partitions that don't already have one.
+    */
+   List       *es_tuple_routing_result_relations;
 
    /* Stuff used for firing triggers: */
    List       *es_trig_target_relations;   /* trigger-only ResultRelInfos */