mirror of
https://github.com/postgres/postgres.git
synced 2025-06-26 12:21:12 +03:00
Remove some recursion in optimizer and clean up some code there.
This commit is contained in:
@ -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;
|
|||||||
|
|
||||||
|
|
||||||
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);
|
|||||||
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)
|
|||||||
*/
|
*/
|
||||||
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)
|
|||||||
*/
|
*/
|
||||||
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)
|
|||||||
* '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,6 +189,8 @@ 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
|
* Determine all possible pairs of relations to be joined at this
|
||||||
* level. Determine paths for joining these relation pairs and modify
|
* level. Determine paths for joining these relation pairs and modify
|
||||||
@ -199,7 +200,7 @@ find_join_paths(Query *root, List *outer_rels, int levels_left)
|
|||||||
|
|
||||||
find_all_join_paths(root, new_rels);
|
find_all_join_paths(root, new_rels);
|
||||||
|
|
||||||
new_rels = prune_joinrels(new_rels);
|
prune_joinrels(new_rels);
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
|
||||||
@ -232,7 +233,7 @@ find_join_paths(Query *root, List *outer_rels, int levels_left)
|
|||||||
rel->size = compute_rel_size(rel);
|
rel->size = compute_rel_size(rel);
|
||||||
rel->width = compute_rel_width(rel);
|
rel->width = compute_rel_width(rel);
|
||||||
|
|
||||||
/*#define OPTIMIZER_DEBUG*/
|
/*#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);
|
||||||
@ -258,21 +259,14 @@ find_join_paths(Query *root, List *outer_rels, int levels_left)
|
|||||||
{
|
{
|
||||||
root->join_relation_list_ = new_rels;
|
root->join_relation_list_ = new_rels;
|
||||||
}
|
}
|
||||||
|
if (!BushyPlanFlag)
|
||||||
|
outer_rels = new_rels;
|
||||||
|
}
|
||||||
|
|
||||||
if (levels_left == 1)
|
|
||||||
{
|
|
||||||
if (BushyPlanFlag)
|
if (BushyPlanFlag)
|
||||||
return (final_join_rels(outer_rels));
|
return final_join_rels(outer_rels);
|
||||||
else
|
else
|
||||||
return (new_rels);
|
return new_rels;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
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 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* 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);
|
|||||||
/*
|
/*
|
||||||
* 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)
|
|||||||
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))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* we now know cur doesn't match, or is NIL */
|
||||||
|
return_list = cur;
|
||||||
|
|
||||||
|
/* remove relations that do match, we use lnext so we can remove easily */
|
||||||
|
if (cur != NIL)
|
||||||
|
{
|
||||||
|
while (lnext(cur) != NIL)
|
||||||
|
{
|
||||||
|
Rel *other_rel = (Rel *) lfirst(lnext(cur));
|
||||||
|
|
||||||
if (same(rel->relids, other_rel->relids))
|
if (same(rel->relids, other_rel->relids))
|
||||||
{
|
{
|
||||||
rel->pathlist = add_pathlist(rel,
|
rel->pathlist = add_pathlist(rel,
|
||||||
rel->pathlist,
|
rel->pathlist,
|
||||||
other_rel->pathlist);
|
other_rel->pathlist);
|
||||||
t_list = nconc(t_list, NIL); /* XXX is this right ? */
|
lnext(cur) = lnext(lnext(cur)); /* delete it */
|
||||||
}
|
}
|
||||||
else
|
cur = lnext(cur);
|
||||||
{
|
|
||||||
temp_node = lcons(other_rel, NIL);
|
|
||||||
t_list = nconc(t_list, temp_node);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return (t_list);
|
return return_list;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -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,
|
|||||||
new_root->uniqueFlag = NULL;
|
new_root->uniqueFlag = NULL;
|
||||||
new_root->sortClause = NULL;
|
new_root->sortClause = NULL;
|
||||||
new_root->groupClause = NULL;
|
new_root->groupClause = NULL;
|
||||||
|
if (new_root->qry_numAgg != 0)
|
||||||
|
{
|
||||||
new_root->qry_numAgg = 0;
|
new_root->qry_numAgg = 0;
|
||||||
|
pfree(new_root->qry_aggs);
|
||||||
new_root->qry_aggs = NULL;
|
new_root->qry_aggs = NULL;
|
||||||
del_agg_tlist_references(new_root->targetList);
|
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 @@
|
|||||||
*
|
*
|
||||||
* 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);
|
|||||||
/*
|
/*
|
||||||
* 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);
|
||||||
|
Reference in New Issue
Block a user