diff -durpN pgsql.orig/src/backend/optimizer/path/allpaths.c pgsql/src/backend/optimizer/path/allpaths.c --- pgsql.orig/src/backend/optimizer/path/allpaths.c 2010-03-29 00:59:32.000000000 +0200 +++ pgsql/src/backend/optimizer/path/allpaths.c 2010-08-25 11:56:10.000000000 +0200 @@ -170,6 +170,10 @@ set_rel_pathlist(PlannerInfo *root, RelO { /* It's an "append relation", process accordingly */ set_append_rel_pathlist(root, rel, rti, rte); +#if 0 + elog(NOTICE, "set_rel_pathlist setting sortClause to NIL"); + root->parse->sortClause = NIL; +#endif } else if (rel->rtekind == RTE_SUBQUERY) { @@ -282,8 +286,10 @@ static void set_append_rel_pathlist(PlannerInfo *root, RelOptInfo *rel, Index rti, RangeTblEntry *rte) { + Query *parse = root->parse; int parentRTindex = rti; List *subpaths = NIL; + List *pathkeys = NIL; double parent_rows; double parent_size; double *parent_attrsizes; @@ -309,6 +315,14 @@ set_append_rel_pathlist(PlannerInfo *roo nattrs = rel->max_attr - rel->min_attr + 1; parent_attrsizes = (double *) palloc0(nattrs * sizeof(double)); + if (parse->sortClause) + { + pathkeys = make_pathkeys_for_sortclauses(root, + parse->sortClause, + parse->targetList, + false); + } + /* * Generate access paths for each member relation, and pick the cheapest * path for each one. @@ -423,6 +437,7 @@ set_append_rel_pathlist(PlannerInfo *roo set_rel_pathlist(root, childrel, childRTindex, childRTE); childpath = childrel->cheapest_total_path; + if (IsA(childpath, AppendPath)) subpaths = list_concat(subpaths, ((AppendPath *) childpath)->subpaths); @@ -487,7 +502,7 @@ set_append_rel_pathlist(PlannerInfo *roo * the parent rel. (Note: this is correct even if we have zero or one * live subpath due to constraint exclusion.) */ - add_path(rel, (Path *) create_append_path(rel, subpaths)); + add_path(rel, (Path *) create_append_path(rel, subpaths, pathkeys, true)); /* Select cheapest path (pretty easy in this case...) */ set_cheapest(rel); @@ -507,7 +522,7 @@ set_dummy_rel_pathlist(RelOptInfo *rel) rel->rows = 0; rel->width = 0; - add_path(rel, (Path *) create_append_path(rel, NIL)); + add_path(rel, (Path *) create_append_path(rel, NIL, NIL, false)); /* Select cheapest path (pretty easy in this case...) */ set_cheapest(rel); diff -durpN pgsql.orig/src/backend/optimizer/path/joinpath.c pgsql/src/backend/optimizer/path/joinpath.c --- pgsql.orig/src/backend/optimizer/path/joinpath.c 2010-04-19 09:42:28.000000000 +0200 +++ pgsql/src/backend/optimizer/path/joinpath.c 2010-08-25 10:51:50.000000000 +0200 @@ -955,7 +955,7 @@ best_appendrel_indexscan(PlannerInfo *ro return NULL; /* Form and return the completed Append path. */ - return (Path *) create_append_path(rel, append_paths); + return (Path *) create_append_path(rel, append_paths, NIL, false); } /* diff -durpN pgsql.orig/src/backend/optimizer/path/joinrels.c pgsql/src/backend/optimizer/path/joinrels.c --- pgsql.orig/src/backend/optimizer/path/joinrels.c 2010-02-26 03:00:45.000000000 +0100 +++ pgsql/src/backend/optimizer/path/joinrels.c 2010-08-25 10:51:53.000000000 +0200 @@ -932,7 +932,7 @@ mark_dummy_rel(RelOptInfo *rel) rel->pathlist = NIL; /* Set up the dummy path */ - add_path(rel, (Path *) create_append_path(rel, NIL)); + add_path(rel, (Path *) create_append_path(rel, NIL, NIL, false)); /* Set or update cheapest_total_path */ set_cheapest(rel); diff -durpN pgsql.orig/src/backend/optimizer/plan/createplan.c pgsql/src/backend/optimizer/plan/createplan.c --- pgsql.orig/src/backend/optimizer/plan/createplan.c 2010-07-13 10:51:03.000000000 +0200 +++ pgsql/src/backend/optimizer/plan/createplan.c 2010-08-25 12:03:45.000000000 +0200 @@ -605,12 +605,40 @@ create_append_plan(PlannerInfo *root, Ap NULL); } - /* Normal case with multiple subpaths */ - foreach(subpaths, best_path->subpaths) + if (best_path->inherited && root->parse->sortClause) { - Path *subpath = (Path *) lfirst(subpaths); + /* Query from a partitioned table with ORDER BY */ + foreach(subpaths, best_path->subpaths) + { + Path *subpath = (Path *) lfirst(subpaths); + Plan *subplan = create_plan_recurse(root, subpath); + ListCell *parent_lc; + List *parent_tlist = root->parse->targetList; + ListCell *child_lc; + List *child_tlist = subplan->targetlist; - subplans = lappend(subplans, create_plan_recurse(root, subpath)); + /* Adjust ressortgroupref of the child targetlist */ + forboth(parent_lc, parent_tlist, child_lc, child_tlist) + { + TargetEntry *parent_tle = (TargetEntry *) lfirst(parent_lc); + TargetEntry *child_tle = (TargetEntry *) lfirst(child_lc); + + child_tle->ressortgroupref = parent_tle->ressortgroupref; + } + + subplans = lappend(subplans, + make_sort_from_sortclauses(root, root->parse->sortClause, subplan)); + } + } + else + { + /* Normal case with multiple subpaths */ + foreach(subpaths, best_path->subpaths) + { + Path *subpath = (Path *) lfirst(subpaths); + + subplans = lappend(subplans, create_plan_recurse(root, subpath)); + } } plan = make_append(subplans, tlist); diff -durpN pgsql.orig/src/backend/optimizer/util/pathnode.c pgsql/src/backend/optimizer/util/pathnode.c --- pgsql.orig/src/backend/optimizer/util/pathnode.c 2010-03-29 00:59:33.000000000 +0200 +++ pgsql/src/backend/optimizer/util/pathnode.c 2010-08-25 11:15:51.000000000 +0200 @@ -638,16 +638,17 @@ create_tidscan_path(PlannerInfo *root, R * pathnode. */ AppendPath * -create_append_path(RelOptInfo *rel, List *subpaths) +create_append_path(RelOptInfo *rel, List *subpaths, List *pathkeys, bool inherited) { AppendPath *pathnode = makeNode(AppendPath); ListCell *l; pathnode->path.pathtype = T_Append; pathnode->path.parent = rel; - pathnode->path.pathkeys = NIL; /* result is always considered + pathnode->path.pathkeys = pathkeys; /* result is always considered * unsorted */ pathnode->subpaths = subpaths; + pathnode->inherited = inherited; pathnode->path.startup_cost = 0; pathnode->path.total_cost = 0; diff -durpN pgsql.orig/src/include/nodes/relation.h pgsql/src/include/nodes/relation.h --- pgsql.orig/src/include/nodes/relation.h 2010-07-13 10:51:07.000000000 +0200 +++ pgsql/src/include/nodes/relation.h 2010-08-25 10:50:02.000000000 +0200 @@ -750,6 +750,7 @@ typedef struct AppendPath { Path path; List *subpaths; /* list of component Paths */ + bool inherited; } AppendPath; #define IS_DUMMY_PATH(p) \ diff -durpN pgsql.orig/src/include/optimizer/pathnode.h pgsql/src/include/optimizer/pathnode.h --- pgsql.orig/src/include/optimizer/pathnode.h 2010-03-29 00:59:33.000000000 +0200 +++ pgsql/src/include/optimizer/pathnode.h 2010-08-25 10:50:23.000000000 +0200 @@ -46,7 +46,8 @@ extern BitmapOrPath *create_bitmap_or_pa List *bitmapquals); extern TidPath *create_tidscan_path(PlannerInfo *root, RelOptInfo *rel, List *tidquals); -extern AppendPath *create_append_path(RelOptInfo *rel, List *subpaths); +extern AppendPath *create_append_path(RelOptInfo *rel, List *subpaths, + List *pathkeys, bool inherited); extern ResultPath *create_result_path(List *quals); extern MaterialPath *create_material_path(RelOptInfo *rel, Path *subpath); extern UniquePath *create_unique_path(PlannerInfo *root, RelOptInfo *rel,