diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2002-12-16 21:30:30 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2002-12-16 21:30:30 +0000 |
commit | 9f76d0d926ffe72e32248b7c79f585c47e643981 (patch) | |
tree | 5fc47061415534dab7ff97519aea1603bccce0c9 /src/backend/optimizer/path/indxpath.c | |
parent | 9cecff0314c3c75248f29fea6b80c19d9a8a8c70 (diff) | |
download | postgresql-9f76d0d926ffe72e32248b7c79f585c47e643981.tar.gz postgresql-9f76d0d926ffe72e32248b7c79f585c47e643981.zip |
Fix GEQO to work again in CVS tip, by being more careful about memory
allocation in best_inner_indexscan(). While at it, simplify GEQO's
interface to the main planner --- make_join_rel() offers exactly the
API it really wants, whereas calling make_rels_by_clause_joins() and
make_rels_by_clauseless_joins() required jumping through hoops.
Rewrite gimme_tree for clarity (sometimes iteration is much better than
recursion), and approximately halve GEQO's runtime by recognizing that
tours of the forms (a,b,c,d,...) and (b,a,c,d,...) are equivalent
because of symmetry in make_join_rel().
Diffstat (limited to 'src/backend/optimizer/path/indxpath.c')
-rw-r--r-- | src/backend/optimizer/path/indxpath.c | 24 |
1 files changed, 20 insertions, 4 deletions
diff --git a/src/backend/optimizer/path/indxpath.c b/src/backend/optimizer/path/indxpath.c index 984c930e3a6..228a876f71a 100644 --- a/src/backend/optimizer/path/indxpath.c +++ b/src/backend/optimizer/path/indxpath.c @@ -9,7 +9,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/optimizer/path/indxpath.c,v 1.129 2002/12/15 16:17:49 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/path/indxpath.c,v 1.130 2002/12/16 21:30:29 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -1398,6 +1398,7 @@ best_inner_indexscan(Query *root, RelOptInfo *rel, List *ilist; List *jlist; InnerIndexscanInfo *info; + MemoryContext oldcontext; /* * Nestloop only supports inner and left joins. @@ -1415,15 +1416,27 @@ best_inner_indexscan(Query *root, RelOptInfo *rel, } /* * If there are no indexable joinclauses for this rel, exit quickly. - * Otherwise, intersect the given outer_relids with index_outer_relids - * to find the set of outer relids actually relevant for this index. - * If there are none, again we can fail immediately. */ if (!rel->index_outer_relids) return NULL; + /* + * Otherwise, we have to do path selection in the memory context of + * the given rel, so that any created path can be safely attached to + * the rel's cache of best inner paths. (This is not currently an + * issue for normal planning, but it is an issue for GEQO planning.) + */ + oldcontext = MemoryContextSwitchTo(GetMemoryChunkContext(rel)); + /* + * Intersect the given outer_relids with index_outer_relids + * to find the set of outer relids actually relevant for this index. + * If there are none, again we can fail immediately. + */ outer_relids = set_intersecti(rel->index_outer_relids, outer_relids); if (!outer_relids) + { + MemoryContextSwitchTo(oldcontext); return NULL; + } /* * Look to see if we already computed the result for this set of * relevant outerrels. (We include the isouterjoin status in the @@ -1437,6 +1450,7 @@ best_inner_indexscan(Query *root, RelOptInfo *rel, info->isouterjoin == isouterjoin) { freeList(outer_relids); + MemoryContextSwitchTo(oldcontext); return info->best_innerpath; } } @@ -1517,6 +1531,8 @@ best_inner_indexscan(Query *root, RelOptInfo *rel, info->best_innerpath = cheapest; rel->index_inner_paths = lcons(info, rel->index_inner_paths); + MemoryContextSwitchTo(oldcontext); + return cheapest; } |