Commit 7c579fa1 authored by Tom Lane's avatar Tom Lane

Further work on making use of new statistics in planner. Adjust APIs

of costsize.c routines to pass Query root, so that costsize can figure
more things out by itself and not be so dependent on its callers to tell
it everything it needs to know.  Use selectivity of hash or merge clause
to estimate number of tuples processed internally in these joins
(this is more useful than it would've been before, since eqjoinsel is
somewhat more accurate than before).
parent 28d2420e
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.142 2001/05/20 20:28:17 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.143 2001/06/05 05:26:03 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -1361,9 +1361,10 @@ _copyRestrictInfo(RestrictInfo *from) ...@@ -1361,9 +1361,10 @@ _copyRestrictInfo(RestrictInfo *from)
* copy remainder of node * copy remainder of node
*/ */
Node_Copy(from, newnode, clause); Node_Copy(from, newnode, clause);
newnode->eval_cost = from->eval_cost;
newnode->ispusheddown = from->ispusheddown; newnode->ispusheddown = from->ispusheddown;
Node_Copy(from, newnode, subclauseindices); Node_Copy(from, newnode, subclauseindices);
newnode->eval_cost = from->eval_cost;
newnode->this_selec = from->this_selec;
newnode->mergejoinoperator = from->mergejoinoperator; newnode->mergejoinoperator = from->mergejoinoperator;
newnode->left_sortop = from->left_sortop; newnode->left_sortop = from->left_sortop;
newnode->right_sortop = from->right_sortop; newnode->right_sortop = from->right_sortop;
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.90 2001/05/20 20:28:18 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.91 2001/06/05 05:26:03 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -514,14 +514,14 @@ _equalRestrictInfo(RestrictInfo *a, RestrictInfo *b) ...@@ -514,14 +514,14 @@ _equalRestrictInfo(RestrictInfo *a, RestrictInfo *b)
{ {
if (!equal(a->clause, b->clause)) if (!equal(a->clause, b->clause))
return false; return false;
/*
* ignore eval_cost, left/right_pathkey, and left/right_bucketsize,
* since they may not be set yet, and should be derivable from the
* clause anyway
*/
if (a->ispusheddown != b->ispusheddown) if (a->ispusheddown != b->ispusheddown)
return false; return false;
/*
* We ignore eval_cost, this_selec, left/right_pathkey, and
* left/right_bucketsize, since they may not be set yet, and should be
* derivable from the clause anyway. Probably it's not really necessary
* to compare any of these remaining fields ...
*/
if (!equal(a->subclauseindices, b->subclauseindices)) if (!equal(a->subclauseindices, b->subclauseindices))
return false; return false;
if (a->mergejoinoperator != b->mergejoinoperator) if (a->mergejoinoperator != b->mergejoinoperator)
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/nodes/readfuncs.c,v 1.109 2001/05/20 20:28:18 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/nodes/readfuncs.c,v 1.110 2001/06/05 05:26:04 tgl Exp $
* *
* NOTES * NOTES
* Most of the read functions for plan nodes are tested. (In fact, they * Most of the read functions for plan nodes are tested. (In fact, they
...@@ -1792,6 +1792,8 @@ _readRestrictInfo(void) ...@@ -1792,6 +1792,8 @@ _readRestrictInfo(void)
/* eval_cost is not part of saved representation; compute on first use */ /* eval_cost is not part of saved representation; compute on first use */
local_node->eval_cost = -1; local_node->eval_cost = -1;
/* ditto for this_selec */
local_node->this_selec = -1;
/* ditto for cached pathkeys and bucketsize */ /* ditto for cached pathkeys and bucketsize */
local_node->left_pathkey = NIL; local_node->left_pathkey = NIL;
local_node->right_pathkey = NIL; local_node->right_pathkey = NIL;
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/allpaths.c,v 1.74 2001/05/20 20:28:18 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/optimizer/path/allpaths.c,v 1.75 2001/06/05 05:26:04 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -223,7 +223,7 @@ set_plain_rel_pathlist(Query *root, RelOptInfo *rel, RangeTblEntry *rte) ...@@ -223,7 +223,7 @@ set_plain_rel_pathlist(Query *root, RelOptInfo *rel, RangeTblEntry *rte)
*/ */
/* Consider sequential scan */ /* Consider sequential scan */
add_path(rel, create_seqscan_path(rel)); add_path(rel, create_seqscan_path(root, rel));
/* Consider TID scans */ /* Consider TID scans */
create_tidscan_paths(root, rel); create_tidscan_paths(root, rel);
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/clausesel.c,v 1.44 2001/05/20 20:28:18 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/optimizer/path/clausesel.c,v 1.45 2001/06/05 05:26:04 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -48,9 +48,6 @@ typedef struct RangeQueryClause ...@@ -48,9 +48,6 @@ typedef struct RangeQueryClause
static void addRangeClause(RangeQueryClause **rqlist, Node *clause, static void addRangeClause(RangeQueryClause **rqlist, Node *clause,
bool varonleft, bool isLTsel, Selectivity s2); bool varonleft, bool isLTsel, Selectivity s2);
static Selectivity clause_selectivity(Query *root,
Node *clause,
int varRelid);
/**************************************************************************** /****************************************************************************
...@@ -364,7 +361,7 @@ addRangeClause(RangeQueryClause **rqlist, Node *clause, ...@@ -364,7 +361,7 @@ addRangeClause(RangeQueryClause **rqlist, Node *clause,
* When varRelid is 0, all variables are treated as variables. This * When varRelid is 0, all variables are treated as variables. This
* is appropriate for ordinary join clauses and restriction clauses. * is appropriate for ordinary join clauses and restriction clauses.
*/ */
static Selectivity Selectivity
clause_selectivity(Query *root, clause_selectivity(Query *root,
Node *clause, Node *clause,
int varRelid) int varRelid)
......
This diff is collapsed.
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/joinpath.c,v 1.64 2001/05/07 00:43:20 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/optimizer/path/joinpath.c,v 1.65 2001/06/05 05:26:04 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -236,7 +236,8 @@ sort_inner_and_outer(Query *root, ...@@ -236,7 +236,8 @@ sort_inner_and_outer(Query *root,
* paths later, and only if they don't need a sort. * paths later, and only if they don't need a sort.
*/ */
add_path(joinrel, (Path *) add_path(joinrel, (Path *)
create_mergejoin_path(joinrel, create_mergejoin_path(root,
joinrel,
jointype, jointype,
outerrel->cheapest_total_path, outerrel->cheapest_total_path,
innerrel->cheapest_total_path, innerrel->cheapest_total_path,
...@@ -357,7 +358,8 @@ match_unsorted_outer(Query *root, ...@@ -357,7 +358,8 @@ match_unsorted_outer(Query *root,
* innerjoin indexpath. * innerjoin indexpath.
*/ */
add_path(joinrel, (Path *) add_path(joinrel, (Path *)
create_nestloop_path(joinrel, create_nestloop_path(root,
joinrel,
jointype, jointype,
outerpath, outerpath,
innerrel->cheapest_total_path, innerrel->cheapest_total_path,
...@@ -366,7 +368,8 @@ match_unsorted_outer(Query *root, ...@@ -366,7 +368,8 @@ match_unsorted_outer(Query *root,
if (innerrel->cheapest_startup_path != if (innerrel->cheapest_startup_path !=
innerrel->cheapest_total_path) innerrel->cheapest_total_path)
add_path(joinrel, (Path *) add_path(joinrel, (Path *)
create_nestloop_path(joinrel, create_nestloop_path(root,
joinrel,
jointype, jointype,
outerpath, outerpath,
innerrel->cheapest_startup_path, innerrel->cheapest_startup_path,
...@@ -374,7 +377,8 @@ match_unsorted_outer(Query *root, ...@@ -374,7 +377,8 @@ match_unsorted_outer(Query *root,
merge_pathkeys)); merge_pathkeys));
if (bestinnerjoin != NULL) if (bestinnerjoin != NULL)
add_path(joinrel, (Path *) add_path(joinrel, (Path *)
create_nestloop_path(joinrel, create_nestloop_path(root,
joinrel,
jointype, jointype,
outerpath, outerpath,
bestinnerjoin, bestinnerjoin,
...@@ -405,7 +409,8 @@ match_unsorted_outer(Query *root, ...@@ -405,7 +409,8 @@ match_unsorted_outer(Query *root,
* innerrel->cheapest_total_path is already correctly sorted.) * innerrel->cheapest_total_path is already correctly sorted.)
*/ */
add_path(joinrel, (Path *) add_path(joinrel, (Path *)
create_mergejoin_path(joinrel, create_mergejoin_path(root,
joinrel,
jointype, jointype,
outerpath, outerpath,
innerrel->cheapest_total_path, innerrel->cheapest_total_path,
...@@ -464,7 +469,8 @@ match_unsorted_outer(Query *root, ...@@ -464,7 +469,8 @@ match_unsorted_outer(Query *root,
else else
newclauses = mergeclauses; newclauses = mergeclauses;
add_path(joinrel, (Path *) add_path(joinrel, (Path *)
create_mergejoin_path(joinrel, create_mergejoin_path(root,
joinrel,
jointype, jointype,
outerpath, outerpath,
innerpath, innerpath,
...@@ -507,7 +513,8 @@ match_unsorted_outer(Query *root, ...@@ -507,7 +513,8 @@ match_unsorted_outer(Query *root,
newclauses = mergeclauses; newclauses = mergeclauses;
} }
add_path(joinrel, (Path *) add_path(joinrel, (Path *)
create_mergejoin_path(joinrel, create_mergejoin_path(root,
joinrel,
jointype, jointype,
outerpath, outerpath,
innerpath, innerpath,
...@@ -605,7 +612,8 @@ match_unsorted_inner(Query *root, ...@@ -605,7 +612,8 @@ match_unsorted_inner(Query *root,
*/ */
merge_pathkeys = build_join_pathkeys(root, joinrel, outersortkeys); merge_pathkeys = build_join_pathkeys(root, joinrel, outersortkeys);
add_path(joinrel, (Path *) add_path(joinrel, (Path *)
create_mergejoin_path(joinrel, create_mergejoin_path(root,
joinrel,
jointype, jointype,
outerrel->cheapest_total_path, outerrel->cheapest_total_path,
innerpath, innerpath,
...@@ -633,7 +641,8 @@ match_unsorted_inner(Query *root, ...@@ -633,7 +641,8 @@ match_unsorted_inner(Query *root,
merge_pathkeys = build_join_pathkeys(root, joinrel, merge_pathkeys = build_join_pathkeys(root, joinrel,
totalouterpath->pathkeys); totalouterpath->pathkeys);
add_path(joinrel, (Path *) add_path(joinrel, (Path *)
create_mergejoin_path(joinrel, create_mergejoin_path(root,
joinrel,
jointype, jointype,
totalouterpath, totalouterpath,
innerpath, innerpath,
...@@ -651,7 +660,8 @@ match_unsorted_inner(Query *root, ...@@ -651,7 +660,8 @@ match_unsorted_inner(Query *root,
merge_pathkeys = build_join_pathkeys(root, joinrel, merge_pathkeys = build_join_pathkeys(root, joinrel,
startupouterpath->pathkeys); startupouterpath->pathkeys);
add_path(joinrel, (Path *) add_path(joinrel, (Path *)
create_mergejoin_path(joinrel, create_mergejoin_path(root,
joinrel,
jointype, jointype,
startupouterpath, startupouterpath,
innerpath, innerpath,
...@@ -718,10 +728,8 @@ hash_inner_and_outer(Query *root, ...@@ -718,10 +728,8 @@ hash_inner_and_outer(Query *root,
foreach(i, restrictlist) foreach(i, restrictlist)
{ {
RestrictInfo *restrictinfo = (RestrictInfo *) lfirst(i); RestrictInfo *restrictinfo = (RestrictInfo *) lfirst(i);
Expr *clause;
Var *left, Var *left,
*right; *right;
Selectivity innerbucketsize;
List *hashclauses; List *hashclauses;
if (restrictinfo->hashjoinoperator == InvalidOid) if (restrictinfo->hashjoinoperator == InvalidOid)
...@@ -734,42 +742,22 @@ hash_inner_and_outer(Query *root, ...@@ -734,42 +742,22 @@ hash_inner_and_outer(Query *root,
if (isouterjoin && restrictinfo->ispusheddown) if (isouterjoin && restrictinfo->ispusheddown)
continue; continue;
clause = restrictinfo->clause;
/* these must be OK, since check_hashjoinable accepted the clause */ /* these must be OK, since check_hashjoinable accepted the clause */
left = get_leftop(clause); left = get_leftop(restrictinfo->clause);
right = get_rightop(clause); right = get_rightop(restrictinfo->clause);
/* /*
* Check if clause is usable with these sub-rels, find inner side, * Check if clause is usable with these input rels.
* estimate bucketsize of inner var for costing purposes.
*
* Since we tend to visit the same clauses over and over when
* planning a large query, we cache the bucketsize estimates in
* the RestrictInfo node to avoid repeated lookups of statistics.
*/ */
if (intMember(left->varno, outerrelids) && if (intMember(left->varno, outerrelids) &&
intMember(right->varno, innerrelids)) intMember(right->varno, innerrelids))
{ {
/* righthand side is inner */ /* righthand side is inner */
innerbucketsize = restrictinfo->right_bucketsize;
if (innerbucketsize < 0)
{
/* not cached yet */
innerbucketsize = estimate_hash_bucketsize(root, right);
restrictinfo->right_bucketsize = innerbucketsize;
}
} }
else if (intMember(left->varno, innerrelids) && else if (intMember(left->varno, innerrelids) &&
intMember(right->varno, outerrelids)) intMember(right->varno, outerrelids))
{ {
/* lefthand side is inner */ /* lefthand side is inner */
innerbucketsize = restrictinfo->left_bucketsize;
if (innerbucketsize < 0)
{
/* not cached yet */
innerbucketsize = estimate_hash_bucketsize(root, left);
restrictinfo->left_bucketsize = innerbucketsize;
}
} }
else else
continue; /* no good for these input relations */ continue; /* no good for these input relations */
...@@ -783,22 +771,22 @@ hash_inner_and_outer(Query *root, ...@@ -783,22 +771,22 @@ hash_inner_and_outer(Query *root,
* any but the cheapest-total-cost inner path, however. * any but the cheapest-total-cost inner path, however.
*/ */
add_path(joinrel, (Path *) add_path(joinrel, (Path *)
create_hashjoin_path(joinrel, create_hashjoin_path(root,
joinrel,
jointype, jointype,
outerrel->cheapest_total_path, outerrel->cheapest_total_path,
innerrel->cheapest_total_path, innerrel->cheapest_total_path,
restrictlist, restrictlist,
hashclauses, hashclauses));
innerbucketsize));
if (outerrel->cheapest_startup_path != outerrel->cheapest_total_path) if (outerrel->cheapest_startup_path != outerrel->cheapest_total_path)
add_path(joinrel, (Path *) add_path(joinrel, (Path *)
create_hashjoin_path(joinrel, create_hashjoin_path(root,
joinrel,
jointype, jointype,
outerrel->cheapest_startup_path, outerrel->cheapest_startup_path,
innerrel->cheapest_total_path, innerrel->cheapest_total_path,
restrictlist, restrictlist,
hashclauses, hashclauses));
innerbucketsize));
} }
} }
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/tidpath.c,v 1.8 2001/01/24 19:42:58 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/optimizer/path/tidpath.c,v 1.9 2001/06/05 05:26:04 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
#include "parser/parse_coerce.h" #include "parser/parse_coerce.h"
#include "utils/lsyscache.h" #include "utils/lsyscache.h"
static void create_tidscan_joinpaths(RelOptInfo *rel); static void create_tidscan_joinpaths(Query *root, RelOptInfo *rel);
static List *TidqualFromRestrictinfo(List *relids, List *restrictinfo); static List *TidqualFromRestrictinfo(List *relids, List *restrictinfo);
static bool isEvaluable(int varno, Node *node); static bool isEvaluable(int varno, Node *node);
static Node *TidequalClause(int varno, Expr *node); static Node *TidequalClause(int varno, Expr *node);
...@@ -243,7 +243,7 @@ TidqualFromRestrictinfo(List *relids, List *restrictinfo) ...@@ -243,7 +243,7 @@ TidqualFromRestrictinfo(List *relids, List *restrictinfo)
* XXX does this actually work? * XXX does this actually work?
*/ */
static void static void
create_tidscan_joinpaths(RelOptInfo *rel) create_tidscan_joinpaths(Query *root, RelOptInfo *rel)
{ {
List *rlst = NIL, List *rlst = NIL,
*lst; *lst;
...@@ -266,7 +266,7 @@ create_tidscan_joinpaths(RelOptInfo *rel) ...@@ -266,7 +266,7 @@ create_tidscan_joinpaths(RelOptInfo *rel)
pathnode->tideval = tideval; pathnode->tideval = tideval;
pathnode->unjoined_relids = joininfo->unjoined_relids; pathnode->unjoined_relids = joininfo->unjoined_relids;
cost_tidscan(&pathnode->path, rel, tideval); cost_tidscan(&pathnode->path, root, rel, tideval);
rlst = lappend(rlst, pathnode); rlst = lappend(rlst, pathnode);
} }
...@@ -286,6 +286,6 @@ create_tidscan_paths(Query *root, RelOptInfo *rel) ...@@ -286,6 +286,6 @@ create_tidscan_paths(Query *root, RelOptInfo *rel)
rel->baserestrictinfo); rel->baserestrictinfo);
if (tideval) if (tideval)
add_path(rel, (Path *) create_tidscan_path(rel, tideval)); add_path(rel, (Path *) create_tidscan_path(root, rel, tideval));
create_tidscan_joinpaths(rel); create_tidscan_joinpaths(root, rel);
} }
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.106 2001/05/20 20:28:18 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.107 2001/06/05 05:26:04 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -47,7 +47,8 @@ static NestLoop *create_nestloop_plan(NestPath *best_path, List *tlist, ...@@ -47,7 +47,8 @@ static NestLoop *create_nestloop_plan(NestPath *best_path, List *tlist,
List *joinclauses, List *otherclauses, List *joinclauses, List *otherclauses,
Plan *outer_plan, List *outer_tlist, Plan *outer_plan, List *outer_tlist,
Plan *inner_plan, List *inner_tlist); Plan *inner_plan, List *inner_tlist);
static MergeJoin *create_mergejoin_plan(MergePath *best_path, List *tlist, static MergeJoin *create_mergejoin_plan(Query *root,
MergePath *best_path, List *tlist,
List *joinclauses, List *otherclauses, List *joinclauses, List *otherclauses,
Plan *outer_plan, List *outer_tlist, Plan *outer_plan, List *outer_tlist,
Plan *inner_plan, List *inner_tlist); Plan *inner_plan, List *inner_tlist);
...@@ -244,7 +245,8 @@ create_join_plan(Query *root, JoinPath *best_path) ...@@ -244,7 +245,8 @@ create_join_plan(Query *root, JoinPath *best_path)
switch (best_path->path.pathtype) switch (best_path->path.pathtype)
{ {
case T_MergeJoin: case T_MergeJoin:
plan = (Join *) create_mergejoin_plan((MergePath *) best_path, plan = (Join *) create_mergejoin_plan(root,
(MergePath *) best_path,
join_tlist, join_tlist,
joinclauses, joinclauses,
otherclauses, otherclauses,
...@@ -673,7 +675,8 @@ create_nestloop_plan(NestPath *best_path, ...@@ -673,7 +675,8 @@ create_nestloop_plan(NestPath *best_path,
} }
static MergeJoin * static MergeJoin *
create_mergejoin_plan(MergePath *best_path, create_mergejoin_plan(Query *root,
MergePath *best_path,
List *tlist, List *tlist,
List *joinclauses, List *joinclauses,
List *otherclauses, List *otherclauses,
...@@ -720,13 +723,15 @@ create_mergejoin_plan(MergePath *best_path, ...@@ -720,13 +723,15 @@ create_mergejoin_plan(MergePath *best_path,
*/ */
if (best_path->outersortkeys) if (best_path->outersortkeys)
outer_plan = (Plan *) outer_plan = (Plan *)
make_sort_from_pathkeys(outer_tlist, make_sort_from_pathkeys(root,
outer_tlist,
outer_plan, outer_plan,
best_path->outersortkeys); best_path->outersortkeys);
if (best_path->innersortkeys) if (best_path->innersortkeys)
inner_plan = (Plan *) inner_plan = (Plan *)
make_sort_from_pathkeys(inner_tlist, make_sort_from_pathkeys(root,
inner_tlist,
inner_plan, inner_plan,
best_path->innersortkeys); best_path->innersortkeys);
...@@ -1367,14 +1372,15 @@ make_mergejoin(List *tlist, ...@@ -1367,14 +1372,15 @@ make_mergejoin(List *tlist,
* each key number from 1 to keycount), or the executor will get confused! * each key number from 1 to keycount), or the executor will get confused!
*/ */
Sort * Sort *
make_sort(List *tlist, Plan *lefttree, int keycount) make_sort(Query *root, List *tlist, Plan *lefttree, int keycount)
{ {
Sort *node = makeNode(Sort); Sort *node = makeNode(Sort);
Plan *plan = &node->plan; Plan *plan = &node->plan;
Path sort_path; /* dummy for result of cost_sort */ Path sort_path; /* dummy for result of cost_sort */
copy_plan_costsize(plan, lefttree); /* only care about copying size */ copy_plan_costsize(plan, lefttree); /* only care about copying size */
cost_sort(&sort_path, NIL, lefttree->plan_rows, lefttree->plan_width); cost_sort(&sort_path, root, NIL,
lefttree->plan_rows, lefttree->plan_width);
plan->startup_cost = sort_path.startup_cost + lefttree->total_cost; plan->startup_cost = sort_path.startup_cost + lefttree->total_cost;
plan->total_cost = sort_path.total_cost + lefttree->total_cost; plan->total_cost = sort_path.total_cost + lefttree->total_cost;
plan->state = (EState *) NULL; plan->state = (EState *) NULL;
...@@ -1399,7 +1405,8 @@ make_sort(List *tlist, Plan *lefttree, int keycount) ...@@ -1399,7 +1405,8 @@ make_sort(List *tlist, Plan *lefttree, int keycount)
* of resdom nodes in the sort plan's target list. * of resdom nodes in the sort plan's target list.
*/ */
Sort * Sort *
make_sort_from_pathkeys(List *tlist, Plan *lefttree, List *pathkeys) make_sort_from_pathkeys(Query *root, List *tlist,
Plan *lefttree, List *pathkeys)
{ {
List *sort_tlist; List *sort_tlist;
List *i; List *i;
...@@ -1455,10 +1462,10 @@ make_sort_from_pathkeys(List *tlist, Plan *lefttree, List *pathkeys) ...@@ -1455,10 +1462,10 @@ make_sort_from_pathkeys(List *tlist, Plan *lefttree, List *pathkeys)
Assert(numsortkeys > 0); Assert(numsortkeys > 0);
return make_sort(sort_tlist, lefttree, numsortkeys); return make_sort(root, sort_tlist, lefttree, numsortkeys);
} }
Material * Material *
make_material(List *tlist, Plan *lefttree) make_material(List *tlist, Plan *lefttree)
{ {
Material *node = makeNode(Material); Material *node = makeNode(Material);
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/initsplan.c,v 1.62 2001/05/20 20:28:19 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/initsplan.c,v 1.63 2001/06/05 05:26:04 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -357,8 +357,9 @@ distribute_qual_to_rels(Query *root, Node *clause, ...@@ -357,8 +357,9 @@ distribute_qual_to_rels(Query *root, Node *clause,
bool can_be_equijoin; bool can_be_equijoin;
restrictinfo->clause = (Expr *) clause; restrictinfo->clause = (Expr *) clause;
restrictinfo->eval_cost = -1; /* not computed until needed */
restrictinfo->subclauseindices = NIL; restrictinfo->subclauseindices = NIL;
restrictinfo->eval_cost = -1; /* not computed until needed */
restrictinfo->this_selec = -1; /* not computed until needed */
restrictinfo->mergejoinoperator = InvalidOid; restrictinfo->mergejoinoperator = InvalidOid;
restrictinfo->left_sortop = InvalidOid; restrictinfo->left_sortop = InvalidOid;
restrictinfo->right_sortop = InvalidOid; restrictinfo->right_sortop = InvalidOid;
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planmain.c,v 1.65 2001/05/20 20:28:19 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planmain.c,v 1.66 2001/06/05 05:26:04 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -317,7 +317,7 @@ subplanner(Query *root, ...@@ -317,7 +317,7 @@ subplanner(Query *root,
{ {
Path sort_path; /* dummy for result of cost_sort */ Path sort_path; /* dummy for result of cost_sort */
cost_sort(&sort_path, root->query_pathkeys, cost_sort(&sort_path, root, root->query_pathkeys,
final_rel->rows, final_rel->width); final_rel->rows, final_rel->width);
sort_path.startup_cost += cheapestpath->total_cost; sort_path.startup_cost += cheapestpath->total_cost;
sort_path.total_cost += cheapestpath->total_cost; sort_path.total_cost += cheapestpath->total_cost;
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planner.c,v 1.107 2001/05/20 20:28:19 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planner.c,v 1.108 2001/06/05 05:26:04 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -48,7 +48,8 @@ static Plan *inheritance_planner(Query *parse, List *inheritlist); ...@@ -48,7 +48,8 @@ static Plan *inheritance_planner(Query *parse, List *inheritlist);
static Plan *grouping_planner(Query *parse, double tuple_fraction); static Plan *grouping_planner(Query *parse, double tuple_fraction);
static List *make_subplanTargetList(Query *parse, List *tlist, static List *make_subplanTargetList(Query *parse, List *tlist,
AttrNumber **groupColIdx); AttrNumber **groupColIdx);
static Plan *make_groupplan(List *group_tlist, bool tuplePerGroup, static Plan *make_groupplan(Query *parse,
List *group_tlist, bool tuplePerGroup,
List *groupClause, AttrNumber *grpColIdx, List *groupClause, AttrNumber *grpColIdx,
bool is_presorted, Plan *subplan); bool is_presorted, Plan *subplan);
static List *postprocess_setop_tlist(List *new_tlist, List *orig_tlist); static List *postprocess_setop_tlist(List *new_tlist, List *orig_tlist);
...@@ -1153,7 +1154,8 @@ grouping_planner(Query *parse, double tuple_fraction) ...@@ -1153,7 +1154,8 @@ grouping_planner(Query *parse, double tuple_fraction)
current_pathkeys = group_pathkeys; current_pathkeys = group_pathkeys;
} }
result_plan = make_groupplan(group_tlist, result_plan = make_groupplan(parse,
group_tlist,
tuplePerGroup, tuplePerGroup,
parse->groupClause, parse->groupClause,
groupColIdx, groupColIdx,
...@@ -1186,7 +1188,7 @@ grouping_planner(Query *parse, double tuple_fraction) ...@@ -1186,7 +1188,7 @@ grouping_planner(Query *parse, double tuple_fraction)
if (parse->sortClause) if (parse->sortClause)
{ {
if (!pathkeys_contained_in(sort_pathkeys, current_pathkeys)) if (!pathkeys_contained_in(sort_pathkeys, current_pathkeys))
result_plan = make_sortplan(tlist, result_plan, result_plan = make_sortplan(parse, tlist, result_plan,
parse->sortClause); parse->sortClause);
} }
...@@ -1329,7 +1331,8 @@ make_subplanTargetList(Query *parse, ...@@ -1329,7 +1331,8 @@ make_subplanTargetList(Query *parse,
* first add an explicit Sort node. * first add an explicit Sort node.
*/ */
static Plan * static Plan *
make_groupplan(List *group_tlist, make_groupplan(Query *parse,
List *group_tlist,
bool tuplePerGroup, bool tuplePerGroup,
List *groupClause, List *groupClause,
AttrNumber *grpColIdx, AttrNumber *grpColIdx,
...@@ -1374,7 +1377,7 @@ make_groupplan(List *group_tlist, ...@@ -1374,7 +1377,7 @@ make_groupplan(List *group_tlist,
Assert(keyno > 0); Assert(keyno > 0);
subplan = (Plan *) make_sort(sort_tlist, subplan, keyno); subplan = (Plan *) make_sort(parse, sort_tlist, subplan, keyno);
} }
return (Plan *) make_group(group_tlist, tuplePerGroup, numCols, return (Plan *) make_group(group_tlist, tuplePerGroup, numCols,
...@@ -1386,7 +1389,7 @@ make_groupplan(List *group_tlist, ...@@ -1386,7 +1389,7 @@ make_groupplan(List *group_tlist,
* Add a Sort node to implement an explicit ORDER BY clause. * Add a Sort node to implement an explicit ORDER BY clause.
*/ */
Plan * Plan *
make_sortplan(List *tlist, Plan *plannode, List *sortcls) make_sortplan(Query *parse, List *tlist, Plan *plannode, List *sortcls)
{ {
List *sort_tlist; List *sort_tlist;
List *i; List *i;
...@@ -1419,7 +1422,7 @@ make_sortplan(List *tlist, Plan *plannode, List *sortcls) ...@@ -1419,7 +1422,7 @@ make_sortplan(List *tlist, Plan *plannode, List *sortcls)
Assert(keyno > 0); Assert(keyno > 0);
return (Plan *) make_sort(sort_tlist, plannode, keyno); return (Plan *) make_sort(parse, sort_tlist, plannode, keyno);
} }
/* /*
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/prep/prepunion.c,v 1.64 2001/05/20 20:28:19 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/optimizer/prep/prepunion.c,v 1.65 2001/06/05 05:26:04 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -242,7 +242,7 @@ generate_union_plan(SetOperationStmt *op, Query *parse, ...@@ -242,7 +242,7 @@ generate_union_plan(SetOperationStmt *op, Query *parse,
tlist = new_unsorted_tlist(plan->targetlist); tlist = new_unsorted_tlist(plan->targetlist);
sortList = addAllTargetsToSortList(NIL, tlist); sortList = addAllTargetsToSortList(NIL, tlist);
plan = make_sortplan(tlist, plan, sortList); plan = make_sortplan(parse, tlist, plan, sortList);
plan = (Plan *) make_unique(tlist, plan, copyObject(sortList)); plan = (Plan *) make_unique(tlist, plan, copyObject(sortList));
} }
return plan; return plan;
...@@ -290,7 +290,7 @@ generate_nonunion_plan(SetOperationStmt *op, Query *parse, ...@@ -290,7 +290,7 @@ generate_nonunion_plan(SetOperationStmt *op, Query *parse,
*/ */
tlist = new_unsorted_tlist(plan->targetlist); tlist = new_unsorted_tlist(plan->targetlist);
sortList = addAllTargetsToSortList(NIL, tlist); sortList = addAllTargetsToSortList(NIL, tlist);
plan = make_sortplan(tlist, plan, sortList); plan = make_sortplan(parse, tlist, plan, sortList);
switch (op->op) switch (op->op)
{ {
case SETOP_INTERSECT: case SETOP_INTERSECT:
...@@ -688,7 +688,8 @@ adjust_inherited_attrs_mutator(Node *node, ...@@ -688,7 +688,8 @@ adjust_inherited_attrs_mutator(Node *node,
adjust_inherited_attrs_mutator((Node *) oldinfo->clause, context); adjust_inherited_attrs_mutator((Node *) oldinfo->clause, context);
newinfo->subclauseindices = NIL; newinfo->subclauseindices = NIL;
newinfo->eval_cost = -1; /* reset this too */ newinfo->eval_cost = -1; /* reset these too */
newinfo->this_selec = -1;
newinfo->left_pathkey = NIL; /* and these */ newinfo->left_pathkey = NIL; /* and these */
newinfo->right_pathkey = NIL; newinfo->right_pathkey = NIL;
newinfo->left_bucketsize = -1; newinfo->left_bucketsize = -1;
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/util/pathnode.c,v 1.73 2001/05/20 20:28:19 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/optimizer/util/pathnode.c,v 1.74 2001/06/05 05:26:04 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -297,7 +297,7 @@ add_path(RelOptInfo *parent_rel, Path *new_path) ...@@ -297,7 +297,7 @@ add_path(RelOptInfo *parent_rel, Path *new_path)
* pathnode. * pathnode.
*/ */
Path * Path *
create_seqscan_path(RelOptInfo *rel) create_seqscan_path(Query *root, RelOptInfo *rel)
{ {
Path *pathnode = makeNode(Path); Path *pathnode = makeNode(Path);
...@@ -305,7 +305,7 @@ create_seqscan_path(RelOptInfo *rel) ...@@ -305,7 +305,7 @@ create_seqscan_path(RelOptInfo *rel)
pathnode->parent = rel; pathnode->parent = rel;
pathnode->pathkeys = NIL; /* seqscan has unordered result */ pathnode->pathkeys = NIL; /* seqscan has unordered result */
cost_seqscan(pathnode, rel); cost_seqscan(pathnode, root, rel);
return pathnode; return pathnode;
} }
...@@ -371,10 +371,9 @@ create_index_path(Query *root, ...@@ -371,10 +371,9 @@ create_index_path(Query *root,
* create_tidscan_path * create_tidscan_path
* Creates a path corresponding to a tid_direct scan, returning the * Creates a path corresponding to a tid_direct scan, returning the
* pathnode. * pathnode.
*
*/ */
TidPath * TidPath *
create_tidscan_path(RelOptInfo *rel, List *tideval) create_tidscan_path(Query *root, RelOptInfo *rel, List *tideval)
{ {
TidPath *pathnode = makeNode(TidPath); TidPath *pathnode = makeNode(TidPath);
...@@ -385,7 +384,7 @@ create_tidscan_path(RelOptInfo *rel, List *tideval) ...@@ -385,7 +384,7 @@ create_tidscan_path(RelOptInfo *rel, List *tideval)
* necessary? */ * necessary? */
pathnode->unjoined_relids = NIL; pathnode->unjoined_relids = NIL;
cost_tidscan(&pathnode->path, rel, tideval); cost_tidscan(&pathnode->path, root, rel, tideval);
/* /*
* divide selectivity for each clause to get an equal selectivity as * divide selectivity for each clause to get an equal selectivity as
...@@ -461,10 +460,10 @@ create_subqueryscan_path(RelOptInfo *rel) ...@@ -461,10 +460,10 @@ create_subqueryscan_path(RelOptInfo *rel)
* 'pathkeys' are the path keys of the new join path * 'pathkeys' are the path keys of the new join path
* *
* Returns the resulting path node. * Returns the resulting path node.
*
*/ */
NestPath * NestPath *
create_nestloop_path(RelOptInfo *joinrel, create_nestloop_path(Query *root,
RelOptInfo *joinrel,
JoinType jointype, JoinType jointype,
Path *outer_path, Path *outer_path,
Path *inner_path, Path *inner_path,
...@@ -481,7 +480,8 @@ create_nestloop_path(RelOptInfo *joinrel, ...@@ -481,7 +480,8 @@ create_nestloop_path(RelOptInfo *joinrel,
pathnode->joinrestrictinfo = restrict_clauses; pathnode->joinrestrictinfo = restrict_clauses;
pathnode->path.pathkeys = pathkeys; pathnode->path.pathkeys = pathkeys;
cost_nestloop(&pathnode->path, outer_path, inner_path, restrict_clauses); cost_nestloop(&pathnode->path, root, outer_path, inner_path,
restrict_clauses);
return pathnode; return pathnode;
} }
...@@ -501,10 +501,10 @@ create_nestloop_path(RelOptInfo *joinrel, ...@@ -501,10 +501,10 @@ create_nestloop_path(RelOptInfo *joinrel,
* (this should be a subset of the restrict_clauses list) * (this should be a subset of the restrict_clauses list)
* 'outersortkeys' are the sort varkeys for the outer relation * 'outersortkeys' are the sort varkeys for the outer relation
* 'innersortkeys' are the sort varkeys for the inner relation * 'innersortkeys' are the sort varkeys for the inner relation
*
*/ */
MergePath * MergePath *
create_mergejoin_path(RelOptInfo *joinrel, create_mergejoin_path(Query *root,
RelOptInfo *joinrel,
JoinType jointype, JoinType jointype,
Path *outer_path, Path *outer_path,
Path *inner_path, Path *inner_path,
...@@ -539,9 +539,11 @@ create_mergejoin_path(RelOptInfo *joinrel, ...@@ -539,9 +539,11 @@ create_mergejoin_path(RelOptInfo *joinrel,
pathnode->innersortkeys = innersortkeys; pathnode->innersortkeys = innersortkeys;
cost_mergejoin(&pathnode->jpath.path, cost_mergejoin(&pathnode->jpath.path,
root,
outer_path, outer_path,
inner_path, inner_path,
restrict_clauses, restrict_clauses,
mergeclauses,
outersortkeys, outersortkeys,
innersortkeys); innersortkeys);
...@@ -559,17 +561,15 @@ create_mergejoin_path(RelOptInfo *joinrel, ...@@ -559,17 +561,15 @@ create_mergejoin_path(RelOptInfo *joinrel,
* 'restrict_clauses' are the RestrictInfo nodes to apply at the join * 'restrict_clauses' are the RestrictInfo nodes to apply at the join
* 'hashclauses' is a list of the hash join clause (always a 1-element list) * 'hashclauses' is a list of the hash join clause (always a 1-element list)
* (this should be a subset of the restrict_clauses list) * (this should be a subset of the restrict_clauses list)
* 'innerbucketsize' is an estimate of the bucketsize of the inner hash key
*
*/ */
HashPath * HashPath *
create_hashjoin_path(RelOptInfo *joinrel, create_hashjoin_path(Query *root,
RelOptInfo *joinrel,
JoinType jointype, JoinType jointype,
Path *outer_path, Path *outer_path,
Path *inner_path, Path *inner_path,
List *restrict_clauses, List *restrict_clauses,
List *hashclauses, List *hashclauses)
Selectivity innerbucketsize)
{ {
HashPath *pathnode = makeNode(HashPath); HashPath *pathnode = makeNode(HashPath);
...@@ -584,10 +584,11 @@ create_hashjoin_path(RelOptInfo *joinrel, ...@@ -584,10 +584,11 @@ create_hashjoin_path(RelOptInfo *joinrel,
pathnode->path_hashclauses = hashclauses; pathnode->path_hashclauses = hashclauses;
cost_hashjoin(&pathnode->jpath.path, cost_hashjoin(&pathnode->jpath.path,
root,
outer_path, outer_path,
inner_path, inner_path,
restrict_clauses, restrict_clauses,
innerbucketsize); hashclauses);
return pathnode; return pathnode;
} }
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/adt/selfuncs.c,v 1.91 2001/05/27 17:37:48 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/utils/adt/selfuncs.c,v 1.92 2001/06/05 05:26:04 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -1132,10 +1132,12 @@ eqjoinsel(PG_FUNCTION_ARGS) ...@@ -1132,10 +1132,12 @@ eqjoinsel(PG_FUNCTION_ARGS)
totalsel2 += otherfreq2 * (otherfreq1 + unmatchfreq1) / totalsel2 += otherfreq2 * (otherfreq1 + unmatchfreq1) /
(nd1 - nmatches); (nd1 - nmatches);
/* /*
* For robustness, we average the two estimates. (Can a case * Use the smaller of the two estimates. This can be justified
* be made for taking the min or max instead?) * in essentially the same terms as given below for the no-stats
* case: to a first approximation, we are estimating from the
* point of view of the relation with smaller nd.
*/ */
selec = (totalsel1 + totalsel2) * 0.5; selec = (totalsel1 < totalsel2) ? totalsel1 : totalsel2;
} }
else else
{ {
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: relation.h,v 1.56 2001/05/20 20:28:20 tgl Exp $ * $Id: relation.h,v 1.57 2001/06/05 05:26:05 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -492,7 +492,7 @@ typedef struct HashPath ...@@ -492,7 +492,7 @@ typedef struct HashPath
* path is responsible for identifying the restrict clauses it can use * path is responsible for identifying the restrict clauses it can use
* and ignoring the rest. Clauses not implemented by an indexscan, * and ignoring the rest. Clauses not implemented by an indexscan,
* mergejoin, or hashjoin will be placed in the plan qual or joinqual field * mergejoin, or hashjoin will be placed in the plan qual or joinqual field
* of the final Plan node, where they will be enforced by general-purpose * of the finished Plan node, where they will be enforced by general-purpose
* qual-expression-evaluation code. (But we are still entitled to count * qual-expression-evaluation code. (But we are still entitled to count
* their selectivity when estimating the result tuple count, if we * their selectivity when estimating the result tuple count, if we
* can guess what it is...) * can guess what it is...)
...@@ -504,14 +504,16 @@ typedef struct RestrictInfo ...@@ -504,14 +504,16 @@ typedef struct RestrictInfo
Expr *clause; /* the represented clause of WHERE or JOIN */ Expr *clause; /* the represented clause of WHERE or JOIN */
Cost eval_cost; /* eval cost of clause; -1 if not yet set */
bool ispusheddown; /* TRUE if clause was pushed down in level */ bool ispusheddown; /* TRUE if clause was pushed down in level */
/* only used if clause is an OR clause: */ /* only used if clause is an OR clause: */
List *subclauseindices; /* indexes matching subclauses */ List *subclauseindices; /* indexes matching subclauses */
/* subclauseindices is a List of Lists of IndexOptInfos */ /* subclauseindices is a List of Lists of IndexOptInfos */
/* cache space for costs (currently only used for join clauses) */
Cost eval_cost; /* eval cost of clause; -1 if not yet set */
Selectivity this_selec; /* selectivity; -1 if not yet set */
/* valid if clause is mergejoinable, else InvalidOid: */ /* valid if clause is mergejoinable, else InvalidOid: */
Oid mergejoinoperator; /* copy of clause operator */ Oid mergejoinoperator; /* copy of clause operator */
Oid left_sortop; /* leftside sortop needed for mergejoin */ Oid left_sortop; /* leftside sortop needed for mergejoin */
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: cost.h,v 1.39 2001/05/07 00:43:26 tgl Exp $ * $Id: cost.h,v 1.40 2001/06/05 05:26:05 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -52,20 +52,27 @@ extern bool enable_nestloop; ...@@ -52,20 +52,27 @@ extern bool enable_nestloop;
extern bool enable_mergejoin; extern bool enable_mergejoin;
extern bool enable_hashjoin; extern bool enable_hashjoin;
extern void cost_seqscan(Path *path, RelOptInfo *baserel); extern void cost_seqscan(Path *path, Query *root,
RelOptInfo *baserel);
extern void cost_index(Path *path, Query *root, extern void cost_index(Path *path, Query *root,
RelOptInfo *baserel, IndexOptInfo *index, RelOptInfo *baserel, IndexOptInfo *index,
List *indexQuals, bool is_injoin); List *indexQuals, bool is_injoin);
extern void cost_tidscan(Path *path, RelOptInfo *baserel, List *tideval); extern void cost_tidscan(Path *path, Query *root,
extern void cost_sort(Path *path, List *pathkeys, double tuples, int width); RelOptInfo *baserel, List *tideval);
extern void cost_nestloop(Path *path, Path *outer_path, Path *inner_path, extern void cost_sort(Path *path, Query *root,
List *restrictlist); List *pathkeys, double tuples, int width);
extern void cost_mergejoin(Path *path, Path *outer_path, Path *inner_path, extern void cost_nestloop(Path *path, Query *root,
List *restrictlist, Path *outer_path, Path *inner_path,
List *outersortkeys, List *innersortkeys); List *restrictlist);
extern void cost_hashjoin(Path *path, Path *outer_path, Path *inner_path, extern void cost_mergejoin(Path *path, Query *root,
List *restrictlist, Selectivity innerbucketsize); Path *outer_path, Path *inner_path,
extern Selectivity estimate_hash_bucketsize(Query *root, Var *var); List *restrictlist,
List *mergeclauses,
List *outersortkeys, List *innersortkeys);
extern void cost_hashjoin(Path *path, Query *root,
Path *outer_path, Path *inner_path,
List *restrictlist,
List *hashclauses);
extern Cost cost_qual_eval(List *quals); extern Cost cost_qual_eval(List *quals);
extern void set_baserel_size_estimates(Query *root, RelOptInfo *rel); extern void set_baserel_size_estimates(Query *root, RelOptInfo *rel);
extern void set_joinrel_size_estimates(Query *root, RelOptInfo *rel, extern void set_joinrel_size_estimates(Query *root, RelOptInfo *rel,
...@@ -84,5 +91,8 @@ extern Selectivity restrictlist_selectivity(Query *root, ...@@ -84,5 +91,8 @@ extern Selectivity restrictlist_selectivity(Query *root,
extern Selectivity clauselist_selectivity(Query *root, extern Selectivity clauselist_selectivity(Query *root,
List *clauses, List *clauses,
int varRelid); int varRelid);
extern Selectivity clause_selectivity(Query *root,
Node *clause,
int varRelid);
#endif /* COST_H */ #endif /* COST_H */
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: pathnode.h,v 1.37 2001/05/20 20:28:20 tgl Exp $ * $Id: pathnode.h,v 1.38 2001/06/05 05:26:05 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -26,40 +26,43 @@ extern int compare_fractional_path_costs(Path *path1, Path *path2, ...@@ -26,40 +26,43 @@ extern int compare_fractional_path_costs(Path *path1, Path *path2,
extern void set_cheapest(RelOptInfo *parent_rel); extern void set_cheapest(RelOptInfo *parent_rel);
extern void add_path(RelOptInfo *parent_rel, Path *new_path); extern void add_path(RelOptInfo *parent_rel, Path *new_path);
extern Path *create_seqscan_path(RelOptInfo *rel); extern Path *create_seqscan_path(Query *root, RelOptInfo *rel);
extern IndexPath *create_index_path(Query *root, RelOptInfo *rel, extern IndexPath *create_index_path(Query *root, RelOptInfo *rel,
IndexOptInfo *index, IndexOptInfo *index,
List *restriction_clauses, List *restriction_clauses,
List *pathkeys, List *pathkeys,
ScanDirection indexscandir); ScanDirection indexscandir);
extern TidPath *create_tidscan_path(RelOptInfo *rel, List *tideval); extern TidPath *create_tidscan_path(Query *root, RelOptInfo *rel,
List *tideval);
extern AppendPath *create_append_path(RelOptInfo *rel, List *subpaths); extern AppendPath *create_append_path(RelOptInfo *rel, List *subpaths);
extern Path *create_subqueryscan_path(RelOptInfo *rel); extern Path *create_subqueryscan_path(RelOptInfo *rel);
extern NestPath *create_nestloop_path(RelOptInfo *joinrel, extern NestPath *create_nestloop_path(Query *root,
JoinType jointype, RelOptInfo *joinrel,
Path *outer_path, JoinType jointype,
Path *inner_path, Path *outer_path,
List *restrict_clauses, Path *inner_path,
List *pathkeys); List *restrict_clauses,
List *pathkeys);
extern MergePath *create_mergejoin_path(RelOptInfo *joinrel, extern MergePath *create_mergejoin_path(Query *root,
JoinType jointype, RelOptInfo *joinrel,
Path *outer_path, JoinType jointype,
Path *inner_path, Path *outer_path,
List *restrict_clauses, Path *inner_path,
List *pathkeys, List *restrict_clauses,
List *mergeclauses, List *pathkeys,
List *outersortkeys, List *mergeclauses,
List *innersortkeys); List *outersortkeys,
List *innersortkeys);
extern HashPath *create_hashjoin_path(RelOptInfo *joinrel, extern HashPath *create_hashjoin_path(Query *root,
JoinType jointype, RelOptInfo *joinrel,
Path *outer_path, JoinType jointype,
Path *inner_path, Path *outer_path,
List *restrict_clauses, Path *inner_path,
List *hashclauses, List *restrict_clauses,
Selectivity innerbucketsize); List *hashclauses);
/* /*
* prototypes for relnode.c * prototypes for relnode.c
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: planmain.h,v 1.50 2001/03/22 04:00:55 momjian Exp $ * $Id: planmain.h,v 1.51 2001/06/05 05:26:05 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -29,9 +29,10 @@ extern Plan *create_plan(Query *root, Path *best_path); ...@@ -29,9 +29,10 @@ extern Plan *create_plan(Query *root, Path *best_path);
extern SubqueryScan *make_subqueryscan(List *qptlist, List *qpqual, extern SubqueryScan *make_subqueryscan(List *qptlist, List *qpqual,
Index scanrelid, Plan *subplan); Index scanrelid, Plan *subplan);
extern Append *make_append(List *appendplans, bool isTarget, List *tlist); extern Append *make_append(List *appendplans, bool isTarget, List *tlist);
extern Sort *make_sort(List *tlist, Plan *lefttree, int keycount); extern Sort *make_sort(Query *root, List *tlist,
extern Sort *make_sort_from_pathkeys(List *tlist, Plan *lefttree, Plan *lefttree, int keycount);
List *pathkeys); extern Sort *make_sort_from_pathkeys(Query *root, List *tlist,
Plan *lefttree, List *pathkeys);
extern Agg *make_agg(List *tlist, List *qual, Plan *lefttree); extern Agg *make_agg(List *tlist, List *qual, Plan *lefttree);
extern Group *make_group(List *tlist, bool tuplePerGroup, int ngrp, extern Group *make_group(List *tlist, bool tuplePerGroup, int ngrp,
AttrNumber *grpColIdx, Plan *lefttree); AttrNumber *grpColIdx, Plan *lefttree);
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: planner.h,v 1.19 2001/01/24 19:43:26 momjian Exp $ * $Id: planner.h,v 1.20 2001/06/05 05:26:05 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
extern Plan *planner(Query *parse); extern Plan *planner(Query *parse);
extern Plan *subquery_planner(Query *parse, double tuple_fraction); extern Plan *subquery_planner(Query *parse, double tuple_fraction);
extern Plan *make_sortplan(List *tlist, Plan *plannode, List *sortcls); extern Plan *make_sortplan(Query *parse, List *tlist,
Plan *plannode, List *sortcls);
#endif /* PLANNER_H */ #endif /* PLANNER_H */
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