mirror of
https://github.com/postgres/postgres.git
synced 2025-11-07 19:06:32 +03:00
Avoid creating duplicate ordered append paths
In generate_orderedappend_paths(), the function does not handle the case where the paths in total_subpaths and fractional_subpaths are identical. This situation is not uncommon, and as a result, it may generate two exactly identical ordered append paths. Fix by checking whether total_subpaths and fractional_subpaths contain the same paths, and skipping creation of the ordered append path for the fractional case when they are identical. Given the lack of field complaints about this, I'm a bit hesitant to back-patch, but let's clean it up in HEAD. Author: Richard Guo <guofenglinux@gmail.com> Reviewed-by: Andrei Lepikhov <lepihov@gmail.com> Reviewed-by: Alexander Korotkov <aekorotkov@gmail.com> Discussion: https://postgr.es/m/CAMbWs4-OYsgA75tGGiBARt87G0y_z_GBTSLrzudcJxAzndYkYw@mail.gmail.com
This commit is contained in:
@@ -1877,6 +1877,7 @@ generate_orderedappend_paths(PlannerInfo *root, RelOptInfo *rel,
|
|||||||
List *total_subpaths = NIL;
|
List *total_subpaths = NIL;
|
||||||
List *fractional_subpaths = NIL;
|
List *fractional_subpaths = NIL;
|
||||||
bool startup_neq_total = false;
|
bool startup_neq_total = false;
|
||||||
|
bool fraction_neq_total = false;
|
||||||
bool match_partition_order;
|
bool match_partition_order;
|
||||||
bool match_partition_order_desc;
|
bool match_partition_order_desc;
|
||||||
int end_index;
|
int end_index;
|
||||||
@@ -2005,15 +2006,21 @@ generate_orderedappend_paths(PlannerInfo *root, RelOptInfo *rel,
|
|||||||
* XXX We might consider partially sorted paths too (with an
|
* XXX We might consider partially sorted paths too (with an
|
||||||
* incremental sort on top). But we'd have to build all the
|
* incremental sort on top). But we'd have to build all the
|
||||||
* incremental paths, do the costing etc.
|
* incremental paths, do the costing etc.
|
||||||
|
*
|
||||||
|
* Also, notice whether we actually have different paths for
|
||||||
|
* the "fractional" and "total" cases. This helps avoid
|
||||||
|
* generating two identical ordered append paths.
|
||||||
*/
|
*/
|
||||||
if (!cheapest_fractional)
|
if (cheapest_fractional == NULL)
|
||||||
cheapest_fractional = cheapest_total;
|
cheapest_fractional = cheapest_total;
|
||||||
|
else if (cheapest_fractional != cheapest_total)
|
||||||
|
fraction_neq_total = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Notice whether we actually have different paths for the
|
* Notice whether we actually have different paths for the
|
||||||
* "cheapest" and "total" cases; frequently there will be no point
|
* "cheapest" and "total" cases. This helps avoid generating two
|
||||||
* in two create_merge_append_path() calls.
|
* identical ordered append paths.
|
||||||
*/
|
*/
|
||||||
if (cheapest_startup != cheapest_total)
|
if (cheapest_startup != cheapest_total)
|
||||||
startup_neq_total = true;
|
startup_neq_total = true;
|
||||||
@@ -2084,7 +2091,7 @@ generate_orderedappend_paths(PlannerInfo *root, RelOptInfo *rel,
|
|||||||
false,
|
false,
|
||||||
-1));
|
-1));
|
||||||
|
|
||||||
if (fractional_subpaths)
|
if (fractional_subpaths && fraction_neq_total)
|
||||||
add_path(rel, (Path *) create_append_path(root,
|
add_path(rel, (Path *) create_append_path(root,
|
||||||
rel,
|
rel,
|
||||||
fractional_subpaths,
|
fractional_subpaths,
|
||||||
@@ -2110,7 +2117,7 @@ generate_orderedappend_paths(PlannerInfo *root, RelOptInfo *rel,
|
|||||||
pathkeys,
|
pathkeys,
|
||||||
NULL));
|
NULL));
|
||||||
|
|
||||||
if (fractional_subpaths)
|
if (fractional_subpaths && fraction_neq_total)
|
||||||
add_path(rel, (Path *) create_merge_append_path(root,
|
add_path(rel, (Path *) create_merge_append_path(root,
|
||||||
rel,
|
rel,
|
||||||
fractional_subpaths,
|
fractional_subpaths,
|
||||||
|
|||||||
Reference in New Issue
Block a user