Test code, not completely working. gather3
authorRobert Haas <[email protected]>
Tue, 27 Oct 2015 21:14:57 +0000 (22:14 +0100)
committerRobert Haas <[email protected]>
Wed, 28 Oct 2015 17:51:25 +0000 (18:51 +0100)
src/backend/commands/explain.c
src/backend/optimizer/plan/planner.c

index 12a59a356060bb3b21e4c0075b5701cca08b7daf..ee3165b73364e76cb99b123cbe9d9ff182e6c9af 100644 (file)
@@ -58,7 +58,7 @@ static double elapsed_time(instr_time *starttime);
 static bool ExplainPreScanNode(PlanState *planstate, Bitmapset **rels_used);
 static void ExplainNode(PlanState *planstate, List *ancestors,
                        const char *relationship, const char *plan_name,
-                       ExplainState *es);
+                       ExplainState *es, PlanState *squashstate);
 static void show_plan_tlist(PlanState *planstate, List *ancestors,
                                ExplainState *es);
 static void show_expression(Node *node, const char *qlabel,
@@ -579,7 +579,7 @@ ExplainPrintPlan(ExplainState *es, QueryDesc *queryDesc)
        es->rtable_names = select_rtable_names_for_explain(es->rtable, rels_used);
        es->deparse_cxt = deparse_context_for_plan_rtable(es->rtable,
                                                                                                          es->rtable_names);
-       ExplainNode(queryDesc->planstate, NIL, NULL, NULL, es);
+       ExplainNode(queryDesc->planstate, NIL, NULL, NULL, es, NULL);
 }
 
 /*
@@ -787,7 +787,7 @@ ExplainPreScanNode(PlanState *planstate, Bitmapset **rels_used)
 static void
 ExplainNode(PlanState *planstate, List *ancestors,
                        const char *relationship, const char *plan_name,
-                       ExplainState *es)
+                       ExplainState *es, PlanState *squashstate)
 {
        Plan       *plan = planstate->plan;
        const char *pname;                      /* node type name for text output */
@@ -804,7 +804,7 @@ ExplainNode(PlanState *planstate, List *ancestors,
                if (gather->single_copy)
                {
                        ExplainNode(outerPlanState(planstate), ancestors, relationship,
-                                               plan_name, es);
+                                               plan_name, es, planstate);
                        return;
                }
        }
@@ -1571,16 +1571,18 @@ ExplainNode(PlanState *planstate, List *ancestors,
        /* initPlan-s */
        if (planstate->initPlan)
                ExplainSubPlans(planstate->initPlan, ancestors, "InitPlan", es);
+       if (squashstate != NULL && squashstate->initPlan)
+               ExplainSubPlans(squashstate->initPlan, ancestors, "SQUASHInitPlan", es);
 
        /* lefttree */
        if (outerPlanState(planstate))
                ExplainNode(outerPlanState(planstate), ancestors,
-                                       "Outer", NULL, es);
+                                       "Outer", NULL, es, NULL);
 
        /* righttree */
        if (innerPlanState(planstate))
                ExplainNode(innerPlanState(planstate), ancestors,
-                                       "Inner", NULL, es);
+                                       "Inner", NULL, es, NULL);
 
        /* special child plans */
        switch (nodeTag(plan))
@@ -1612,7 +1614,7 @@ ExplainNode(PlanState *planstate, List *ancestors,
                        break;
                case T_SubqueryScan:
                        ExplainNode(((SubqueryScanState *) planstate)->subplan, ancestors,
-                                               "Subquery", NULL, es);
+                                               "Subquery", NULL, es, NULL);
                        break;
                case T_CustomScan:
                        ExplainCustomChildren((CustomScanState *) planstate,
@@ -1625,6 +1627,11 @@ ExplainNode(PlanState *planstate, List *ancestors,
        /* subPlan-s */
        if (planstate->subPlan)
                ExplainSubPlans(planstate->subPlan, ancestors, "SubPlan", es);
+       if (squashstate != NULL && squashstate->subPlan)
+       {
+               List *myancestors = lcons(squashstate, ancestors);
+               ExplainSubPlans(squashstate->subPlan, myancestors, "SQUASHSubPlan", es);
+       }
 
        /* end of child plans */
        if (haschildren)
@@ -2628,7 +2635,7 @@ ExplainMemberNodes(List *plans, PlanState **planstates,
 
        for (j = 0; j < nplans; j++)
                ExplainNode(planstates[j], ancestors,
-                                       "Member", NULL, es);
+                                       "Member", NULL, es, NULL);
 }
 
 /*
@@ -2649,7 +2656,7 @@ ExplainSubPlans(List *plans, List *ancestors,
                SubPlan    *sp = (SubPlan *) sps->xprstate.expr;
 
                ExplainNode(sps->planstate, ancestors,
-                                       relationship, sp->plan_name, es);
+                                       relationship, sp->plan_name, es, NULL);
        }
 }
 
@@ -2664,7 +2671,8 @@ ExplainCustomChildren(CustomScanState *css, List *ancestors, ExplainState *es)
        (list_length(css->custom_ps) != 1 ? "children" : "child");
 
        foreach(cell, css->custom_ps)
-               ExplainNode((PlanState *) lfirst(cell), ancestors, label, NULL, es);
+               ExplainNode((PlanState *) lfirst(cell), ancestors, label, NULL, es,
+                                       NULL);
 }
 
 /*
index 34ce39c56aa4552c93611c83b23885f30d02a78b..fde0c6d141e3f4e1e9d94952b3d7da4f91bc4e87 100644 (file)
@@ -1888,12 +1888,17 @@ grouping_planner(PlannerInfo *root, double tuple_fraction)
                         * results.
                         */
                        bool            need_sort_for_grouping = false;
+                       Plan       *checkplan;
+                       bool            insert_gather = false;
 
                        /* Try to run it in a worker. */
                        if (best_path->parallel_safe)
+                       {
+                               insert_gather = true;
                                best_path = (Path *)
                                        create_single_copy_gather_path(root, final_rel,
                                                                                                   best_path, NULL);
+                       }
 
                        current_pathkeys = best_path->pathkeys;
 
@@ -1912,6 +1917,14 @@ grouping_planner(PlannerInfo *root, double tuple_fraction)
 
                        result_plan = create_plan(root, best_path);
 
+                       checkplan = result_plan;
+                       if (insert_gather)
+                       {
+                               Assert(IsA(checkplan, Gather));
+                               checkplan = outerPlan(checkplan);
+                               Assert(!IsA(checkplan, Gather));
+                       }
+
                        /*
                         * create_plan returns a plan with just a "flat" tlist of required
                         * Vars.  Usually we need to insert the sub_tlist as the tlist of
@@ -1926,7 +1939,7 @@ grouping_planner(PlannerInfo *root, double tuple_fraction)
                                 * we need, we must insert a Result node to project the
                                 * desired tlist.
                                 */
-                               if (!is_projection_capable_plan(result_plan) &&
+                               if (!is_projection_capable_plan(checkplan) &&
                                        !tlist_same_exprs(sub_tlist, result_plan->targetlist))
                                {
                                        result_plan = (Plan *) make_result(root,