summaryrefslogtreecommitdiff
path: root/src/backend/optimizer/path
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/optimizer/path')
-rw-r--r--src/backend/optimizer/path/allpaths.c21
-rw-r--r--src/backend/optimizer/path/costsize.c88
-rw-r--r--src/backend/optimizer/path/equivclass.c4
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);