aboutsummaryrefslogtreecommitdiff
path: root/src/backend/optimizer/path/costsize.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/optimizer/path/costsize.c')
-rw-r--r--src/backend/optimizer/path/costsize.c52
1 files changed, 38 insertions, 14 deletions
diff --git a/src/backend/optimizer/path/costsize.c b/src/backend/optimizer/path/costsize.c
index c7d21d00310..223a0616fa0 100644
--- a/src/backend/optimizer/path/costsize.c
+++ b/src/backend/optimizer/path/costsize.c
@@ -855,14 +855,19 @@ cost_bitmap_or_node(BitmapOrPath *path, PlannerInfo *root)
/*
* cost_tidscan
* Determines and returns the cost of scanning a relation using TIDs.
+ *
+ * 'baserel' is the relation to be scanned
+ * 'tidquals' is the list of TID-checkable quals
+ * 'param_info' is the ParamPathInfo if this is a parameterized path, else NULL
*/
void
cost_tidscan(Path *path, PlannerInfo *root,
- RelOptInfo *baserel, List *tidquals)
+ RelOptInfo *baserel, List *tidquals, ParamPathInfo *param_info)
{
Cost startup_cost = 0;
Cost run_cost = 0;
bool isCurrentOf = false;
+ QualCost qpqual_cost;
Cost cpu_per_tuple;
QualCost tid_qual_cost;
int ntuples;
@@ -873,8 +878,11 @@ cost_tidscan(Path *path, PlannerInfo *root,
Assert(baserel->relid > 0);
Assert(baserel->rtekind == RTE_RELATION);
- /* For now, tidscans are never parameterized */
- path->rows = baserel->rows;
+ /* Mark the path with the correct row estimate */
+ if (param_info)
+ path->rows = param_info->ppi_rows;
+ else
+ path->rows = baserel->rows;
/* Count how many tuples we expect to retrieve */
ntuples = 0;
@@ -931,10 +939,12 @@ cost_tidscan(Path *path, PlannerInfo *root,
/* disk costs --- assume each tuple on a different page */
run_cost += spc_random_page_cost * ntuples;
- /* CPU costs */
- startup_cost += baserel->baserestrictcost.startup +
- tid_qual_cost.per_tuple;
- cpu_per_tuple = cpu_tuple_cost + baserel->baserestrictcost.per_tuple -
+ /* Add scanning CPU costs */
+ get_restriction_qual_cost(root, baserel, param_info, &qpqual_cost);
+
+ /* XXX currently we assume TID quals are a subset of qpquals */
+ startup_cost += qpqual_cost.startup + tid_qual_cost.per_tuple;
+ cpu_per_tuple = cpu_tuple_cost + qpqual_cost.per_tuple -
tid_qual_cost.per_tuple;
run_cost += cpu_per_tuple * ntuples;
@@ -1097,25 +1107,32 @@ cost_valuesscan(Path *path, PlannerInfo *root,
* and should NOT be counted here.
*/
void
-cost_ctescan(Path *path, PlannerInfo *root, RelOptInfo *baserel)
+cost_ctescan(Path *path, PlannerInfo *root,
+ RelOptInfo *baserel, ParamPathInfo *param_info)
{
Cost startup_cost = 0;
Cost run_cost = 0;
+ QualCost qpqual_cost;
Cost cpu_per_tuple;
/* Should only be applied to base relations that are CTEs */
Assert(baserel->relid > 0);
Assert(baserel->rtekind == RTE_CTE);
- /* ctescans are never parameterized */
- path->rows = baserel->rows;
+ /* Mark the path with the correct row estimate */
+ if (param_info)
+ path->rows = param_info->ppi_rows;
+ else
+ path->rows = baserel->rows;
/* Charge one CPU tuple cost per row for tuplestore manipulation */
cpu_per_tuple = cpu_tuple_cost;
/* Add scanning CPU costs */
- startup_cost += baserel->baserestrictcost.startup;
- cpu_per_tuple += cpu_tuple_cost + baserel->baserestrictcost.per_tuple;
+ get_restriction_qual_cost(root, baserel, param_info, &qpqual_cost);
+
+ startup_cost += qpqual_cost.startup;
+ cpu_per_tuple += cpu_tuple_cost + qpqual_cost.per_tuple;
run_cost += cpu_per_tuple * baserel->tuples;
path->startup_cost = startup_cost;
@@ -3904,13 +3921,20 @@ set_rel_width(PlannerInfo *root, RelOptInfo *rel)
{
Node *node = (Node *) lfirst(lc);
- if (IsA(node, Var))
+ /*
+ * Ordinarily, a Var in a rel's reltargetlist must belong to that rel;
+ * but there are corner cases involving LATERAL references in
+ * appendrel members where that isn't so (see set_append_rel_size()).
+ * If the Var has the wrong varno, fall through to the generic case
+ * (it doesn't seem worth the trouble to be any smarter).
+ */
+ if (IsA(node, Var) &&
+ ((Var *) node)->varno == rel->relid)
{
Var *var = (Var *) node;
int ndx;
int32 item_width;
- Assert(var->varno == rel->relid);
Assert(var->varattno >= rel->min_attr);
Assert(var->varattno <= rel->max_attr);