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,
171171List * 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,
203207innerrel -> cheapest_total_path ,
204208restrictlist ,
205209merge_pathkeys ,
206- get_actual_clauses ( curclause_list ) ,
210+ curclause_list ,
207211outerkeys ,
208212innerkeys ));
209213}
@@ -265,6 +269,7 @@ match_unsorted_outer(Query *root,
265269List * trialsortkeys ;
266270Path * cheapest_startup_inner ;
267271Path * cheapest_total_inner ;
272+ int num_mergeclauses ;
268273int clausecnt ;
269274
270275/*
@@ -325,7 +330,7 @@ match_unsorted_outer(Query *root,
325330innerrel -> cheapest_total_path ,
326331restrictlist ,
327332merge_pathkeys ,
328- get_actual_clauses ( mergeclauses ) ,
333+ mergeclauses ,
329334NIL ,
330335innersortkeys ));
331336
@@ -337,10 +342,12 @@ match_unsorted_outer(Query *root,
337342trialsortkeys = listCopy (innersortkeys );/* modifiable copy */
338343cheapest_startup_inner = NULL ;
339344cheapest_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{
343349Path * 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,
356363TOTAL_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 ;
363371add_path (joinrel , (Path * )
364372create_mergejoin_path (joinrel ,
365373outerpath ,
@@ -383,10 +391,17 @@ match_unsorted_outer(Query *root,
383391/* Found a cheap (or even-cheaper) sorted path */
384392if (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+ }
390405add_path (joinrel , (Path * )
391406create_mergejoin_path (joinrel ,
392407outerpath ,
@@ -461,7 +476,7 @@ match_unsorted_inner(Query *root,
461476innerpath ,
462477restrictlist ,
463478merge_pathkeys ,
464- get_actual_clauses ( mergeclauses ) ,
479+ mergeclauses ,
465480outersortkeys ,
466481NIL ));
467482/*
@@ -487,7 +502,7 @@ match_unsorted_inner(Query *root,
487502innerpath ,
488503restrictlist ,
489504merge_pathkeys ,
490- get_actual_clauses ( mergeclauses ) ,
505+ mergeclauses ,
491506NIL ,
492507NIL ));
493508
@@ -505,7 +520,7 @@ match_unsorted_inner(Query *root,
505520innerpath ,
506521restrictlist ,
507522merge_pathkeys ,
508- get_actual_clauses ( mergeclauses ) ,
523+ mergeclauses ,
509524NIL ,
510525NIL ));
511526}
@@ -552,6 +567,7 @@ hash_inner_and_outer(Query *root,
552567Var * left ,
553568* right ,
554569* inner ;
570+ List * hashclauses ;
555571Selectivity innerdisbursion ;
556572
557573if (restrictinfo -> hashjoinoperator == InvalidOid )
@@ -572,6 +588,9 @@ hash_inner_and_outer(Query *root,
572588else
573589continue ;/* 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 */
576595innerdisbursion = estimate_disbursion (root ,inner );
577596
@@ -585,15 +604,15 @@ hash_inner_and_outer(Query *root,
585604outerrel -> cheapest_total_path ,
586605innerrel -> cheapest_total_path ,
587606restrictlist ,
588- lcons ( clause , NIL ) ,
607+ hashclauses ,
589608innerdisbursion ));
590609if (outerrel -> cheapest_startup_path != outerrel -> cheapest_total_path )
591610add_path (joinrel , (Path * )
592611create_hashjoin_path (joinrel ,
593612outerrel -> cheapest_startup_path ,
594613innerrel -> cheapest_total_path ,
595614restrictlist ,
596- lcons ( clause , NIL ) ,
615+ hashclauses ,
597616innerdisbursion ));
598617}
599618}