Commit d24ef0d0 authored by Tom Lane's avatar Tom Lane

Make EXPLAIN results for Append, Group, Agg, Unique nodes more plausible.

Group and Unique use an arbitrary assumption that there will be about
10% as many groups as input tuples --- perhaps someday we can refine this.
parent 40055db1
......@@ -10,7 +10,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.82 2000/01/27 18:11:30 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.83 2000/02/03 06:12:18 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -743,9 +743,9 @@ create_hashjoin_node(HashPath *best_path,
* * Var nodes representing index keys must have varattno equal to the
* index's attribute number, not the attribute number in the original rel.
* * indxpath.c may have selected an index that is binary-compatible with
* the actual expression operator, but not the same; we must replace the
* expression's operator with the binary-compatible equivalent operator
* that the index will recognize.
* the actual expression operator, but not exactly the same datatype.
* We must replace the expression's operator with the binary-compatible
* equivalent operator that the index will recognize.
* * If the index key is on the right, commute the clause to put it on the
* left. (Someday the executor might not need this, but for now it does.)
*
......@@ -1054,6 +1054,7 @@ copy_path_costsize(Plan *dest, Path *src)
* Copy cost and size info from a lower plan node to an inserted node.
* This is not critical, since the decisions have already been made,
* but it helps produce more reasonable-looking EXPLAIN output.
* (Some callers alter the info after copying it.)
*/
static void
copy_plan_costsize(Plan *dest, Plan *src)
......@@ -1178,12 +1179,7 @@ make_nestloop(List *qptlist,
NestLoop *node = makeNode(NestLoop);
Plan *plan = &node->join;
/*
* this cost estimate is entirely bogus... hopefully it will be
* overwritten by caller.
*/
plan->cost = (lefttree ? lefttree->cost : 0) +
(righttree ? righttree->cost : 0);
/* cost should be inserted by caller */
plan->state = (EState *) NULL;
plan->targetlist = qptlist;
plan->qual = qpqual;
......@@ -1204,12 +1200,7 @@ make_hashjoin(List *tlist,
HashJoin *node = makeNode(HashJoin);
Plan *plan = &node->join;
/*
* this cost estimate is entirely bogus... hopefully it will be
* overwritten by caller.
*/
plan->cost = (lefttree ? lefttree->cost : 0) +
(righttree ? righttree->cost : 0);
/* cost should be inserted by caller */
plan->state = (EState *) NULL;
plan->targetlist = tlist;
plan->qual = qpqual;
......@@ -1248,12 +1239,7 @@ make_mergejoin(List *tlist,
MergeJoin *node = makeNode(MergeJoin);
Plan *plan = &node->join;
/*
* this cost estimate is entirely bogus... hopefully it will be
* overwritten by caller.
*/
plan->cost = (lefttree ? lefttree->cost : 0) +
(righttree ? righttree->cost : 0);
/* cost should be inserted by caller */
plan->state = (EState *) NULL;
plan->targetlist = tlist;
plan->qual = qpqual;
......@@ -1293,6 +1279,7 @@ make_material(List *tlist,
Plan *plan = &node->plan;
copy_plan_costsize(plan, lefttree);
/* XXX shouldn't we charge some additional cost for materialization? */
plan->state = (EState *) NULL;
plan->targetlist = tlist;
plan->qual = NIL;
......@@ -1310,6 +1297,20 @@ make_agg(List *tlist, Plan *lefttree)
Agg *node = makeNode(Agg);
copy_plan_costsize(&node->plan, lefttree);
/*
* The tuple width from the input node is OK, as is the cost (we are
* ignoring the cost of computing the aggregate; is there any value
* in accounting for it?). But the tuple count is bogus. We will
* produce a single tuple if the input is not a Group, and a tuple
* per group otherwise. For now, estimate the number of groups as
* 10% of the number of tuples --- bogus, but how to do better?
* (Note we assume the input Group node is in "tuplePerGroup" mode,
* so it didn't reduce its row count already.)
*/
if (IsA(lefttree, Group))
node->plan.plan_rows *= 0.1;
else
node->plan.plan_rows = 1;
node->plan.state = (EState *) NULL;
node->plan.qual = NULL;
node->plan.targetlist = tlist;
......@@ -1329,6 +1330,15 @@ make_group(List *tlist,
Group *node = makeNode(Group);
copy_plan_costsize(&node->plan, lefttree);
/*
* If tuplePerGroup (which is named exactly backwards) is true,
* we will return all the input tuples, so the input node's row count
* is OK. Otherwise, we'll return only one tuple from each group.
* For now, estimate the number of groups as 10% of the number of
* tuples --- bogus, but how to do better?
*/
if (! tuplePerGroup)
node->plan.plan_rows *= 0.1;
node->plan.state = (EState *) NULL;
node->plan.qual = NULL;
node->plan.targetlist = tlist;
......@@ -1357,6 +1367,11 @@ make_unique(List *tlist, Plan *lefttree, List *distinctList)
List *slitem;
copy_plan_costsize(plan, lefttree);
/*
* As for Group, we make the unsupported assumption that there will be
* 10% as many tuples out as in.
*/
plan->plan_rows *= 0.1;
plan->state = (EState *) NULL;
plan->targetlist = tlist;
plan->qual = NIL;
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/prep/prepunion.c,v 1.42 2000/01/27 18:11:32 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/optimizer/prep/prepunion.c,v 1.43 2000/02/03 06:12:19 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -218,11 +218,11 @@ plan_union_queries(Query *parse)
parse->havingQual = NULL;
parse->hasAggs = false;
return (make_append(union_plans,
union_rts,
0,
NULL,
parse->targetList));
return make_append(union_plans,
union_rts,
0,
NULL,
parse->targetList);
}
......@@ -272,11 +272,11 @@ plan_inherit_queries(Query *parse, List *tlist, Index rt_index)
union_plans = plan_inherit_query(union_relids, rt_index, rt_entry,
parse, tlist, &inheritrtable);
return (make_append(union_plans,
NULL,
rt_index,
inheritrtable,
((Plan *) lfirst(union_plans))->targetlist));
return make_append(union_plans,
NULL,
rt_index,
inheritrtable,
((Plan *) lfirst(union_plans))->targetlist);
}
/*
......@@ -551,9 +551,18 @@ make_append(List *appendplans,
node->unionrtables = unionrtables;
node->inheritrelid = rt_index;
node->inheritrtable = inheritrtable;
node->plan.cost = 0.0;
node->plan.cost = 0;
node->plan.plan_rows = 0;
node->plan.plan_width = 0;
foreach(subnode, appendplans)
node->plan.cost += ((Plan *) lfirst(subnode))->cost;
{
Plan *subplan = (Plan *) lfirst(subnode);
node->plan.cost += subplan->cost;
node->plan.plan_rows += subplan->plan_rows;
if (node->plan.plan_width < subplan->plan_width)
node->plan.plan_width = subplan->plan_width;
}
node->plan.state = (EState *) NULL;
node->plan.targetlist = tlist;
node->plan.qual = NIL;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment