Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 8b109eb

Browse files
committed
Teach planner to convert simple UNION ALL subqueries into append relations,
thereby sharing code with the inheritance case. This puts the UNION-ALL-view approach to partitioned tables on par with inheritance, so far as constraint exclusion is concerned: it works either way. (Still need to update the docs to say so.) The definition of "simple UNION ALL" is a little simpler than I would like --- basically the union arms can only be SELECT * FROM foo --- but it's good enough for partitioned-table cases.
1 parent a25b1de commit 8b109eb

File tree

10 files changed

+888
-388
lines changed

10 files changed

+888
-388
lines changed

src/backend/optimizer/path/allpaths.c

Lines changed: 50 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/optimizer/path/allpaths.c,v 1.140 2006/01/31 21:39:23 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/optimizer/path/allpaths.c,v 1.141 2006/02/03 21:08:49 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -42,6 +42,8 @@ int geqo_threshold;
4242

4343

4444
static void set_base_rel_pathlists(PlannerInfo *root);
45+
static void set_rel_pathlist(PlannerInfo *root, RelOptInfo *rel,
46+
Index rti, RangeTblEntry *rte);
4547
static void set_plain_rel_pathlist(PlannerInfo *root, RelOptInfo *rel,
4648
RangeTblEntry *rte);
4749
static void set_append_rel_pathlist(PlannerInfo *root, RelOptInfo *rel,
@@ -133,7 +135,6 @@ set_base_rel_pathlists(PlannerInfo *root)
133135
for (rti = 1; rti < root->simple_rel_array_size; rti++)
134136
{
135137
RelOptInfo *rel = root->simple_rel_array[rti];
136-
RangeTblEntry *rte;
137138

138139
/* there may be empty slots corresponding to non-baserel RTEs */
139140
if (rel == NULL)
@@ -145,33 +146,44 @@ set_base_rel_pathlists(PlannerInfo *root)
145146
if (rel->reloptkind != RELOPT_BASEREL)
146147
continue;
147148

148-
rte = rt_fetch(rti, root->parse->rtable);
149+
set_rel_pathlist(root, rel, rti,
150+
rt_fetch(rti, root->parse->rtable));
151+
}
152+
}
149153

150-
if (rte->inh)
151-
{
152-
/* It's an "append relation", process accordingly */
153-
set_append_rel_pathlist(root, rel, rti, rte);
154-
}
155-
else if (rel->rtekind == RTE_SUBQUERY)
156-
{
157-
/* Subquery --- generate a separate plan for it */
158-
set_subquery_pathlist(root, rel, rti, rte);
159-
}
160-
else if (rel->rtekind == RTE_FUNCTION)
161-
{
162-
/* RangeFunction --- generate a separate plan for it */
163-
set_function_pathlist(root, rel, rte);
164-
}
165-
else
166-
{
167-
/* Plain relation */
168-
set_plain_rel_pathlist(root, rel, rte);
169-
}
154+
/*
155+
* set_rel_pathlist
156+
* Build access paths for a base relation
157+
*/
158+
static void
159+
set_rel_pathlist(PlannerInfo *root, RelOptInfo *rel,
160+
Index rti, RangeTblEntry *rte)
161+
{
162+
if (rte->inh)
163+
{
164+
/* It's an "append relation", process accordingly */
165+
set_append_rel_pathlist(root, rel, rti, rte);
166+
}
167+
else if (rel->rtekind == RTE_SUBQUERY)
168+
{
169+
/* Subquery --- generate a separate plan for it */
170+
set_subquery_pathlist(root, rel, rti, rte);
171+
}
172+
else if (rel->rtekind == RTE_FUNCTION)
173+
{
174+
/* RangeFunction --- generate a separate plan for it */
175+
set_function_pathlist(root, rel, rte);
176+
}
177+
else
178+
{
179+
/* Plain relation */
180+
Assert(rel->rtekind == RTE_RELATION);
181+
set_plain_rel_pathlist(root, rel, rte);
182+
}
170183

171184
#ifdef OPTIMIZER_DEBUG
172-
debug_print_rel(root, rel);
185+
debug_print_rel(root, rel);
173186
#endif
174-
}
175187
}
176188

177189
/*
@@ -181,9 +193,6 @@ set_base_rel_pathlists(PlannerInfo *root)
181193
static void
182194
set_plain_rel_pathlist(PlannerInfo *root, RelOptInfo *rel, RangeTblEntry *rte)
183195
{
184-
Assert(rel->rtekind == RTE_RELATION);
185-
Assert(!rte->inh);
186-
187196
/* Mark rel with estimated output rows, width, etc */
188197
set_baserel_size_estimates(root, rel);
189198

@@ -265,6 +274,7 @@ set_append_rel_pathlist(PlannerInfo *root, RelOptInfo *rel,
265274
int childRTindex;
266275
RelOptInfo *childrel;
267276
RangeTblEntry *childrte;
277+
Path *childpath;
268278
ListCell *parentvars;
269279
ListCell *childvars;
270280

@@ -346,10 +356,20 @@ set_append_rel_pathlist(PlannerInfo *root, RelOptInfo *rel,
346356

347357
/*
348358
* Compute the child's access paths, and save the cheapest.
359+
*
360+
* It's possible that the child is itself an appendrel, in which
361+
* case we can "cut out the middleman" and just add its child
362+
* paths to our own list. (We don't try to do this earlier because
363+
* we need to apply both levels of transformation to the quals.)
349364
*/
350-
set_plain_rel_pathlist(root, childrel, childrte);
365+
set_rel_pathlist(root, childrel, childRTindex, childrte);
351366

352-
subpaths = lappend(subpaths, childrel->cheapest_total_path);
367+
childpath = childrel->cheapest_total_path;
368+
if (IsA(childpath, AppendPath))
369+
subpaths = list_concat(subpaths,
370+
((AppendPath *) childpath)->subpaths);
371+
else
372+
subpaths = lappend(subpaths, childpath);
353373

354374
/*
355375
* Propagate size information from the child back to the parent. For

src/backend/optimizer/path/joinpath.c

Lines changed: 4 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/optimizer/path/joinpath.c,v 1.99 2006/01/31 21:39:23 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/optimizer/path/joinpath.c,v 1.100 2006/02/03 21:08:49 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -20,7 +20,6 @@
2020
#include "optimizer/cost.h"
2121
#include "optimizer/pathnode.h"
2222
#include "optimizer/paths.h"
23-
#include "optimizer/prep.h"
2423
#include "parser/parsetree.h"
2524
#include "utils/lsyscache.h"
2625

@@ -856,8 +855,6 @@ join_before_append(PlannerInfo *root,
856855
int childRTindex;
857856
RelOptInfo *childrel;
858857
Path *bestinnerjoin;
859-
Relids joinrelids;
860-
Relids *save_attr_needed;
861858
RelOptInfo *this_joinrel;
862859
List *this_restrictlist;
863860

@@ -899,27 +896,9 @@ join_before_append(PlannerInfo *root,
899896
* in joinrels.c, it provides necessary context for the Path,
900897
* such as properly-translated target and quals lists.
901898
*/
902-
joinrelids = bms_copy(joinrel->relids);
903-
joinrelids = bms_del_member(joinrelids, parentRTindex);
904-
joinrelids = bms_add_member(joinrelids, childRTindex);
905-
906-
/*
907-
* Kluge: temporarily adjust the outer rel's attr_needed info so
908-
* that it references the member rel instead of the appendrel.
909-
* This is needed to build the correct targetlist for the joinrel.
910-
*/
911-
save_attr_needed = outerrel->attr_needed;
912-
outerrel->attr_needed =
913-
adjust_other_rel_attr_needed(outerrel, appinfo,
914-
outerrel->min_attr,
915-
outerrel->max_attr);
916-
917-
this_joinrel = build_join_rel(root, joinrelids, outerrel, childrel,
918-
jointype, &this_restrictlist);
919-
920-
/* Now we can undo the hack on attr_needed */
921-
pfree(outerrel->attr_needed);
922-
outerrel->attr_needed = save_attr_needed;
899+
this_joinrel = translate_join_rel(root, joinrel, appinfo,
900+
outerrel, childrel, jointype,
901+
&this_restrictlist);
923902

924903
/* Build Path for join and add to result list */
925904
append_paths = lappend(append_paths,

src/backend/optimizer/plan/planner.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/optimizer/plan/planner.c,v 1.197 2006/01/31 21:39:24 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/optimizer/plan/planner.c,v 1.198 2006/02/03 21:08:49 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -222,7 +222,7 @@ subquery_planner(Query *parse, double tuple_fraction,
222222
* this query.
223223
*/
224224
parse->jointree = (FromExpr *)
225-
pull_up_subqueries(root, (Node *) parse->jointree, false);
225+
pull_up_subqueries(root, (Node *) parse->jointree, false, false);
226226

227227
/*
228228
* Detect whether any rangetable entries are RTE_JOIN kind; if not, we can

0 commit comments

Comments
 (0)