enforce sorting when RemoteSubplan feeds data to GroupAggregate
authorTomas Vondra <[email protected]>
Fri, 20 Jan 2017 23:18:41 +0000 (00:18 +0100)
committerTomas Vondra <[email protected]>
Fri, 20 Jan 2017 23:18:41 +0000 (00:18 +0100)
When the second step of distributed aggregation is executed using
GroupAggregate, the RemoteSubplan needs to produce sorted output.
We might insert Sort node above the RemoteSubplan, but we don't
do that as we wan to push as much work to the remote side.

Therefore the remote part of the plan needs to produce sorted
output, and RemoteSubplan needs to perform merge-sort. For the
code generating remote parallel paths, this was already done,
because the code injects an explicit sort on top of the Gather
when the second phase is GroupAggregate.

But for the special XL plans, using partial aggregates without
the Gather, this was not happening, so when the partial path was
executed using HashAggregate, the RemoteSubplan did not know
it needs to enforce sorted output.

Fixed by adding an explicit Sort node as the last step of the
remote path.

src/backend/optimizer/plan/planner.c

index 4cab3aea93aecbd91cc3adf66f55b4c601d891b2..aec4939241aceb836eb20bf63e4cb7e93329c1e8 100644 (file)
@@ -4497,7 +4497,7 @@ create_grouping_paths(PlannerInfo *root,
                        /* If the whole aggregate was pushed down, we're done. */
                        if (! can_push_down_grouping(root, parse, cheapest_path))
                        {
-                               Path *path;
+                               Path *path, *agg_path;
 
                                path = (Path *) create_agg_path(root,
                                                                           grouped_rel,
@@ -4510,6 +4510,9 @@ create_grouping_paths(PlannerInfo *root,
                                                                           &agg_partial_costs,
                                                                           dNumPartialGroups);
 
+                               /* keep partially aggregated path for the can_sort branch */
+                               agg_path = path;
+
                                path = create_remotesubplan_path(root, path, NULL);
 
                                /* Generate paths with both hash and sort second phase. */
@@ -4527,6 +4530,19 @@ create_grouping_paths(PlannerInfo *root,
                                                                                 dNumGroups));
 
                                if (can_sort)
+                               {
+                                       /*
+                                        * AGG_HASHED aggregate paths are always unsorted, so add
+                                        * a Sorted node for the final AGG_SORTED step.
+                                        */
+                                       path = (Path *) create_sort_path(root,
+                                                                                                        grouped_rel,
+                                                                                                        agg_path,
+                                                                                                        root->group_pathkeys,
+                                                                                                        -1.0);
+
+                                       path = create_remotesubplan_path(root, path, NULL);
+
                                        add_path(grouped_rel, (Path *)
                                                         create_agg_path(root,
                                                                                         grouped_rel,
@@ -4538,6 +4554,7 @@ create_grouping_paths(PlannerInfo *root,
                                                                                         (List *) parse->havingQual,
                                                                                         &agg_final_costs,
                                                                                         dNumGroups));
+                               }
                        }
                }