Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit3cbcb78

Browse files
committed
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...
1 parentbc8a39b commit3cbcb78

File tree

6 files changed

+89
-49
lines changed

6 files changed

+89
-49
lines changed

‎src/backend/optimizer/path/joinpath.c

Lines changed: 39 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/joinpath.c,v 1.52 2000/02/15 20:49:17 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/joinpath.c,v 1.53 2000/02/18 23:47:19 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -171,9 +171,13 @@ sort_inner_and_outer(Query *root,
171171
List*merge_pathkeys;
172172

173173
/* Make a mergeclause list with this guy first. */
174-
curclause_list=lcons(restrictinfo,
175-
lremove(restrictinfo,
176-
listCopy(mergeclause_list)));
174+
if (i!=mergeclause_list)
175+
curclause_list=lcons(restrictinfo,
176+
lremove(restrictinfo,
177+
listCopy(mergeclause_list)));
178+
else
179+
curclause_list=mergeclause_list;/* no work at first one... */
180+
177181
/* Build sort pathkeys for both sides.
178182
*
179183
* Note: it's possible that the cheapest paths will already be
@@ -203,7 +207,7 @@ sort_inner_and_outer(Query *root,
203207
innerrel->cheapest_total_path,
204208
restrictlist,
205209
merge_pathkeys,
206-
get_actual_clauses(curclause_list),
210+
curclause_list,
207211
outerkeys,
208212
innerkeys));
209213
}
@@ -265,6 +269,7 @@ match_unsorted_outer(Query *root,
265269
List*trialsortkeys;
266270
Path*cheapest_startup_inner;
267271
Path*cheapest_total_inner;
272+
intnum_mergeclauses;
268273
intclausecnt;
269274

270275
/*
@@ -325,7 +330,7 @@ match_unsorted_outer(Query *root,
325330
innerrel->cheapest_total_path,
326331
restrictlist,
327332
merge_pathkeys,
328-
get_actual_clauses(mergeclauses),
333+
mergeclauses,
329334
NIL,
330335
innersortkeys));
331336

@@ -337,10 +342,12 @@ match_unsorted_outer(Query *root,
337342
trialsortkeys=listCopy(innersortkeys);/* modifiable copy */
338343
cheapest_startup_inner=NULL;
339344
cheapest_total_inner=NULL;
345+
num_mergeclauses=length(mergeclauses);
340346

341-
for (clausecnt=length(mergeclauses);clausecnt>0;clausecnt--)
347+
for (clausecnt=num_mergeclauses;clausecnt>0;clausecnt--)
342348
{
343349
Path*innerpath;
350+
List*newclauses=NIL;
344351

345352
/* Look for an inner path ordered well enough to merge with
346353
* the first 'clausecnt' mergeclauses. NB: trialsortkeys list
@@ -356,10 +363,11 @@ match_unsorted_outer(Query *root,
356363
TOTAL_COST)<0))
357364
{
358365
/* Found a cheap (or even-cheaper) sorted path */
359-
List*newclauses;
360-
361-
newclauses=ltruncate(clausecnt,
362-
get_actual_clauses(mergeclauses));
366+
if (clausecnt<num_mergeclauses)
367+
newclauses=ltruncate(clausecnt,
368+
listCopy(mergeclauses));
369+
else
370+
newclauses=mergeclauses;
363371
add_path(joinrel, (Path*)
364372
create_mergejoin_path(joinrel,
365373
outerpath,
@@ -383,10 +391,17 @@ match_unsorted_outer(Query *root,
383391
/* Found a cheap (or even-cheaper) sorted path */
384392
if (innerpath!=cheapest_total_inner)
385393
{
386-
List*newclauses;
387-
388-
newclauses=ltruncate(clausecnt,
389-
get_actual_clauses(mergeclauses));
394+
/* Avoid rebuilding clause list if we already made one;
395+
* saves memory in big join trees...
396+
*/
397+
if (newclauses==NIL)
398+
{
399+
if (clausecnt<num_mergeclauses)
400+
newclauses=ltruncate(clausecnt,
401+
listCopy(mergeclauses));
402+
else
403+
newclauses=mergeclauses;
404+
}
390405
add_path(joinrel, (Path*)
391406
create_mergejoin_path(joinrel,
392407
outerpath,
@@ -461,7 +476,7 @@ match_unsorted_inner(Query *root,
461476
innerpath,
462477
restrictlist,
463478
merge_pathkeys,
464-
get_actual_clauses(mergeclauses),
479+
mergeclauses,
465480
outersortkeys,
466481
NIL));
467482
/*
@@ -487,7 +502,7 @@ match_unsorted_inner(Query *root,
487502
innerpath,
488503
restrictlist,
489504
merge_pathkeys,
490-
get_actual_clauses(mergeclauses),
505+
mergeclauses,
491506
NIL,
492507
NIL));
493508

@@ -505,7 +520,7 @@ match_unsorted_inner(Query *root,
505520
innerpath,
506521
restrictlist,
507522
merge_pathkeys,
508-
get_actual_clauses(mergeclauses),
523+
mergeclauses,
509524
NIL,
510525
NIL));
511526
}
@@ -552,6 +567,7 @@ hash_inner_and_outer(Query *root,
552567
Var*left,
553568
*right,
554569
*inner;
570+
List*hashclauses;
555571
Selectivityinnerdisbursion;
556572

557573
if (restrictinfo->hashjoinoperator==InvalidOid)
@@ -572,6 +588,9 @@ hash_inner_and_outer(Query *root,
572588
else
573589
continue;/* no good for these input relations */
574590

591+
/* always a one-element list of hash clauses */
592+
hashclauses=lcons(restrictinfo,NIL);
593+
575594
/* estimate disbursion of inner var for costing purposes */
576595
innerdisbursion=estimate_disbursion(root,inner);
577596

@@ -585,15 +604,15 @@ hash_inner_and_outer(Query *root,
585604
outerrel->cheapest_total_path,
586605
innerrel->cheapest_total_path,
587606
restrictlist,
588-
lcons(clause,NIL),
607+
hashclauses,
589608
innerdisbursion));
590609
if (outerrel->cheapest_startup_path!=outerrel->cheapest_total_path)
591610
add_path(joinrel, (Path*)
592611
create_hashjoin_path(joinrel,
593612
outerrel->cheapest_startup_path,
594613
innerrel->cheapest_total_path,
595614
restrictlist,
596-
lcons(clause,NIL),
615+
hashclauses,
597616
innerdisbursion));
598617
}
599618
}

‎src/backend/optimizer/path/pathkeys.c

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/pathkeys.c,v 1.19 2000/02/15 20:49:17 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/pathkeys.c,v 1.20 2000/02/18 23:47:19 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -778,6 +778,7 @@ make_pathkeys_for_mergeclauses(Query *root,
778778
Node*key;
779779
Oidsortop;
780780
PathKeyItem*item;
781+
List*pathkey;
781782

782783
Assert(restrictinfo->mergejoinoperator!=InvalidOid);
783784

@@ -791,10 +792,21 @@ make_pathkeys_for_mergeclauses(Query *root,
791792
key= (Node*)get_leftop(restrictinfo->clause);
792793
sortop=restrictinfo->left_sortop;
793794
/*
794-
* Add a pathkey sublist for this sort item
795+
* Find pathkey sublist for this sort item. We expect to find
796+
* the canonical set including the mergeclause's left and right
797+
* sides; if we get back just the one item, something is rotten.
795798
*/
796799
item=makePathKeyItem(key,sortop);
797-
pathkeys=lappend(pathkeys,make_canonical_pathkey(root,item));
800+
pathkey=make_canonical_pathkey(root,item);
801+
Assert(length(pathkey)>1);
802+
/*
803+
* Since the item we just made is not in the returned canonical set,
804+
* we can free it --- this saves a useful amount of storage in a
805+
* big join tree.
806+
*/
807+
pfree(item);
808+
809+
pathkeys=lappend(pathkeys,pathkey);
798810
}
799811

800812
returnpathkeys;

‎src/backend/optimizer/plan/createplan.c

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
*
1111
*
1212
* IDENTIFICATION
13-
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.85 2000/02/15 20:49:18 tgl Exp $
13+
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.86 2000/02/18 23:47:21 tgl Exp $
1414
*
1515
*-------------------------------------------------------------------------
1616
*/
@@ -626,13 +626,14 @@ create_mergejoin_node(MergePath *best_path,
626626
*mergeclauses;
627627
MergeJoin*join_node;
628628

629+
mergeclauses=get_actual_clauses(best_path->path_mergeclauses);
630+
629631
/*
630632
* Remove the mergeclauses from the list of join qual clauses,
631633
* leaving the list of quals that must be checked as qpquals.
632634
* Set those clauses to contain INNER/OUTER var references.
633635
*/
634-
qpqual=join_references(set_difference(clauses,
635-
best_path->path_mergeclauses),
636+
qpqual=join_references(set_difference(clauses,mergeclauses),
636637
outer_tlist,
637638
inner_tlist,
638639
(Index)0);
@@ -641,7 +642,7 @@ create_mergejoin_node(MergePath *best_path,
641642
* Now set the references in the mergeclauses and rearrange them so
642643
* that the outer variable is always on the left.
643644
*/
644-
mergeclauses=switch_outer(join_references(best_path->path_mergeclauses,
645+
mergeclauses=switch_outer(join_references(mergeclauses,
645646
outer_tlist,
646647
inner_tlist,
647648
(Index)0));
@@ -692,14 +693,14 @@ create_hashjoin_node(HashPath *best_path,
692693
* We represent it as a list anyway, for convenience with routines
693694
* that want to work on lists of clauses.
694695
*/
696+
hashclauses=get_actual_clauses(best_path->path_hashclauses);
695697

696698
/*
697699
* Remove the hashclauses from the list of join qual clauses,
698700
* leaving the list of quals that must be checked as qpquals.
699701
* Set those clauses to contain INNER/OUTER var references.
700702
*/
701-
qpqual=join_references(set_difference(clauses,
702-
best_path->path_hashclauses),
703+
qpqual=join_references(set_difference(clauses,hashclauses),
703704
outer_tlist,
704705
inner_tlist,
705706
(Index)0);
@@ -708,7 +709,7 @@ create_hashjoin_node(HashPath *best_path,
708709
* Now set the references in the hashclauses and rearrange them so
709710
* that the outer variable is always on the left.
710711
*/
711-
hashclauses=switch_outer(join_references(best_path->path_hashclauses,
712+
hashclauses=switch_outer(join_references(hashclauses,
712713
outer_tlist,
713714
inner_tlist,
714715
(Index)0));

‎src/backend/optimizer/util/pathnode.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/optimizer/util/pathnode.c,v 1.60 2000/02/15 20:49:20 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/optimizer/util/pathnode.c,v 1.61 2000/02/18 23:47:30 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -416,7 +416,8 @@ create_nestloop_path(RelOptInfo *joinrel,
416416
* 'inner_path' is the inner path
417417
* 'restrict_clauses' are the RestrictInfo nodes to apply at the join
418418
* 'pathkeys' are the path keys of the new join path
419-
* 'mergeclauses' are the applicable join/restriction clauses
419+
* 'mergeclauses' are the RestrictInfo nodes to use as merge clauses
420+
*(this should be a subset of the restrict_clauses list)
420421
* 'outersortkeys' are the sort varkeys for the outer relation
421422
* 'innersortkeys' are the sort varkeys for the inner relation
422423
*
@@ -473,6 +474,7 @@ create_mergejoin_path(RelOptInfo *joinrel,
473474
* 'inner_path' is the cheapest inner path
474475
* 'restrict_clauses' are the RestrictInfo nodes to apply at the join
475476
* 'hashclauses' is a list of the hash join clause (always a 1-element list)
477+
*(this should be a subset of the restrict_clauses list)
476478
* 'innerdisbursion' is an estimate of the disbursion of the inner hash key
477479
*
478480
*/

‎src/backend/optimizer/util/relnode.c

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/optimizer/util/relnode.c,v 1.24 2000/02/15 20:49:21 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/optimizer/util/relnode.c,v 1.25 2000/02/18 23:47:31 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -345,11 +345,8 @@ subbuild_joinrel_restrictlist(RelOptInfo *joinrel,
345345
foreach(xjoininfo,joininfo_list)
346346
{
347347
JoinInfo*joininfo= (JoinInfo*)lfirst(xjoininfo);
348-
Relidsnew_unjoined_relids;
349348

350-
new_unjoined_relids=set_differencei(joininfo->unjoined_relids,
351-
joinrel->relids);
352-
if (new_unjoined_relids==NIL)
349+
if (is_subseti(joininfo->unjoined_relids,joinrel->relids))
353350
{
354351
/*
355352
* Clauses in this JoinInfo list become restriction clauses

‎src/include/nodes/relation.h

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $Id: relation.h,v 1.44 2000/02/15 20:49:25 tgl Exp $
10+
* $Id: relation.h,v 1.45 2000/02/18 23:47:17 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -237,6 +237,8 @@ typedef struct Path
237237
* are usable as indexquals (as determined by indxpath.c) may appear here.
238238
* NOTE that the semantics of the top-level list in 'indexqual' is OR
239239
* combination, while the sublists are implicitly AND combinations!
240+
* Also note that indexquals lists do not contain RestrictInfo nodes,
241+
* just bare clause expressions.
240242
*
241243
* 'indexscandir' is one of:
242244
*ForwardScanDirection: forward scan of an ordered index
@@ -293,32 +295,39 @@ typedef JoinPath NestPath;
293295
/*
294296
* A mergejoin path has these fields.
295297
*
298+
* path_mergeclauses lists the clauses (in the form of RestrictInfos)
299+
* that will be used in the merge. (Before 7.0, this was a list of
300+
* bare clause expressions, but we can save on list memory by leaving
301+
* it in the form of a RestrictInfo list.)
302+
*
296303
* Note that the mergeclauses are a subset of the parent relation's
297304
* restriction-clause list. Any join clauses that are not mergejoinable
298305
* appear only in the parent's restrict list, and must be checked by a
299306
* qpqual at execution time.
307+
*
308+
* outersortkeys (resp. innersortkeys) is NIL if the outer path
309+
* (resp. inner path) is already ordered appropriately for the
310+
* mergejoin. If it is not NIL then it is a PathKeys list describing
311+
* the ordering that must be created by an explicit sort step.
300312
*/
301313

302314
typedefstructMergePath
303315
{
304316
JoinPathjpath;
305-
List*path_mergeclauses;/* join clauses used for merge */
306-
/*
307-
* outersortkeys (resp. innersortkeys) is NIL if the outer path
308-
* (resp. inner path) is already ordered appropriately for the
309-
* mergejoin. If it is not NIL then it is a PathKeys list describing
310-
* the ordering that must be created by an explicit sort step.
311-
*/
312-
List*outersortkeys;
313-
List*innersortkeys;
317+
List*path_mergeclauses;/* join clauses to be used for merge */
318+
List*outersortkeys;/* keys for explicit sort, if any */
319+
List*innersortkeys;/* keys for explicit sort, if any */
314320
}MergePath;
315321

316322
/*
317323
* A hashjoin path has these fields.
318324
*
319325
* The remarks above for mergeclauses apply for hashclauses as well.
320-
* However, hashjoin does not care what order its inputs appear in,
321-
* so we have no need for sortkeys.
326+
* (But note that path_hashclauses will always be a one-element list,
327+
* since we only hash on one hashable clause.)
328+
*
329+
* Hashjoin does not care what order its inputs appear in, so we have
330+
* no need for sortkeys.
322331
*/
323332

324333
typedefstructHashPath

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp