*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.50 1999/03/01 00:10:33 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.51 1999/04/30 04:04:27 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#include "utils/builtins.h"
#include "optimizer/restrictinfo.h"
+#include "optimizer/cost.h"
#include "optimizer/clauses.h"
#include "optimizer/planmain.h"
#include "optimizer/tlist.h"
static Noname *make_noname(List *tlist, List *pathkeys, Oid *operators,
Plan *plan_node, int nonametype);
static IndexScan *make_indexscan(List *qptlist, List *qpqual, Index scanrelid,
- List *indxid, List *indxqual, List *indxqualorig, Cost cost);
+ List *indxid, List *indxqual, List *indxqualorig);
static NestLoop *make_nestloop(List *qptlist, List *qpqual, Plan *lefttree,
Plan *righttree);
static HashJoin *make_hashjoin(List *tlist, List *qpqual,
List *mergeclauses, Plan *righttree, Plan *lefttree);
static Material *make_material(List *tlist, Oid nonameid, Plan *lefttree,
int keycount);
+static void copy_costsize(Plan *dest, Plan *src);
/*
* create_plan
lfirsti(best_path->path.parent->relids),
best_path->indexid,
fixed_indxqual,
- indxqual,
- best_path->path.path_cost);
+ indxqual);
+
+ scan_node->scan.plan.cost = best_path->path.path_cost;
return scan_node;
}
Oid *outer_order = generate_merge_input_sortorder(
best_path->outersortkeys,
best_path->jpath.path.pathorder->ord.merge);
- Noname *sorted_outer_node = make_noname(outer_tlist,
- best_path->outersortkeys,
- outer_order,
- outer_node,
- NONAME_SORT);
-
- sorted_outer_node->plan.cost = outer_node->cost;
- outer_node = (Plan *) sorted_outer_node;
+ outer_node = (Plan *) make_noname(outer_tlist,
+ best_path->outersortkeys,
+ outer_order,
+ outer_node,
+ NONAME_SORT);
}
if (best_path->innersortkeys)
Oid *inner_order = generate_merge_input_sortorder(
best_path->innersortkeys,
best_path->jpath.path.pathorder->ord.merge);
- Noname *sorted_inner_node = make_noname(inner_tlist,
- best_path->innersortkeys,
- inner_order,
- inner_node,
- NONAME_SORT);
-
- sorted_inner_node->plan.cost = outer_node->cost; /* XXX not inner_node? */
- inner_node = (Plan *) sorted_inner_node;
+ inner_node = (Plan *) make_noname(inner_tlist,
+ best_path->innersortkeys,
+ inner_order,
+ inner_node,
+ NONAME_SORT);
}
join_node = make_mergejoin(tlist,
hashclauses,
outer_node,
(Plan *) hash_node);
+
join_node->join.cost = best_path->jpath.path.path_cost;
return join_node;
return tlist;
}
+/*
+ * 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.
+ */
+
+static void
+copy_costsize (Plan *dest, Plan *src)
+{
+ if (src)
+ {
+ dest->cost = src->cost;
+ dest->plan_size = src->plan_size;
+ dest->plan_width = src->plan_width;
+ }
+ else
+ {
+ dest->cost = 0;
+ dest->plan_size = 0;
+ dest->plan_width = 0;
+ }
+}
+
+
/*****************************************************************************
*
*
SeqScan *node = makeNode(SeqScan);
Plan *plan = &node->plan;
- plan->cost = (lefttree ? lefttree->cost : 0);
+ copy_costsize(plan, lefttree);
plan->state = (EState *) NULL;
plan->targetlist = qptlist;
plan->qual = qpqual;
Index scanrelid,
List *indxid,
List *indxqual,
- List *indxqualorig,
- Cost cost)
+ List *indxqualorig)
{
IndexScan *node = makeNode(IndexScan);
Plan *plan = &node->scan.plan;
- plan->cost = cost;
+ copy_costsize(plan, NULL);
plan->state = (EState *) NULL;
plan->targetlist = qptlist;
plan->qual = qpqual;
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);
plan->state = (EState *) NULL;
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);
- plan->cost = 0.0;
plan->state = (EState *) NULL;
plan->targetlist = tlist;
plan->qual = qpqual;
Hash *node = makeNode(Hash);
Plan *plan = &node->plan;
- plan->cost = (lefttree ? lefttree->cost : 0);
- plan->cost = 0.0;
+ copy_costsize(plan, lefttree);
plan->state = (EState *) NULL;
plan->targetlist = tlist;
plan->qual = NULL;
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);
plan->state = (EState *) NULL;
Sort *node = makeNode(Sort);
Plan *plan = &node->plan;
- plan->cost = (lefttree ? lefttree->cost : 0);
+ copy_costsize(plan, lefttree);
+ plan->cost += cost_sort(NULL, plan->plan_size, plan->plan_width, true);
plan->state = (EState *) NULL;
plan->targetlist = tlist;
plan->qual = NIL;
Material *node = makeNode(Material);
Plan *plan = &node->plan;
- plan->cost = (lefttree ? lefttree->cost : 0);
+ copy_costsize(plan, lefttree);
plan->state = (EState *) NULL;
plan->targetlist = tlist;
plan->qual = NIL;
{
Agg *node = makeNode(Agg);
- node->plan.cost = (lefttree ? lefttree->cost : 0);
+ copy_costsize(& node->plan, lefttree);
node->plan.state = (EState *) NULL;
node->plan.qual = NULL;
node->plan.targetlist = tlist;
{
Group *node = makeNode(Group);
- node->plan.cost = (lefttree ? lefttree->plan.cost : 0);
+ copy_costsize(& node->plan, (Plan *) lefttree);
node->plan.state = (EState *) NULL;
node->plan.qual = NULL;
node->plan.targetlist = tlist;
Unique *node = makeNode(Unique);
Plan *plan = &node->plan;
- plan->cost = (lefttree ? lefttree->cost : 0);
+ copy_costsize(plan, lefttree);
plan->state = (EState *) NULL;
plan->targetlist = tlist;
plan->qual = NIL;