push-down-sort-into-inh-2.patch
application/octet-stream
Filename: push-down-sort-into-inh-2.patch
Type: application/octet-stream
Part: 0
Message:
Re: Path question
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: unified
| File | + | − |
|---|---|---|
| src/backend/optimizer/path/allpaths.c | 17 | 2 |
| src/backend/optimizer/path/joinpath.c | 1 | 1 |
| src/backend/optimizer/path/joinrels.c | 1 | 1 |
| src/backend/optimizer/plan/createplan.c | 32 | 4 |
| src/backend/optimizer/util/pathnode.c | 3 | 2 |
| src/include/nodes/relation.h | 1 | 0 |
| src/include/optimizer/pathnode.h | 2 | 1 |
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,