diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c index 255f56b..b7144d9 100644 --- a/src/backend/optimizer/path/allpaths.c +++ b/src/backend/optimizer/path/allpaths.c @@ -104,7 +104,7 @@ static void generate_orderedappend_paths(PlannerInfo *root, RelOptInfo *rel, static Path *get_cheapest_parameterized_child_path(PlannerInfo *root, RelOptInfo *rel, Relids required_outer); -static void accumulate_append_subpath(Path *path, +static bool accumulate_append_subpath(Path *path, List **subpaths, List **special_subpaths); static Path *get_singleton_append_subpath(Path *path); static void set_dummy_rel_pathlist(RelOptInfo *rel); @@ -1395,8 +1395,14 @@ add_paths_to_append_rel(PlannerInfo *root, RelOptInfo *rel, if (childrel->partial_pathlist != NIL) { cheapest_partial_path = linitial(childrel->partial_pathlist); - accumulate_append_subpath(cheapest_partial_path, - &partial_subpaths, NULL); + + /* + * Don't allow partial Append if it prevents a child Append from + * being flattened. + */ + if (!accumulate_append_subpath(cheapest_partial_path, + &partial_subpaths, NULL)) + partial_subpaths_valid = false; } else partial_subpaths_valid = false; @@ -2037,8 +2043,10 @@ get_cheapest_parameterized_child_path(PlannerInfo *root, RelOptInfo *rel, * children to subpaths and the rest to special_subpaths. If the latter is * NULL, we don't flatten the path at all (unless it contains only partial * paths). + * + * Returns whether able to flatten or not. */ -static void +static bool accumulate_append_subpath(Path *path, List **subpaths, List **special_subpaths) { if (IsA(path, AppendPath)) @@ -2048,7 +2056,7 @@ accumulate_append_subpath(Path *path, List **subpaths, List **special_subpaths) if (!apath->path.parallel_aware || apath->first_partial_path == 0) { *subpaths = list_concat(*subpaths, apath->subpaths); - return; + return true; } else if (special_subpaths != NULL) { @@ -2063,18 +2071,21 @@ accumulate_append_subpath(Path *path, List **subpaths, List **special_subpaths) apath->first_partial_path); *special_subpaths = list_concat(*special_subpaths, new_special_subpaths); - return; + return true; } + else + return false; } else if (IsA(path, MergeAppendPath)) { MergeAppendPath *mpath = (MergeAppendPath *) path; *subpaths = list_concat(*subpaths, mpath->subpaths); - return; + return true; } *subpaths = lappend(*subpaths, path); + return true; } /*