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+ int num_mergeclauses ;
268273 int clausecnt ;
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 Selectivity innerdisbursion ;
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}
0 commit comments