1
0
mirror of https://github.com/postgres/postgres.git synced 2025-11-15 03:41:20 +03:00

Remove duplicate geqo functions, and more optimizer cleanup

This commit is contained in:
Bruce Momjian
1999-02-15 03:22:37 +00:00
parent 944d3c395e
commit ba2883b264
26 changed files with 188 additions and 810 deletions

View File

@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/allpaths.c,v 1.34 1999/02/14 05:27:11 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/allpaths.c,v 1.35 1999/02/15 03:22:03 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -44,7 +44,7 @@ int32 _use_geqo_rels_ = GEQO_RELS;
static void find_base_rel_paths(Query *root, List *rels);
static List *find_join_paths(Query *root, List *outer_rels, int levels_needed);
static RelOptInfo *make_one_rel_by_joins(Query *root, List *outer_rels, int levels_needed);
#ifdef OPTIMIZER_DEBUG
static void debug_print_rel(Query *root, RelOptInfo *rel);
@@ -52,14 +52,14 @@ static void debug_print_rel(Query *root, RelOptInfo *rel);
#endif
/*
* find_paths
* Finds all possible access paths for executing a query, returning the
* top level list of relation entries.
* make_one_rel
* Finds all possible access paths for executing a query, returning a
* single rel.
*
* 'rels' is the list of single relation entries appearing in the query
*/
List *
find_paths(Query *root, List *rels)
RelOptInfo *
make_one_rel(Query *root, List *rels)
{
int levels_needed;
@@ -69,7 +69,7 @@ find_paths(Query *root, List *rels)
levels_needed = length(rels);
if (levels_needed <= 0)
return NIL;
return NULL;
find_base_rel_paths(root, rels);
@@ -78,7 +78,7 @@ find_paths(Query *root, List *rels)
/*
* Unsorted single relation, no more processing is required.
*/
return rels;
return lfirst(rels);
}
else
{
@@ -88,7 +88,7 @@ find_paths(Query *root, List *rels)
*/
set_rest_relselec(root, rels);
return find_join_paths(root, rels, levels_needed);
return make_one_rel_by_joins(root, rels, levels_needed);
}
}
@@ -142,7 +142,7 @@ find_base_rel_paths(Query *root, List *rels)
}
/*
* find_join_paths
* make_one_rel_by_joins
* Find all possible joinpaths for a query by successively finding ways
* to join single relations into join relations.
*
@@ -158,8 +158,8 @@ find_base_rel_paths(Query *root, List *rels)
* Returns the final level of join relations, i.e., the relation that is
* the result of joining all the original relations together.
*/
static List *
find_join_paths(Query *root, List *outer_rels, int levels_needed)
static RelOptInfo *
make_one_rel_by_joins(Query *root, List *outer_rels, int levels_needed)
{
List *x;
List *joined_rels = NIL;
@@ -170,7 +170,7 @@ find_join_paths(Query *root, List *outer_rels, int levels_needed)
* <utesch@aut.tu-freiberg.de> *
*******************************************/
if ((_use_geqo_) && length(root->base_rel_list) >= _use_geqo_rels_)
return lcons(geqo(root), NIL); /* returns *one* Rel, so lcons it */
return geqo(root);
/*******************************************
* rest will be deprecated in case of GEQO *
@@ -184,7 +184,7 @@ find_join_paths(Query *root, List *outer_rels, int levels_needed)
* modify 'joined_rels' accordingly, then eliminate redundant join
* relations.
*/
joined_rels = make_new_rels_by_joins(root, outer_rels);
joined_rels = make_rels_by_joins(root, outer_rels);
update_rels_pathlist_for_joins(root, joined_rels);
@@ -202,9 +202,9 @@ find_join_paths(Query *root, List *outer_rels, int levels_needed)
rels_set_cheapest(joined_rels);
#ifdef NOT_USED
if (BushyPlanFlag)
{
/*
* In case of bushy trees if there is still a join between a
* join relation and another relation, add a new joininfo that
@@ -213,6 +213,7 @@ find_join_paths(Query *root, List *outer_rels, int levels_needed)
*/
add_new_joininfos(root, joined_rels, outer_rels);
}
#endif
foreach(x, joined_rels)
{
@@ -228,6 +229,7 @@ find_join_paths(Query *root, List *outer_rels, int levels_needed)
#endif
}
#ifdef NOT_USED
if (BushyPlanFlag)
{
/*
@@ -243,16 +245,24 @@ find_join_paths(Query *root, List *outer_rels, int levels_needed)
root->join_rel_list = outer_rels;
}
else
root->join_rel_list = joined_rels;
#endif
root->join_rel_list = joined_rels;
#ifdef NOT_USED
if (!BushyPlanFlag)
outer_rels = joined_rels;
#endif
outer_rels = joined_rels;
}
Assert(length(joined_rels) == 1);
#ifdef NOT_USED
if (BushyPlanFlag)
return final_join_rels(outer_rels);
else
return joined_rels;
#endif
return lfirst(joined_rels);
}
/*****************************************************************************

View File

@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/costsize.c,v 1.32 1999/02/13 23:16:16 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/costsize.c,v 1.33 1999/02/15 03:22:04 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -440,21 +440,19 @@ compute_joinrel_size(JoinPath *joinpath)
Cost temp = 1.0;
int temp1 = 0;
/* cartesian product */
temp *= ((Path *) joinpath->outerjoinpath)->parent->size;
temp *= ((Path *) joinpath->innerjoinpath)->parent->size;
temp = temp * product_selec(joinpath->pathinfo);
if (temp >= (MAXINT - 1))
temp1 = MAXINT;
else
if (temp >= (MAXINT-1)/2)
{
/*
* should be ceil here, we don't want joinrel size's of one, do
* we?
*/
temp1 = ceil((double) temp);
/* if we exceed (MAXINT-1)/2, we switch to log scale */
/* +1 prevents log(0) */
temp1 = ceil(log(temp + 1 - (MAXINT-1)/2) + (MAXINT-1)/2);
}
else
temp1 = ceil((double) temp);
Assert(temp1 >= 0);
return temp1;

View File

@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/indxpath.c,v 1.46 1999/02/15 02:04:55 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/indxpath.c,v 1.47 1999/02/15 03:22:05 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -1302,13 +1302,13 @@ index_innerjoin(Query *root, RelOptInfo *rel, List *clausegroup_list,
pathnode->path.joinid = ((RestrictInfo *) lfirst(clausegroup))->restrictinfojoinid;
pathnode->path.path_cost = cost_index((Oid) lfirsti(index->relids),
(int) temp_pages,
temp_selec,
rel->pages,
rel->tuples,
index->pages,
index->tuples,
true);
(int) temp_pages,
temp_selec,
rel->pages,
rel->tuples,
index->pages,
index->tuples,
true);
/*
* copy restrictinfo list into path for expensive function

View File

@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/joinpath.c,v 1.26 1999/02/15 02:04:57 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/joinpath.c,v 1.27 1999/02/15 03:22:05 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -78,6 +78,7 @@ update_rels_pathlist_for_joins(Query *root, List *joinrels)
Path *bestinnerjoin;
List *pathlist = NIL;
/* flatten out relids later in this function */
innerrelids = lsecond(joinrel->relids);
outerrelids = lfirst(joinrel->relids);

View File

@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/joinrels.c,v 1.22 1999/02/15 02:04:57 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/joinrels.c,v 1.23 1999/02/15 03:22:05 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -31,20 +31,15 @@ bool _use_right_sided_plans_ = false;
#endif
static List *find_clause_joins(Query *root, RelOptInfo *outer_rel, List *joininfo_list);
static List *find_clauseless_joins(RelOptInfo *outer_rel, List *inner_rels);
static RelOptInfo *init_join_rel(RelOptInfo *outer_rel, RelOptInfo *inner_rel, JoinInfo * joininfo);
static List *new_join_tlist(List *tlist, List *other_relids,
int first_resdomno);
static List *new_joininfo_list(List *joininfo_list, List *join_relids);
static void add_superrels(RelOptInfo *rel, RelOptInfo *super_rel);
static bool nonoverlap_rels(RelOptInfo *rel1, RelOptInfo *rel2);
static bool nonoverlap_sets(List *s1, List *s2);
static void set_joinrel_size(RelOptInfo *joinrel, RelOptInfo *outer_rel, RelOptInfo *inner_rel,
JoinInfo * jinfo);
JoinInfo *jinfo);
/*
* make_new_rels_by_joins
* make_rels_by_joins
* Find all possible joins for each of the outer join relations in
* 'outer_rels'. A rel node is created for each possible join relation,
* and the resulting list of nodes is returned. If at all possible, only
@@ -57,7 +52,7 @@ static void set_joinrel_size(RelOptInfo *joinrel, RelOptInfo *outer_rel, RelOptI
* Returns a list of rel nodes corresponding to the new join relations.
*/
List *
make_new_rels_by_joins(Query *root, List *outer_rels)
make_rels_by_joins(Query *root, List *outer_rels)
{
List *joins = NIL;
List *join_list = NIL;
@@ -67,16 +62,20 @@ make_new_rels_by_joins(Query *root, List *outer_rels)
{
RelOptInfo *outer_rel = (RelOptInfo *) lfirst(r);
if (!(joins = find_clause_joins(root, outer_rel, outer_rel->joininfo)))
if (!(joins = make_rels_by_clause_joins(root, outer_rel,
outer_rel->joininfo,
NIL)))
{
/*
* Oops, we have a relation that is not joined to any other
* relation. Cartesian product time.
*/
#ifdef NOT_USED
if (BushyPlanFlag)
joins = find_clauseless_joins(outer_rel, outer_rels);
joins = make_rels_by_clauseless_joins(outer_rel, outer_rels);
else
joins = find_clauseless_joins(outer_rel, root->base_rel_list);
#endif
joins = make_rels_by_clauseless_joins(outer_rel, root->base_rel_list);
}
join_list = nconc(join_list, joins);
@@ -86,7 +85,7 @@ make_new_rels_by_joins(Query *root, List *outer_rels)
}
/*
* find_clause_joins
* make_rels_by_clause_joins
* Determines whether joins can be performed between an outer relation
* 'outer_rel' and those relations within 'outer_rel's joininfo nodes
* (i.e., relations that participate in join clauses that 'outer_rel'
@@ -100,8 +99,9 @@ make_new_rels_by_joins(Query *root, List *outer_rels)
*
* Returns a list of new join relations.
*/
static List *
find_clause_joins(Query *root, RelOptInfo *outer_rel, List *joininfo_list)
List *
make_rels_by_clause_joins(Query *root, RelOptInfo *outer_rel,
List *joininfo_list, List *only_relids)
{
List *join_list = NIL;
List *i = NIL;
@@ -111,15 +111,18 @@ find_clause_joins(Query *root, RelOptInfo *outer_rel, List *joininfo_list)
JoinInfo *joininfo = (JoinInfo *) lfirst(i);
RelOptInfo *rel;
if (!joininfo->inactive)
if (!joininfo->bushy_inactive)
{
List *other_rels = joininfo->otherrels;
if (other_rels != NIL)
{
if (length(other_rels) == 1)
if (length(other_rels) == 1 &&
(only_relids == NIL ||
/* geqo only wants certain relids to make new rels */
same(joininfo->otherrels, only_relids)))
{
rel = init_join_rel(outer_rel,
rel = make_join_rel(outer_rel,
get_base_rel(root, lfirsti(other_rels)),
joininfo);
/* how about right-sided plan ? */
@@ -128,18 +131,20 @@ find_clause_joins(Query *root, RelOptInfo *outer_rel, List *joininfo_list)
{
if (rel != NULL)
join_list = lappend(join_list, rel);
rel = init_join_rel(get_base_rel(root,
rel = make_join_rel(get_base_rel(root,
lfirsti(other_rels)),
outer_rel,
joininfo);
}
}
#ifdef NOT_USED
else if (BushyPlanFlag)
{
rel = init_join_rel(outer_rel,
rel = make_join_rel(outer_rel,
get_join_rel(root, other_rels),
joininfo);
}
#endif
else
rel = NULL;
@@ -153,15 +158,15 @@ find_clause_joins(Query *root, RelOptInfo *outer_rel, List *joininfo_list)
}
/*
* find_clauseless_joins
* make_rels_by_clauseless_joins
* Given an outer relation 'outer_rel' and a list of inner relations
* 'inner_rels', create a join relation between 'outer_rel' and each
* member of 'inner_rels' that isn't already included in 'outer_rel'.
*
* Returns a list of new join relations.
*/
static List *
find_clauseless_joins(RelOptInfo *outer_rel, List *inner_rels)
List *
make_rels_by_clauseless_joins(RelOptInfo *outer_rel, List *inner_rels)
{
RelOptInfo *inner_rel;
List *t_list = NIL;
@@ -173,7 +178,7 @@ find_clauseless_joins(RelOptInfo *outer_rel, List *inner_rels)
if (nonoverlap_rels(inner_rel, outer_rel))
{
t_list = lappend(t_list,
init_join_rel(outer_rel,
make_join_rel(outer_rel,
inner_rel,
(JoinInfo *) NULL));
}
@@ -183,7 +188,7 @@ find_clauseless_joins(RelOptInfo *outer_rel, List *inner_rels)
}
/*
* init_join_rel
* make_join_rel
* Creates and initializes a new join relation.
*
* 'outer_rel' and 'inner_rel' are relation nodes for the relations to be
@@ -193,8 +198,8 @@ find_clauseless_joins(RelOptInfo *outer_rel, List *inner_rels)
*
* Returns the new join relation node.
*/
static RelOptInfo *
init_join_rel(RelOptInfo *outer_rel, RelOptInfo *inner_rel, JoinInfo * joininfo)
RelOptInfo *
make_join_rel(RelOptInfo *outer_rel, RelOptInfo *inner_rel, JoinInfo *joininfo)
{
RelOptInfo *joinrel = makeNode(RelOptInfo);
List *joinrel_joininfo_list = NIL;
@@ -217,7 +222,7 @@ init_join_rel(RelOptInfo *outer_rel, RelOptInfo *inner_rel, JoinInfo * joininfo)
joinrel->pages = 0;
joinrel->tuples = 0;
joinrel->width = 0;
/* joinrel->targetlist = NIL;*/
/* joinrel->targetlist = NIL;*/
joinrel->pathlist = NIL;
joinrel->cheapestpath = (Path *) NULL;
joinrel->pruneable = true;
@@ -229,9 +234,11 @@ init_join_rel(RelOptInfo *outer_rel, RelOptInfo *inner_rel, JoinInfo * joininfo)
joinrel->innerjoin = NIL;
joinrel->superrels = NIL;
joinrel->relids = lcons(outer_rel->relids, /* ??? aren't they lists?
* -ay */
lcons(inner_rel->relids, NIL));
/*
* This function uses a trick to pass inner/outer rels as
* different lists, and then flattens it out later.
*/
joinrel->relids = lcons(outer_rel->relids, lcons(inner_rel->relids, NIL));
new_outer_tlist = nconc(new_outer_tlist, new_inner_tlist);
joinrel->targetlist = new_outer_tlist;
@@ -239,8 +246,10 @@ init_join_rel(RelOptInfo *outer_rel, RelOptInfo *inner_rel, JoinInfo * joininfo)
if (joininfo)
{
joinrel->restrictinfo = joininfo->jinfo_restrictinfo;
#ifdef NOT_USED
if (BushyPlanFlag)
joininfo->inactive = true;
joininfo->bushy_inactive = true;
#endif
}
joinrel_joininfo_list = new_joininfo_list(append(outer_rel->joininfo, inner_rel->joininfo),
@@ -269,7 +278,7 @@ init_join_rel(RelOptInfo *outer_rel, RelOptInfo *inner_rel, JoinInfo * joininfo)
*
* Returns the new target list.
*/
static List *
List *
new_join_tlist(List *tlist,
List *other_relids,
int first_resdomno)
@@ -352,7 +361,7 @@ new_joininfo_list(List *joininfo_list, List *join_relids)
other_joininfo->jinfo_restrictinfo = joininfo->jinfo_restrictinfo;
other_joininfo->mergejoinable = joininfo->mergejoinable;
other_joininfo->hashjoinable = joininfo->hashjoinable;
other_joininfo->inactive = false;
other_joininfo->bushy_inactive = false;
current_joininfo_list = lcons(other_joininfo,
current_joininfo_list);
@@ -418,7 +427,7 @@ add_new_joininfos(Query *root, List *joinrels, List *outerrels)
new_joininfo->jinfo_restrictinfo = restrict_info;
new_joininfo->mergejoinable = mergejoinable;
new_joininfo->hashjoinable = hashjoinable;
new_joininfo->inactive = false;
new_joininfo->bushy_inactive = false;
rel->joininfo = lappend(rel->joininfo, new_joininfo);
foreach(xsuper_rel, super_rels)
@@ -444,7 +453,7 @@ add_new_joininfos(Query *root, List *joinrels, List *outerrels)
new_joininfo->jinfo_restrictinfo = restrict_info;
new_joininfo->mergejoinable = mergejoinable;
new_joininfo->hashjoinable = hashjoinable;
new_joininfo->inactive = false;
new_joininfo->bushy_inactive = false;
joinrel->joininfo = lappend(joinrel->joininfo,
new_joininfo);
}
@@ -461,6 +470,7 @@ add_new_joininfos(Query *root, List *joinrels, List *outerrels)
}
}
#ifdef NOT_USED
/*
* final_join_rels
* Find the join relation that includes all the original
@@ -470,11 +480,11 @@ add_new_joininfos(Query *root, List *joinrels, List *outerrels)
*
* Returns the list of final join relations.
*/
List *
RelOptInfo *
final_join_rels(List *join_rel_list)
{
List *xrel = NIL;
List *t_list = NIL;
RelOptInfo *final_rel = NULL;
/*
* find the relations that has no further joins, i.e., its joininfos
@@ -497,13 +507,14 @@ final_join_rels(List *join_rel_list)
}
}
if (final)
{
t_list = lappend(t_list, rel);
}
if (final_rel == NULL ||
path_is_cheaper(rel->cheapestpath, final_rel->cheapestpath))
final_rel = rel;
}
return t_list;
return final_rel;
}
#endif
/*
* add_superrels
@@ -551,7 +562,7 @@ nonoverlap_sets(List *s1, List *s2)
}
static void
set_joinrel_size(RelOptInfo *joinrel, RelOptInfo *outer_rel, RelOptInfo *inner_rel, JoinInfo * jinfo)
set_joinrel_size(RelOptInfo *joinrel, RelOptInfo *outer_rel, RelOptInfo *inner_rel, JoinInfo *jinfo)
{
int ntuples;
float selec;

View File

@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/Attic/mergeutils.c,v 1.18 1999/02/13 23:16:20 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/Attic/mergeutils.c,v 1.19 1999/02/15 03:22:06 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -47,7 +47,6 @@ group_clauses_by_order(List *restrictinfo_list,
if (merge_ordering)
{
/*
* Create a new mergeinfo node and add it to 'mergeinfo_list'
* if one does not yet exist for this merge ordering.

View File

@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/Attic/prune.c,v 1.32 1999/02/14 04:56:47 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/Attic/prune.c,v 1.33 1999/02/15 03:22:06 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -106,7 +106,7 @@ rels_set_cheapest(List *rel_list)
}
}
#ifdef NOT_USED
/*
* merge_joinrels
* Given two lists of rel nodes that are already
@@ -133,7 +133,7 @@ merge_joinrels(List *rel_list1, List *rel_list2)
/*
* prune_oldrels
* If all the joininfo's in a rel node are inactive,
* If all the joininfo's in a rel node are bushy_inactive,
* that means that this node has been joined into
* other nodes in all possible ways, therefore
* this node can be discarded. If not, it will cause
@@ -165,7 +165,7 @@ prune_oldrels(List *old_rels)
{
JoinInfo *joininfo = (JoinInfo *) lfirst(xjoininfo);
if (!joininfo->inactive)
if (!joininfo->bushy_inactive)
{
temp_list = lcons(rel, temp_list);
break;
@@ -175,3 +175,5 @@ prune_oldrels(List *old_rels)
}
return temp_list;
}
#endif