Commit 78a055a6 authored by Bruce Momjian's avatar Bruce Momjian

Remove some recursion in optimizer and clean up some code there.

parent 0808e658
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/allpaths.c,v 1.13 1997/09/08 21:44:44 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/optimizer/path/allpaths.c,v 1.14 1997/12/21 05:18:18 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -44,7 +44,7 @@ int32 _use_geqo_rels_ = GEQO_RELS; ...@@ -44,7 +44,7 @@ int32 _use_geqo_rels_ = GEQO_RELS;
static void find_rel_paths(Query *root, List *rels); static void find_rel_paths(Query *root, List *rels);
static List *find_join_paths(Query *root, List *outer_rels, int levels_left); static List *find_join_paths(Query *root, List *outer_rels, int levels_needed);
/* /*
* find-paths-- * find-paths--
...@@ -56,14 +56,14 @@ static List *find_join_paths(Query *root, List *outer_rels, int levels_left); ...@@ -56,14 +56,14 @@ static List *find_join_paths(Query *root, List *outer_rels, int levels_left);
List * List *
find_paths(Query *root, List *rels) find_paths(Query *root, List *rels)
{ {
int levels_left; int levels_needed;
/* /*
* Set the number of join (not nesting) levels yet to be processed. * Set the number of join (not nesting) levels yet to be processed.
*/ */
levels_left = length(rels); levels_needed = length(rels);
if (levels_left <= 0) if (levels_needed <= 0)
return NIL; return NIL;
/* /*
...@@ -71,13 +71,13 @@ find_paths(Query *root, List *rels) ...@@ -71,13 +71,13 @@ find_paths(Query *root, List *rels)
*/ */
find_rel_paths(root, rels); find_rel_paths(root, rels);
if (levels_left <= 1) if (levels_needed <= 1)
{ {
/* /*
* Unsorted single relation, no more processing is required. * Unsorted single relation, no more processing is required.
*/ */
return (rels); return rels;
} }
else else
{ {
...@@ -88,7 +88,7 @@ find_paths(Query *root, List *rels) ...@@ -88,7 +88,7 @@ find_paths(Query *root, List *rels)
*/ */
set_rest_relselec(root, rels); set_rest_relselec(root, rels);
return (find_join_paths(root, rels, levels_left - 1)); return find_join_paths(root, rels, levels_needed);
} }
} }
...@@ -165,17 +165,16 @@ find_rel_paths(Query *root, List *rels) ...@@ -165,17 +165,16 @@ find_rel_paths(Query *root, List *rels)
* 'outer-rels' is the current list of relations for which join paths * 'outer-rels' is the current list of relations for which join paths
* are to be found, i.e., he current list of relations that * are to be found, i.e., he current list of relations that
* have already been derived. * have already been derived.
* 'levels-left' is the current join level being processed, where '1' is * 'levels-needed' is the number of iterations needed
* the "last" level
* *
* Returns the final level of join relations, i.e., the relation that is * Returns the final level of join relations, i.e., the relation that is
* the result of joining all the original relations togehter. * the result of joining all the original relations together.
*/ */
static List * static List *
find_join_paths(Query *root, List *outer_rels, int levels_left) find_join_paths(Query *root, List *outer_rels, int levels_needed)
{ {
List *x; List *x;
List *new_rels; List *new_rels = NIL;
Rel *rel; Rel *rel;
/******************************************* /*******************************************
...@@ -190,89 +189,84 @@ find_join_paths(Query *root, List *outer_rels, int levels_left) ...@@ -190,89 +189,84 @@ find_join_paths(Query *root, List *outer_rels, int levels_left)
* rest will be deprecated in case of GEQO * * rest will be deprecated in case of GEQO *
*******************************************/ *******************************************/
/* while (--levels_needed)
* Determine all possible pairs of relations to be joined at this {
* level. Determine paths for joining these relation pairs and modify /*
* 'new-rels' accordingly, then eliminate redundant join relations. * Determine all possible pairs of relations to be joined at this
*/ * level. Determine paths for joining these relation pairs and modify
new_rels = find_join_rels(root, outer_rels); * 'new-rels' accordingly, then eliminate redundant join relations.
*/
find_all_join_paths(root, new_rels); new_rels = find_join_rels(root, outer_rels);
new_rels = prune_joinrels(new_rels); find_all_join_paths(root, new_rels);
prune_joinrels(new_rels);
#if 0 #if 0
/*
* * for each expensive predicate in each path in each distinct rel, *
* consider doing pullup -- JMH
*/
if (XfuncMode != XFUNC_NOPULL && XfuncMode != XFUNC_OFF)
foreach(x, new_rels)
xfunc_trypullup((Rel *) lfirst(x));
#endif
prune_rel_paths(new_rels);
if (BushyPlanFlag)
{
/* /*
* In case of bushy trees if there is still a join between a join * * for each expensive predicate in each path in each distinct rel, *
* relation and another relation, add a new joininfo that involves * consider doing pullup -- JMH
* the join relation to the joininfo list of the other relation
*/ */
add_new_joininfos(root, new_rels, outer_rels); if (XfuncMode != XFUNC_NOPULL && XfuncMode != XFUNC_OFF)
} foreach(x, new_rels)
xfunc_trypullup((Rel *) lfirst(x));
foreach(x, new_rels) #endif
{
rel = (Rel *) lfirst(x); prune_rel_paths(new_rels);
if (rel->size <= 0)
rel->size = compute_rel_size(rel); if (BushyPlanFlag)
rel->width = compute_rel_width(rel); {
/*#define OPTIMIZER_DEBUG*/ /*
* In case of bushy trees if there is still a join between a join
* relation and another relation, add a new joininfo that involves
* the join relation to the joininfo list of the other relation
*/
add_new_joininfos(root, new_rels, outer_rels);
}
foreach(x, new_rels)
{
rel = (Rel *) lfirst(x);
if (rel->size <= 0)
rel->size = compute_rel_size(rel);
rel->width = compute_rel_width(rel);
/*#define OPTIMIZER_DEBUG*/
#ifdef OPTIMIZER_DEBUG #ifdef OPTIMIZER_DEBUG
printf("levels left: %d\n", levels_left); printf("levels left: %d\n", levels_left);
debug_print_rel(root, rel); debug_print_rel(root, rel);
#endif #endif
} }
if (BushyPlanFlag)
{
/*
* prune rels that have been completely incorporated into new join
* rels
*/
outer_rels = prune_oldrels(outer_rels);
/*
* merge join rels if then contain the same list of base rels
*/
outer_rels = merge_joinrels(new_rels, outer_rels);
root->join_relation_list_ = outer_rels;
}
else
{
root->join_relation_list_ = new_rels;
}
if (levels_left == 1)
{
if (BushyPlanFlag) if (BushyPlanFlag)
return (final_join_rels(outer_rels)); {
/*
* prune rels that have been completely incorporated into new join
* rels
*/
outer_rels = prune_oldrels(outer_rels);
/*
* merge join rels if then contain the same list of base rels
*/
outer_rels = merge_joinrels(new_rels, outer_rels);
root->join_relation_list_ = outer_rels;
}
else else
return (new_rels); {
root->join_relation_list_ = new_rels;
}
if (!BushyPlanFlag)
outer_rels = new_rels;
} }
if (BushyPlanFlag)
return final_join_rels(outer_rels);
else else
{ return new_rels;
if (BushyPlanFlag)
return (find_join_paths(root, outer_rels, levels_left - 1));
else
return (find_join_paths(root, new_rels, levels_left - 1));
}
} }
/***************************************************************************** /*****************************************************************************
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/Attic/prune.c,v 1.6 1997/09/08 21:45:08 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/optimizer/path/Attic/prune.c,v 1.7 1997/12/21 05:18:21 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -29,23 +29,21 @@ static List *prune_joinrel(Rel *rel, List *other_rels); ...@@ -29,23 +29,21 @@ static List *prune_joinrel(Rel *rel, List *other_rels);
/* /*
* prune-joinrels-- * prune-joinrels--
* Removes any redundant relation entries from a list of rel nodes * Removes any redundant relation entries from a list of rel nodes
* 'rel-list'. * 'rel-list'. Obviosly, the first relation can't be a duplicate.
* *
* Returns the resulting list. * Returns the resulting list.
* *
*/ */
List * void
prune_joinrels(List *rel_list) prune_joinrels(List *rel_list)
{ {
List *temp_list = NIL; List *i;
if (rel_list != NIL) /*
{ * rel_list can shorten while running as duplicate relations are deleted
temp_list = lcons(lfirst(rel_list), */
prune_joinrels(prune_joinrel((Rel *) lfirst(rel_list), foreach(i, rel_list)
lnext(rel_list)))); lnext(i) = prune_joinrel((Rel *) lfirst(i), lnext(i));
}
return (temp_list);
} }
/* /*
...@@ -62,28 +60,39 @@ prune_joinrels(List *rel_list) ...@@ -62,28 +60,39 @@ prune_joinrels(List *rel_list)
static List * static List *
prune_joinrel(Rel *rel, List *other_rels) prune_joinrel(Rel *rel, List *other_rels)
{ {
List *i = NIL; List *cur = NIL;
List *t_list = NIL; List *return_list = NIL;
List *temp_node = NIL;
Rel *other_rel = (Rel *) NULL;
foreach(i, other_rels) /* find first relation that doesn't match */
foreach(cur, other_rels)
{ {
other_rel = (Rel *) lfirst(i); Rel *other_rel = (Rel *) lfirst(cur);
if (same(rel->relids, other_rel->relids))
{ if (!same(rel->relids, other_rel->relids))
rel->pathlist = add_pathlist(rel, break;
rel->pathlist, }
other_rel->pathlist);
t_list = nconc(t_list, NIL); /* XXX is this right ? */ /* we now know cur doesn't match, or is NIL */
} return_list = cur;
else
/* remove relations that do match, we use lnext so we can remove easily */
if (cur != NIL)
{
while (lnext(cur) != NIL)
{ {
temp_node = lcons(other_rel, NIL); Rel *other_rel = (Rel *) lfirst(lnext(cur));
t_list = nconc(t_list, temp_node);
if (same(rel->relids, other_rel->relids))
{
rel->pathlist = add_pathlist(rel,
rel->pathlist,
other_rel->pathlist);
lnext(cur) = lnext(lnext(cur)); /* delete it */
}
cur = lnext(cur);
} }
} }
return (t_list); return return_list;
} }
/* /*
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/prep/prepunion.c,v 1.11 1997/12/20 07:59:33 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/optimizer/prep/prepunion.c,v 1.12 1997/12/21 05:18:28 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -236,9 +236,13 @@ plan_union_query(List *relids, ...@@ -236,9 +236,13 @@ plan_union_query(List *relids,
new_root->uniqueFlag = NULL; new_root->uniqueFlag = NULL;
new_root->sortClause = NULL; new_root->sortClause = NULL;
new_root->groupClause = NULL; new_root->groupClause = NULL;
new_root->qry_numAgg = 0; if (new_root->qry_numAgg != 0)
new_root->qry_aggs = NULL; {
del_agg_tlist_references(new_root->targetList); new_root->qry_numAgg = 0;
pfree(new_root->qry_aggs);
new_root->qry_aggs = NULL;
del_agg_tlist_references(new_root->targetList);
}
fix_parsetree_attnums(rt_index, fix_parsetree_attnums(rt_index,
rt_entry->relid, rt_entry->relid,
relid, relid,
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* Copyright (c) 1994, Regents of the University of California * Copyright (c) 1994, Regents of the University of California
* *
* $Id: paths.h,v 1.5 1997/11/26 01:13:47 momjian Exp $ * $Id: paths.h,v 1.6 1997/12/21 05:18:48 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -92,7 +92,7 @@ extern List *final_join_rels(List *join_rel_list); ...@@ -92,7 +92,7 @@ extern List *final_join_rels(List *join_rel_list);
/* /*
* prototypes for path/prune.c * prototypes for path/prune.c
*/ */
extern List *prune_joinrels(List *rel_list); extern void prune_joinrels(List *rel_list);
extern void prune_rel_paths(List *rel_list); extern void prune_rel_paths(List *rel_list);
extern Path *prune_rel_path(Rel *rel, Path *unorderedpath); extern Path *prune_rel_path(Rel *rel, Path *unorderedpath);
extern List *merge_joinrels(List *rel_list1, List *rel_list2); extern List *merge_joinrels(List *rel_list1, List *rel_list2);
......
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