Commit 6bc27698 authored by Tomas Vondra's avatar Tomas Vondra

Error out when Gather Merge input is not sorted

To build Gather Merge path, the input needs to be sufficiently sorted.
Ensuring this is the responsibility of the code constructing the paths,
but create_gather_merge_plan tried to handle unsorted paths by adding
an explicit Sort. In light of the recent issues related to Incremental
Sort, this is rather fragile. Some of the expressions may be volatile
or parallel unsafe, in which case we can't add the Sort here.

We could do more checks and add the Sort in at least some cases, but
it seems cleaner to just error out and make it clear this is a bug in
code constructing those paths.

Author: James Coleman
Reviewed-by: Tomas Vondra
Discussion: https://postgr.es/m/CAAaqYe8cK3g5CfLC4w7bs%3DhC0mSksZC%3DH5M8LSchj5e5OxpTAg%40mail.gmail.com
Discussion: https://postgr.es/m/CAJGNTeNaxpXgBVcRhJX%2B2vSbq%2BF2kJqGBcvompmpvXb7pq%2BoFA%40mail.gmail.com
parent c06d6aa4
...@@ -1793,13 +1793,15 @@ create_gather_merge_plan(PlannerInfo *root, GatherMergePath *best_path) ...@@ -1793,13 +1793,15 @@ create_gather_merge_plan(PlannerInfo *root, GatherMergePath *best_path)
&gm_plan->nullsFirst); &gm_plan->nullsFirst);
/* Now, insert a Sort node if subplan isn't sufficiently ordered */ /*
* All gather merge paths should have already guaranteed the necessary sort
* order either by adding an explicit sort node or by using presorted input.
* We can't simply add a sort here on additional pathkeys, because we can't
* guarantee the sort would be safe. For example, expressions may be
* volatile or otherwise parallel unsafe.
*/
if (!pathkeys_contained_in(pathkeys, best_path->subpath->pathkeys)) if (!pathkeys_contained_in(pathkeys, best_path->subpath->pathkeys))
subplan = (Plan *) make_sort(subplan, gm_plan->numCols, elog(ERROR, "gather merge input not sufficiently sorted");
gm_plan->sortColIdx,
gm_plan->sortOperators,
gm_plan->collations,
gm_plan->nullsFirst);
/* Now insert the subplan under GatherMerge. */ /* Now insert the subplan under GatherMerge. */
gm_plan->plan.lefttree = subplan; gm_plan->plan.lefttree = subplan;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment