diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2003-06-29 23:05:05 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2003-06-29 23:05:05 +0000 |
commit | 835bb975d8d11268582d9dbd26b0eeaa62b60632 (patch) | |
tree | 5d5d3d57acfe7627235aa72c28c37d8c85b210a3 /src/backend/optimizer/plan/createplan.c | |
parent | cf883ea95c4bad69910300cbd6c0ef5cb84a9178 (diff) | |
download | postgresql-835bb975d8d11268582d9dbd26b0eeaa62b60632.tar.gz postgresql-835bb975d8d11268582d9dbd26b0eeaa62b60632.zip |
Restructure building of join relation targetlists so that a join plan
node emits only those vars that are actually needed above it in the
plan tree. (There were comments in the code suggesting that this was
done at some point in the dim past, but for a long time we have just
made join nodes emit everything that either input emitted.) Aside from
being marginally more efficient, this fixes the problem noted by Peter
Eisentraut where a join above an IN-implemented-as-join might fail,
because the subplan targetlist constructed in the latter case didn't
meet the expectation of including everything.
Along the way, fix some places that were O(N^2) in the targetlist
length. This is not all the trouble spots for wide queries by any
means, but it's a step forward.
Diffstat (limited to 'src/backend/optimizer/plan/createplan.c')
-rw-r--r-- | src/backend/optimizer/plan/createplan.c | 78 |
1 files changed, 42 insertions, 36 deletions
diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c index 81ee7962df9..1cdc3628b20 100644 --- a/src/backend/optimizer/plan/createplan.c +++ b/src/backend/optimizer/plan/createplan.c @@ -10,7 +10,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.146 2003/06/16 02:03:37 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.147 2003/06/29 23:05:04 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -23,6 +23,7 @@ #include "optimizer/clauses.h" #include "optimizer/cost.h" #include "optimizer/paths.h" +#include "optimizer/plancat.h" #include "optimizer/planmain.h" #include "optimizer/restrictinfo.h" #include "optimizer/tlist.h" @@ -34,6 +35,7 @@ static Scan *create_scan_plan(Query *root, Path *best_path); +static List *build_relation_tlist(RelOptInfo *rel); static bool use_physical_tlist(RelOptInfo *rel); static void disuse_physical_tlist(Plan *plan, Path *path); static Join *create_join_plan(Query *root, JoinPath *best_path); @@ -199,20 +201,13 @@ create_scan_plan(Query *root, Path *best_path) */ if (use_physical_tlist(rel)) { - int resdomno = 1; - List *v; - - tlist = NIL; - foreach(v, rel->varlist) - { - Var *var = (Var *) lfirst(v); - - tlist = lappend(tlist, create_tl_element(var, resdomno)); - resdomno++; - } + tlist = build_physical_tlist(root, rel); + /* if fail because of dropped cols, use regular method */ + if (tlist == NIL) + tlist = build_relation_tlist(rel); } else - tlist = rel->targetlist; + tlist = build_relation_tlist(rel); /* * Extract the relevant restriction clauses from the parent relation; @@ -267,6 +262,28 @@ create_scan_plan(Query *root, Path *best_path) } /* + * Build a target list (ie, a list of TargetEntry) for a relation. + */ +static List * +build_relation_tlist(RelOptInfo *rel) +{ + FastList tlist; + int resdomno = 1; + List *v; + + FastListInit(&tlist); + foreach(v, FastListValue(&rel->reltargetlist)) + { + /* Do we really need to copy here? Not sure */ + Var *var = (Var *) copyObject(lfirst(v)); + + FastAppend(&tlist, create_tl_element(var, resdomno)); + resdomno++; + } + return FastListValue(&tlist); +} + +/* * use_physical_tlist * Decide whether to use a tlist matching relation structure, * rather than only those Vars actually referenced. @@ -274,12 +291,12 @@ create_scan_plan(Query *root, Path *best_path) static bool use_physical_tlist(RelOptInfo *rel) { - List *t; + int i; /* * Currently, can't do this for subquery or function scans. (This - * is mainly because we don't set up the necessary info when creating - * their RelOptInfo nodes.) + * is mainly because we don't have an equivalent of build_physical_tlist + * for them; worth adding?) */ if (rel->rtekind != RTE_RELATION) return false; @@ -290,25 +307,14 @@ use_physical_tlist(RelOptInfo *rel) if (rel->reloptkind != RELOPT_BASEREL) return false; /* - * Can't do it if relation contains dropped columns. This is detected - * in plancat.c, see notes there. - */ - if (rel->varlist == NIL) - return false; - /* * Can't do it if any system columns are requested, either. (This could * possibly be fixed but would take some fragile assumptions in setrefs.c, * I think.) */ - foreach(t, rel->targetlist) + for (i = rel->min_attr; i <= 0; i++) { - TargetEntry *tle = (TargetEntry *) lfirst(t); - Var *var = (Var *) tle->expr; - - if (!var || !IsA(var, Var)) - return false; /* probably can't happen */ - if (var->varattno <= 0) - return false; /* system column! */ + if (!bms_is_empty(rel->attr_needed[i - rel->min_attr])) + return false; } return true; } @@ -333,7 +339,7 @@ disuse_physical_tlist(Plan *plan, Path *path) case T_TidScan: case T_SubqueryScan: case T_FunctionScan: - plan->targetlist = path->parent->targetlist; + plan->targetlist = build_relation_tlist(path->parent); break; default: break; @@ -411,7 +417,7 @@ static Append * create_append_plan(Query *root, AppendPath *best_path) { Append *plan; - List *tlist = best_path->path.parent->targetlist; + List *tlist = build_relation_tlist(best_path->path.parent); List *subplans = NIL; List *subpaths; @@ -443,7 +449,7 @@ create_result_plan(Query *root, ResultPath *best_path) Plan *subplan; if (best_path->path.parent) - tlist = best_path->path.parent->targetlist; + tlist = build_relation_tlist(best_path->path.parent); else tlist = NIL; /* will be filled in later */ @@ -842,7 +848,7 @@ create_nestloop_plan(Query *root, Plan *outer_plan, Plan *inner_plan) { - List *tlist = best_path->path.parent->targetlist; + List *tlist = build_relation_tlist(best_path->path.parent); List *joinrestrictclauses = best_path->joinrestrictinfo; List *joinclauses; List *otherclauses; @@ -912,7 +918,7 @@ create_mergejoin_plan(Query *root, Plan *outer_plan, Plan *inner_plan) { - List *tlist = best_path->jpath.path.parent->targetlist; + List *tlist = build_relation_tlist(best_path->jpath.path.parent); List *joinclauses; List *otherclauses; List *mergeclauses; @@ -992,7 +998,7 @@ create_hashjoin_plan(Query *root, Plan *outer_plan, Plan *inner_plan) { - List *tlist = best_path->jpath.path.parent->targetlist; + List *tlist = build_relation_tlist(best_path->jpath.path.parent); List *joinclauses; List *otherclauses; List *hashclauses; |