mirror of
https://github.com/postgres/postgres.git
synced 2025-11-09 06:21:09 +03:00
Plug some more memory leaks in the planner. It still leaks like a sieve,
but this is as good as it'll get for this release...
This commit is contained in:
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/joinpath.c,v 1.52 2000/02/15 20:49:17 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/joinpath.c,v 1.53 2000/02/18 23:47:19 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -171,9 +171,13 @@ sort_inner_and_outer(Query *root,
|
||||
List *merge_pathkeys;
|
||||
|
||||
/* Make a mergeclause list with this guy first. */
|
||||
curclause_list = lcons(restrictinfo,
|
||||
lremove(restrictinfo,
|
||||
listCopy(mergeclause_list)));
|
||||
if (i != mergeclause_list)
|
||||
curclause_list = lcons(restrictinfo,
|
||||
lremove(restrictinfo,
|
||||
listCopy(mergeclause_list)));
|
||||
else
|
||||
curclause_list = mergeclause_list; /* no work at first one... */
|
||||
|
||||
/* Build sort pathkeys for both sides.
|
||||
*
|
||||
* Note: it's possible that the cheapest paths will already be
|
||||
@@ -203,7 +207,7 @@ sort_inner_and_outer(Query *root,
|
||||
innerrel->cheapest_total_path,
|
||||
restrictlist,
|
||||
merge_pathkeys,
|
||||
get_actual_clauses(curclause_list),
|
||||
curclause_list,
|
||||
outerkeys,
|
||||
innerkeys));
|
||||
}
|
||||
@@ -265,6 +269,7 @@ match_unsorted_outer(Query *root,
|
||||
List *trialsortkeys;
|
||||
Path *cheapest_startup_inner;
|
||||
Path *cheapest_total_inner;
|
||||
int num_mergeclauses;
|
||||
int clausecnt;
|
||||
|
||||
/*
|
||||
@@ -325,7 +330,7 @@ match_unsorted_outer(Query *root,
|
||||
innerrel->cheapest_total_path,
|
||||
restrictlist,
|
||||
merge_pathkeys,
|
||||
get_actual_clauses(mergeclauses),
|
||||
mergeclauses,
|
||||
NIL,
|
||||
innersortkeys));
|
||||
|
||||
@@ -337,10 +342,12 @@ match_unsorted_outer(Query *root,
|
||||
trialsortkeys = listCopy(innersortkeys); /* modifiable copy */
|
||||
cheapest_startup_inner = NULL;
|
||||
cheapest_total_inner = NULL;
|
||||
num_mergeclauses = length(mergeclauses);
|
||||
|
||||
for (clausecnt = length(mergeclauses); clausecnt > 0; clausecnt--)
|
||||
for (clausecnt = num_mergeclauses; clausecnt > 0; clausecnt--)
|
||||
{
|
||||
Path *innerpath;
|
||||
List *newclauses = NIL;
|
||||
|
||||
/* Look for an inner path ordered well enough to merge with
|
||||
* the first 'clausecnt' mergeclauses. NB: trialsortkeys list
|
||||
@@ -356,10 +363,11 @@ match_unsorted_outer(Query *root,
|
||||
TOTAL_COST) < 0))
|
||||
{
|
||||
/* Found a cheap (or even-cheaper) sorted path */
|
||||
List *newclauses;
|
||||
|
||||
newclauses = ltruncate(clausecnt,
|
||||
get_actual_clauses(mergeclauses));
|
||||
if (clausecnt < num_mergeclauses)
|
||||
newclauses = ltruncate(clausecnt,
|
||||
listCopy(mergeclauses));
|
||||
else
|
||||
newclauses = mergeclauses;
|
||||
add_path(joinrel, (Path *)
|
||||
create_mergejoin_path(joinrel,
|
||||
outerpath,
|
||||
@@ -383,10 +391,17 @@ match_unsorted_outer(Query *root,
|
||||
/* Found a cheap (or even-cheaper) sorted path */
|
||||
if (innerpath != cheapest_total_inner)
|
||||
{
|
||||
List *newclauses;
|
||||
|
||||
newclauses = ltruncate(clausecnt,
|
||||
get_actual_clauses(mergeclauses));
|
||||
/* Avoid rebuilding clause list if we already made one;
|
||||
* saves memory in big join trees...
|
||||
*/
|
||||
if (newclauses == NIL)
|
||||
{
|
||||
if (clausecnt < num_mergeclauses)
|
||||
newclauses = ltruncate(clausecnt,
|
||||
listCopy(mergeclauses));
|
||||
else
|
||||
newclauses = mergeclauses;
|
||||
}
|
||||
add_path(joinrel, (Path *)
|
||||
create_mergejoin_path(joinrel,
|
||||
outerpath,
|
||||
@@ -461,7 +476,7 @@ match_unsorted_inner(Query *root,
|
||||
innerpath,
|
||||
restrictlist,
|
||||
merge_pathkeys,
|
||||
get_actual_clauses(mergeclauses),
|
||||
mergeclauses,
|
||||
outersortkeys,
|
||||
NIL));
|
||||
/*
|
||||
@@ -487,7 +502,7 @@ match_unsorted_inner(Query *root,
|
||||
innerpath,
|
||||
restrictlist,
|
||||
merge_pathkeys,
|
||||
get_actual_clauses(mergeclauses),
|
||||
mergeclauses,
|
||||
NIL,
|
||||
NIL));
|
||||
|
||||
@@ -505,7 +520,7 @@ match_unsorted_inner(Query *root,
|
||||
innerpath,
|
||||
restrictlist,
|
||||
merge_pathkeys,
|
||||
get_actual_clauses(mergeclauses),
|
||||
mergeclauses,
|
||||
NIL,
|
||||
NIL));
|
||||
}
|
||||
@@ -552,6 +567,7 @@ hash_inner_and_outer(Query *root,
|
||||
Var *left,
|
||||
*right,
|
||||
*inner;
|
||||
List *hashclauses;
|
||||
Selectivity innerdisbursion;
|
||||
|
||||
if (restrictinfo->hashjoinoperator == InvalidOid)
|
||||
@@ -572,6 +588,9 @@ hash_inner_and_outer(Query *root,
|
||||
else
|
||||
continue; /* no good for these input relations */
|
||||
|
||||
/* always a one-element list of hash clauses */
|
||||
hashclauses = lcons(restrictinfo, NIL);
|
||||
|
||||
/* estimate disbursion of inner var for costing purposes */
|
||||
innerdisbursion = estimate_disbursion(root, inner);
|
||||
|
||||
@@ -585,7 +604,7 @@ hash_inner_and_outer(Query *root,
|
||||
outerrel->cheapest_total_path,
|
||||
innerrel->cheapest_total_path,
|
||||
restrictlist,
|
||||
lcons(clause, NIL),
|
||||
hashclauses,
|
||||
innerdisbursion));
|
||||
if (outerrel->cheapest_startup_path != outerrel->cheapest_total_path)
|
||||
add_path(joinrel, (Path *)
|
||||
@@ -593,7 +612,7 @@ hash_inner_and_outer(Query *root,
|
||||
outerrel->cheapest_startup_path,
|
||||
innerrel->cheapest_total_path,
|
||||
restrictlist,
|
||||
lcons(clause, NIL),
|
||||
hashclauses,
|
||||
innerdisbursion));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/pathkeys.c,v 1.19 2000/02/15 20:49:17 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/pathkeys.c,v 1.20 2000/02/18 23:47:19 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -778,6 +778,7 @@ make_pathkeys_for_mergeclauses(Query *root,
|
||||
Node *key;
|
||||
Oid sortop;
|
||||
PathKeyItem *item;
|
||||
List *pathkey;
|
||||
|
||||
Assert(restrictinfo->mergejoinoperator != InvalidOid);
|
||||
|
||||
@@ -791,10 +792,21 @@ make_pathkeys_for_mergeclauses(Query *root,
|
||||
key = (Node *) get_leftop(restrictinfo->clause);
|
||||
sortop = restrictinfo->left_sortop;
|
||||
/*
|
||||
* Add a pathkey sublist for this sort item
|
||||
* Find pathkey sublist for this sort item. We expect to find
|
||||
* the canonical set including the mergeclause's left and right
|
||||
* sides; if we get back just the one item, something is rotten.
|
||||
*/
|
||||
item = makePathKeyItem(key, sortop);
|
||||
pathkeys = lappend(pathkeys, make_canonical_pathkey(root, item));
|
||||
pathkey = make_canonical_pathkey(root, item);
|
||||
Assert(length(pathkey) > 1);
|
||||
/*
|
||||
* Since the item we just made is not in the returned canonical set,
|
||||
* we can free it --- this saves a useful amount of storage in a
|
||||
* big join tree.
|
||||
*/
|
||||
pfree(item);
|
||||
|
||||
pathkeys = lappend(pathkeys, pathkey);
|
||||
}
|
||||
|
||||
return pathkeys;
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.85 2000/02/15 20:49:18 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.86 2000/02/18 23:47:21 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -626,13 +626,14 @@ create_mergejoin_node(MergePath *best_path,
|
||||
*mergeclauses;
|
||||
MergeJoin *join_node;
|
||||
|
||||
mergeclauses = get_actual_clauses(best_path->path_mergeclauses);
|
||||
|
||||
/*
|
||||
* Remove the mergeclauses from the list of join qual clauses,
|
||||
* leaving the list of quals that must be checked as qpquals.
|
||||
* Set those clauses to contain INNER/OUTER var references.
|
||||
*/
|
||||
qpqual = join_references(set_difference(clauses,
|
||||
best_path->path_mergeclauses),
|
||||
qpqual = join_references(set_difference(clauses, mergeclauses),
|
||||
outer_tlist,
|
||||
inner_tlist,
|
||||
(Index) 0);
|
||||
@@ -641,7 +642,7 @@ create_mergejoin_node(MergePath *best_path,
|
||||
* Now set the references in the mergeclauses and rearrange them so
|
||||
* that the outer variable is always on the left.
|
||||
*/
|
||||
mergeclauses = switch_outer(join_references(best_path->path_mergeclauses,
|
||||
mergeclauses = switch_outer(join_references(mergeclauses,
|
||||
outer_tlist,
|
||||
inner_tlist,
|
||||
(Index) 0));
|
||||
@@ -692,14 +693,14 @@ create_hashjoin_node(HashPath *best_path,
|
||||
* We represent it as a list anyway, for convenience with routines
|
||||
* that want to work on lists of clauses.
|
||||
*/
|
||||
hashclauses = get_actual_clauses(best_path->path_hashclauses);
|
||||
|
||||
/*
|
||||
* Remove the hashclauses from the list of join qual clauses,
|
||||
* leaving the list of quals that must be checked as qpquals.
|
||||
* Set those clauses to contain INNER/OUTER var references.
|
||||
*/
|
||||
qpqual = join_references(set_difference(clauses,
|
||||
best_path->path_hashclauses),
|
||||
qpqual = join_references(set_difference(clauses, hashclauses),
|
||||
outer_tlist,
|
||||
inner_tlist,
|
||||
(Index) 0);
|
||||
@@ -708,7 +709,7 @@ create_hashjoin_node(HashPath *best_path,
|
||||
* Now set the references in the hashclauses and rearrange them so
|
||||
* that the outer variable is always on the left.
|
||||
*/
|
||||
hashclauses = switch_outer(join_references(best_path->path_hashclauses,
|
||||
hashclauses = switch_outer(join_references(hashclauses,
|
||||
outer_tlist,
|
||||
inner_tlist,
|
||||
(Index) 0));
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/optimizer/util/pathnode.c,v 1.60 2000/02/15 20:49:20 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/optimizer/util/pathnode.c,v 1.61 2000/02/18 23:47:30 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -416,7 +416,8 @@ create_nestloop_path(RelOptInfo *joinrel,
|
||||
* 'inner_path' is the inner path
|
||||
* 'restrict_clauses' are the RestrictInfo nodes to apply at the join
|
||||
* 'pathkeys' are the path keys of the new join path
|
||||
* 'mergeclauses' are the applicable join/restriction clauses
|
||||
* 'mergeclauses' are the RestrictInfo nodes to use as merge clauses
|
||||
* (this should be a subset of the restrict_clauses list)
|
||||
* 'outersortkeys' are the sort varkeys for the outer relation
|
||||
* 'innersortkeys' are the sort varkeys for the inner relation
|
||||
*
|
||||
@@ -473,6 +474,7 @@ create_mergejoin_path(RelOptInfo *joinrel,
|
||||
* 'inner_path' is the cheapest inner path
|
||||
* '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)
|
||||
* (this should be a subset of the restrict_clauses list)
|
||||
* 'innerdisbursion' is an estimate of the disbursion of the inner hash key
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/optimizer/util/relnode.c,v 1.24 2000/02/15 20:49:21 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/optimizer/util/relnode.c,v 1.25 2000/02/18 23:47:31 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -345,11 +345,8 @@ subbuild_joinrel_restrictlist(RelOptInfo *joinrel,
|
||||
foreach(xjoininfo, joininfo_list)
|
||||
{
|
||||
JoinInfo *joininfo = (JoinInfo *) lfirst(xjoininfo);
|
||||
Relids new_unjoined_relids;
|
||||
|
||||
new_unjoined_relids = set_differencei(joininfo->unjoined_relids,
|
||||
joinrel->relids);
|
||||
if (new_unjoined_relids == NIL)
|
||||
if (is_subseti(joininfo->unjoined_relids, joinrel->relids))
|
||||
{
|
||||
/*
|
||||
* Clauses in this JoinInfo list become restriction clauses
|
||||
|
||||
Reference in New Issue
Block a user