8
8
*
9
9
*
10
10
* 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 $
12
12
*
13
13
*-------------------------------------------------------------------------
14
14
*/
@@ -171,9 +171,13 @@ sort_inner_and_outer(Query *root,
171
171
List * merge_pathkeys ;
172
172
173
173
/* 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
+
177
181
/* Build sort pathkeys for both sides.
178
182
*
179
183
* Note: it's possible that the cheapest paths will already be
@@ -203,7 +207,7 @@ sort_inner_and_outer(Query *root,
203
207
innerrel -> cheapest_total_path ,
204
208
restrictlist ,
205
209
merge_pathkeys ,
206
- get_actual_clauses ( curclause_list ) ,
210
+ curclause_list ,
207
211
outerkeys ,
208
212
innerkeys ));
209
213
}
@@ -265,6 +269,7 @@ match_unsorted_outer(Query *root,
265
269
List * trialsortkeys ;
266
270
Path * cheapest_startup_inner ;
267
271
Path * cheapest_total_inner ;
272
+ int num_mergeclauses ;
268
273
int clausecnt ;
269
274
270
275
/*
@@ -325,7 +330,7 @@ match_unsorted_outer(Query *root,
325
330
innerrel -> cheapest_total_path ,
326
331
restrictlist ,
327
332
merge_pathkeys ,
328
- get_actual_clauses ( mergeclauses ) ,
333
+ mergeclauses ,
329
334
NIL ,
330
335
innersortkeys ));
331
336
@@ -337,10 +342,12 @@ match_unsorted_outer(Query *root,
337
342
trialsortkeys = listCopy (innersortkeys ); /* modifiable copy */
338
343
cheapest_startup_inner = NULL ;
339
344
cheapest_total_inner = NULL ;
345
+ num_mergeclauses = length (mergeclauses );
340
346
341
- for (clausecnt = length ( mergeclauses ) ; clausecnt > 0 ; clausecnt -- )
347
+ for (clausecnt = num_mergeclauses ; clausecnt > 0 ; clausecnt -- )
342
348
{
343
349
Path * innerpath ;
350
+ List * newclauses = NIL ;
344
351
345
352
/* Look for an inner path ordered well enough to merge with
346
353
* the first 'clausecnt' mergeclauses. NB: trialsortkeys list
@@ -356,10 +363,11 @@ match_unsorted_outer(Query *root,
356
363
TOTAL_COST ) < 0 ))
357
364
{
358
365
/* 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 ;
363
371
add_path (joinrel , (Path * )
364
372
create_mergejoin_path (joinrel ,
365
373
outerpath ,
@@ -383,10 +391,17 @@ match_unsorted_outer(Query *root,
383
391
/* Found a cheap (or even-cheaper) sorted path */
384
392
if (innerpath != cheapest_total_inner )
385
393
{
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
+ }
390
405
add_path (joinrel , (Path * )
391
406
create_mergejoin_path (joinrel ,
392
407
outerpath ,
@@ -461,7 +476,7 @@ match_unsorted_inner(Query *root,
461
476
innerpath ,
462
477
restrictlist ,
463
478
merge_pathkeys ,
464
- get_actual_clauses ( mergeclauses ) ,
479
+ mergeclauses ,
465
480
outersortkeys ,
466
481
NIL ));
467
482
/*
@@ -487,7 +502,7 @@ match_unsorted_inner(Query *root,
487
502
innerpath ,
488
503
restrictlist ,
489
504
merge_pathkeys ,
490
- get_actual_clauses ( mergeclauses ) ,
505
+ mergeclauses ,
491
506
NIL ,
492
507
NIL ));
493
508
@@ -505,7 +520,7 @@ match_unsorted_inner(Query *root,
505
520
innerpath ,
506
521
restrictlist ,
507
522
merge_pathkeys ,
508
- get_actual_clauses ( mergeclauses ) ,
523
+ mergeclauses ,
509
524
NIL ,
510
525
NIL ));
511
526
}
@@ -552,6 +567,7 @@ hash_inner_and_outer(Query *root,
552
567
Var * left ,
553
568
* right ,
554
569
* inner ;
570
+ List * hashclauses ;
555
571
Selectivity innerdisbursion ;
556
572
557
573
if (restrictinfo -> hashjoinoperator == InvalidOid )
@@ -572,6 +588,9 @@ hash_inner_and_outer(Query *root,
572
588
else
573
589
continue ; /* no good for these input relations */
574
590
591
+ /* always a one-element list of hash clauses */
592
+ hashclauses = lcons (restrictinfo , NIL );
593
+
575
594
/* estimate disbursion of inner var for costing purposes */
576
595
innerdisbursion = estimate_disbursion (root , inner );
577
596
@@ -585,15 +604,15 @@ hash_inner_and_outer(Query *root,
585
604
outerrel -> cheapest_total_path ,
586
605
innerrel -> cheapest_total_path ,
587
606
restrictlist ,
588
- lcons ( clause , NIL ) ,
607
+ hashclauses ,
589
608
innerdisbursion ));
590
609
if (outerrel -> cheapest_startup_path != outerrel -> cheapest_total_path )
591
610
add_path (joinrel , (Path * )
592
611
create_hashjoin_path (joinrel ,
593
612
outerrel -> cheapest_startup_path ,
594
613
innerrel -> cheapest_total_path ,
595
614
restrictlist ,
596
- lcons ( clause , NIL ) ,
615
+ hashclauses ,
597
616
innerdisbursion ));
598
617
}
599
618
}
0 commit comments