diff options
Diffstat (limited to 'src/backend/optimizer/path')
| -rw-r--r-- | src/backend/optimizer/path/allpaths.c | 21 | ||||
| -rw-r--r-- | src/backend/optimizer/path/costsize.c | 88 | ||||
| -rw-r--r-- | src/backend/optimizer/path/equivclass.c | 4 |
3 files changed, 71 insertions, 42 deletions
diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c index a942249fd0..7d6a3b8d6b 100644 --- a/src/backend/optimizer/path/allpaths.c +++ b/src/backend/optimizer/path/allpaths.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/optimizer/path/allpaths.c,v 1.174 2008/10/04 21:56:53 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/optimizer/path/allpaths.c,v 1.175 2008/10/21 20:42:52 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -423,6 +423,10 @@ set_append_rel_pathlist(PlannerInfo *root, RelOptInfo *rel, Var *parentvar = (Var *) lfirst(parentvars); Var *childvar = (Var *) lfirst(childvars); + /* + * Accumulate per-column estimates too. Whole-row Vars and + * PlaceHolderVars can be ignored here. + */ if (IsA(parentvar, Var) && IsA(childvar, Var)) { @@ -1105,12 +1109,25 @@ qual_is_pushdown_safe(Query *subquery, Index rti, Node *qual, * Examine all Vars used in clause; since it's a restriction clause, all * such Vars must refer to subselect output columns. */ - vars = pull_var_clause(qual, false); + vars = pull_var_clause(qual, true); foreach(vl, vars) { Var *var = (Var *) lfirst(vl); TargetEntry *tle; + /* + * XXX Punt if we find any PlaceHolderVars in the restriction clause. + * It's not clear whether a PHV could safely be pushed down, and even + * less clear whether such a situation could arise in any cases of + * practical interest anyway. So for the moment, just refuse to push + * down. + */ + if (!IsA(var, Var)) + { + safe = false; + break; + } + Assert(var->varno == rti); /* Check point 2 */ diff --git a/src/backend/optimizer/path/costsize.c b/src/backend/optimizer/path/costsize.c index fa580cf14e..ba33da829a 100644 --- a/src/backend/optimizer/path/costsize.c +++ b/src/backend/optimizer/path/costsize.c @@ -54,7 +54,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/optimizer/path/costsize.c,v 1.199 2008/10/17 20:27:24 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/optimizer/path/costsize.c,v 1.200 2008/10/21 20:42:52 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -69,6 +69,7 @@ #include "optimizer/clauses.h" #include "optimizer/cost.h" #include "optimizer/pathnode.h" +#include "optimizer/placeholder.h" #include "optimizer/planmain.h" #include "parser/parsetree.h" #include "utils/lsyscache.h" @@ -2610,55 +2611,66 @@ set_rel_width(PlannerInfo *root, RelOptInfo *rel) { Oid reloid = planner_rt_fetch(rel->relid, root)->relid; int32 tuple_width = 0; - ListCell *tllist; + ListCell *lc; - foreach(tllist, rel->reltargetlist) + foreach(lc, rel->reltargetlist) { - Var *var = (Var *) lfirst(tllist); - int ndx; - int32 item_width; + Node *node = (Node *) lfirst(lc); - /* For now, punt on whole-row child Vars */ - if (!IsA(var, Var)) + if (IsA(node, Var)) { - tuple_width += 32; /* arbitrary */ - continue; - } - - Assert(var->varno == rel->relid); - Assert(var->varattno >= rel->min_attr); - Assert(var->varattno <= rel->max_attr); + Var *var = (Var *) node; + int ndx; + int32 item_width; - ndx = var->varattno - rel->min_attr; + Assert(var->varno == rel->relid); + Assert(var->varattno >= rel->min_attr); + Assert(var->varattno <= rel->max_attr); - /* - * The width probably hasn't been cached yet, but may as well check - */ - if (rel->attr_widths[ndx] > 0) - { - tuple_width += rel->attr_widths[ndx]; - continue; - } + ndx = var->varattno - rel->min_attr; - if (reloid != InvalidOid) - { - item_width = get_attavgwidth(reloid, var->varattno); - if (item_width > 0) + /* + * The width probably hasn't been cached yet, but may as well check + */ + if (rel->attr_widths[ndx] > 0) { - rel->attr_widths[ndx] = item_width; - tuple_width += item_width; + tuple_width += rel->attr_widths[ndx]; continue; } + + /* Try to get column width from statistics */ + if (reloid != InvalidOid) + { + item_width = get_attavgwidth(reloid, var->varattno); + if (item_width > 0) + { + rel->attr_widths[ndx] = item_width; + tuple_width += item_width; + continue; + } + } + + /* + * Not a plain relation, or can't find statistics for it. Estimate + * using just the type info. + */ + item_width = get_typavgwidth(var->vartype, var->vartypmod); + Assert(item_width > 0); + rel->attr_widths[ndx] = item_width; + tuple_width += item_width; } + else if (IsA(node, PlaceHolderVar)) + { + PlaceHolderVar *phv = (PlaceHolderVar *) node; + PlaceHolderInfo *phinfo = find_placeholder_info(root, phv); - /* - * Not a plain relation, or can't find statistics for it. Estimate - * using just the type info. - */ - item_width = get_typavgwidth(var->vartype, var->vartypmod); - Assert(item_width > 0); - rel->attr_widths[ndx] = item_width; - tuple_width += item_width; + tuple_width += phinfo->ph_width; + } + else + { + /* For now, punt on whole-row child Vars */ + tuple_width += 32; /* arbitrary */ + } } Assert(tuple_width >= 0); rel->width = tuple_width; diff --git a/src/backend/optimizer/path/equivclass.c b/src/backend/optimizer/path/equivclass.c index 0847b95574..c035100875 100644 --- a/src/backend/optimizer/path/equivclass.c +++ b/src/backend/optimizer/path/equivclass.c @@ -10,7 +10,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/optimizer/path/equivclass.c,v 1.12 2008/08/25 22:42:33 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/optimizer/path/equivclass.c,v 1.13 2008/10/21 20:42:52 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -687,7 +687,7 @@ generate_base_implied_equalities_no_const(PlannerInfo *root, foreach(lc, ec->ec_members) { EquivalenceMember *cur_em = (EquivalenceMember *) lfirst(lc); - List *vars = pull_var_clause((Node *) cur_em->em_expr, false); + List *vars = pull_var_clause((Node *) cur_em->em_expr, true); add_vars_to_targetlist(root, vars, ec->ec_relids); list_free(vars); |
