88 *
99 *
1010 * IDENTIFICATION
11- * $PostgreSQL: pgsql/src/backend/optimizer/plan/initsplan.c,v 1.132 2007/05/22 23:23:56 tgl Exp $
11+ * $PostgreSQL: pgsql/src/backend/optimizer/plan/initsplan.c,v 1.133 2007/08/31 01:44:05 tgl Exp $
1212 *
1313 *-------------------------------------------------------------------------
1414 */
@@ -38,9 +38,11 @@ intjoin_collapse_limit;
3838
3939
4040static List * deconstruct_recurse (PlannerInfo * root ,Node * jtnode ,
41- bool below_outer_join ,Relids * qualscope );
41+ bool below_outer_join ,
42+ Relids * qualscope ,Relids * inner_join_rels );
4243static OuterJoinInfo * make_outerjoininfo (PlannerInfo * root ,
4344Relids left_rels ,Relids right_rels ,
45+ Relids inner_join_rels ,
4446bool is_full_join ,Node * clause );
4547static void distribute_qual_to_rels (PlannerInfo * root ,Node * clause ,
4648bool is_deduced ,
@@ -204,13 +206,14 @@ List *
204206deconstruct_jointree (PlannerInfo * root )
205207{
206208Relids qualscope ;
209+ Relids inner_join_rels ;
207210
208211/* Start recursion at top of jointree */
209212Assert (root -> parse -> jointree != NULL &&
210213IsA (root -> parse -> jointree ,FromExpr ));
211214
212215return deconstruct_recurse (root , (Node * )root -> parse -> jointree , false,
213- & qualscope );
216+ & qualscope , & inner_join_rels );
214217}
215218
216219/*
@@ -224,20 +227,24 @@ deconstruct_jointree(PlannerInfo *root)
224227 * Outputs:
225228 **qualscope gets the set of base Relids syntactically included in this
226229 *jointree node (do not modify or free this, as it may also be pointed
227- *to by RestrictInfo nodes)
230+ *to by RestrictInfo and OuterJoinInfo nodes)
231+ **inner_join_rels gets the set of base Relids syntactically included in
232+ *inner joins appearing at or below this jointree node (do not modify
233+ *or free this, either)
228234 *Return value is the appropriate joinlist for this jointree node
229235 *
230236 * In addition, entries will be added to root->oj_info_list for outer joins.
231237 */
232238static List *
233239deconstruct_recurse (PlannerInfo * root ,Node * jtnode ,bool below_outer_join ,
234- Relids * qualscope )
240+ Relids * qualscope , Relids * inner_join_rels )
235241{
236242List * joinlist ;
237243
238244if (jtnode == NULL )
239245{
240246* qualscope = NULL ;
247+ * inner_join_rels = NULL ;
241248return NIL ;
242249}
243250if (IsA (jtnode ,RangeTblRef ))
@@ -246,6 +253,8 @@ deconstruct_recurse(PlannerInfo *root, Node *jtnode, bool below_outer_join,
246253
247254/* No quals to deal with, just return correct result */
248255* qualscope = bms_make_singleton (varno );
256+ /* A single baserel does not create an inner join */
257+ * inner_join_rels = NULL ;
249258joinlist = list_make1 (jtnode );
250259}
251260else if (IsA (jtnode ,FromExpr ))
@@ -261,6 +270,7 @@ deconstruct_recurse(PlannerInfo *root, Node *jtnode, bool below_outer_join,
261270 * subproblems, since that won't lengthen the joinlist anyway.
262271 */
263272* qualscope = NULL ;
273+ * inner_join_rels = NULL ;
264274joinlist = NIL ;
265275remaining = list_length (f -> fromlist );
266276foreach (l ,f -> fromlist )
@@ -271,7 +281,8 @@ deconstruct_recurse(PlannerInfo *root, Node *jtnode, bool below_outer_join,
271281
272282sub_joinlist = deconstruct_recurse (root ,lfirst (l ),
273283below_outer_join ,
274- & sub_qualscope );
284+ & sub_qualscope ,
285+ inner_join_rels );
275286* qualscope = bms_add_members (* qualscope ,sub_qualscope );
276287sub_members = list_length (sub_joinlist );
277288remaining -- ;
@@ -282,6 +293,16 @@ deconstruct_recurse(PlannerInfo *root, Node *jtnode, bool below_outer_join,
282293joinlist = lappend (joinlist ,sub_joinlist );
283294}
284295
296+ /*
297+ * A FROM with more than one list element is an inner join subsuming
298+ * all below it, so we should report inner_join_rels = qualscope.
299+ * If there was exactly one element, we should (and already did) report
300+ * whatever its inner_join_rels were. If there were no elements
301+ * (is that possible?) the initialization before the loop fixed it.
302+ */
303+ if (list_length (f -> fromlist )> 1 )
304+ * inner_join_rels = * qualscope ;
305+
285306/*
286307 * Now process the top-level quals.
287308 */
@@ -295,6 +316,8 @@ deconstruct_recurse(PlannerInfo *root, Node *jtnode, bool below_outer_join,
295316JoinExpr * j = (JoinExpr * )jtnode ;
296317Relids leftids ,
297318rightids ,
319+ left_inners ,
320+ right_inners ,
298321nonnullable_rels ,
299322ojscope ;
300323List * leftjoinlist ,
@@ -319,44 +342,48 @@ deconstruct_recurse(PlannerInfo *root, Node *jtnode, bool below_outer_join,
319342case JOIN_INNER :
320343leftjoinlist = deconstruct_recurse (root ,j -> larg ,
321344below_outer_join ,
322- & leftids );
345+ & leftids , & left_inners );
323346rightjoinlist = deconstruct_recurse (root ,j -> rarg ,
324347below_outer_join ,
325- & rightids );
348+ & rightids , & right_inners );
326349* qualscope = bms_union (leftids ,rightids );
350+ * inner_join_rels = * qualscope ;
327351/* Inner join adds no restrictions for quals */
328352nonnullable_rels = NULL ;
329353break ;
330354case JOIN_LEFT :
331355leftjoinlist = deconstruct_recurse (root ,j -> larg ,
332356below_outer_join ,
333- & leftids );
357+ & leftids , & left_inners );
334358rightjoinlist = deconstruct_recurse (root ,j -> rarg ,
335359true,
336- & rightids );
360+ & rightids , & right_inners );
337361* qualscope = bms_union (leftids ,rightids );
362+ * inner_join_rels = bms_union (left_inners ,right_inners );
338363nonnullable_rels = leftids ;
339364break ;
340365case JOIN_FULL :
341366leftjoinlist = deconstruct_recurse (root ,j -> larg ,
342367 true,
343- & leftids );
368+ & leftids , & left_inners );
344369rightjoinlist = deconstruct_recurse (root ,j -> rarg ,
345370true,
346- & rightids );
371+ & rightids , & right_inners );
347372* qualscope = bms_union (leftids ,rightids );
373+ * inner_join_rels = bms_union (left_inners ,right_inners );
348374/* each side is both outer and inner */
349375nonnullable_rels = * qualscope ;
350376break ;
351377case JOIN_RIGHT :
352378/* notice we switch leftids and rightids */
353379leftjoinlist = deconstruct_recurse (root ,j -> larg ,
354380 true,
355- & rightids );
381+ & rightids , & right_inners );
356382rightjoinlist = deconstruct_recurse (root ,j -> rarg ,
357383below_outer_join ,
358- & leftids );
384+ & leftids , & left_inners );
359385* qualscope = bms_union (leftids ,rightids );
386+ * inner_join_rels = bms_union (left_inners ,right_inners );
360387nonnullable_rels = leftids ;
361388break ;
362389default :
@@ -375,8 +402,11 @@ deconstruct_recurse(PlannerInfo *root, Node *jtnode, bool below_outer_join,
375402 */
376403if (j -> jointype != JOIN_INNER )
377404{
378- ojinfo = make_outerjoininfo (root ,leftids ,rightids ,
379- (j -> jointype == JOIN_FULL ),j -> quals );
405+ ojinfo = make_outerjoininfo (root ,
406+ leftids ,rightids ,
407+ * inner_join_rels ,
408+ (j -> jointype == JOIN_FULL ),
409+ j -> quals );
380410ojscope = bms_union (ojinfo -> min_lefthand ,ojinfo -> min_righthand );
381411}
382412else
@@ -445,6 +475,7 @@ deconstruct_recurse(PlannerInfo *root, Node *jtnode, bool below_outer_join,
445475 * Inputs:
446476 *left_rels: the base Relids syntactically on outer side of join
447477 *right_rels: the base Relids syntactically on inner side of join
478+ *inner_join_rels: base Relids participating in inner joins below this one
448479 *is_full_join: what it says
449480 *clause: the outer join's join condition
450481 *
@@ -457,17 +488,19 @@ deconstruct_recurse(PlannerInfo *root, Node *jtnode, bool below_outer_join,
457488 *
458489 * Note: we assume that this function is invoked bottom-up, so that
459490 * root->oj_info_list already contains entries for all outer joins that are
460- * syntactically below this one; and indeed that oj_info_list is ordered
461- * with syntactically lower joins listed first.
491+ * syntactically below this one.
462492 */
463493static OuterJoinInfo *
464494make_outerjoininfo (PlannerInfo * root ,
465495Relids left_rels ,Relids right_rels ,
496+ Relids inner_join_rels ,
466497bool is_full_join ,Node * clause )
467498{
468499OuterJoinInfo * ojinfo = makeNode (OuterJoinInfo );
469500Relids clause_relids ;
470501Relids strict_relids ;
502+ Relids min_lefthand ;
503+ Relids min_righthand ;
471504ListCell * l ;
472505
473506/*
@@ -497,6 +530,8 @@ make_outerjoininfo(PlannerInfo *root,
497530ojinfo -> delay_upper_joins = false;
498531
499532/* If it's a full join, no need to be very smart */
533+ ojinfo -> syn_lefthand = left_rels ;
534+ ojinfo -> syn_righthand = right_rels ;
500535ojinfo -> is_full_join = is_full_join ;
501536if (is_full_join )
502537{
@@ -521,21 +556,17 @@ make_outerjoininfo(PlannerInfo *root,
521556ojinfo -> lhs_strict = bms_overlap (strict_relids ,left_rels );
522557
523558/*
524- * Required LHS is basically the LHS rels mentioned in the clause... but
525- * if there aren't any, punt and make it the full LHS, to avoid having an
526- * empty min_lefthand which will confuse later processing. (We don't try
527- * to be smart about such cases, just correct.) We may have to add more
528- * rels based on lower outer joins; see below.
559+ * Required LHS always includes the LHS rels mentioned in the clause.
560+ * We may have to add more rels based on lower outer joins; see below.
529561 */
530- ojinfo -> min_lefthand = bms_intersect (clause_relids ,left_rels );
531- if (bms_is_empty (ojinfo -> min_lefthand ))
532- ojinfo -> min_lefthand = bms_copy (left_rels );
562+ min_lefthand = bms_intersect (clause_relids ,left_rels );
533563
534564/*
535- *Required RHS is normally the full set of RHS rels. Sometimes we can
536- *exclude some, see below .
565+ *Similarly for required RHS. But here, we must also include any lower
566+ *inner joins, to ensure we don't try to commute with any of them .
537567 */
538- ojinfo -> min_righthand = bms_copy (right_rels );
568+ min_righthand = bms_int_members (bms_union (clause_relids ,inner_join_rels ),
569+ right_rels );
539570
540571foreach (l ,root -> oj_info_list )
541572{
@@ -548,23 +579,29 @@ make_outerjoininfo(PlannerInfo *root,
548579/*
549580 * For a lower OJ in our LHS, if our join condition uses the lower
550581 * join's RHS and is not strict for that rel, we must preserve the
551- * ordering of the two OJs, so add lower OJ's full required relset to
552- * min_lefthand.
582+ * ordering of the two OJs, so add lower OJ's full syntactic relset to
583+ * min_lefthand. (We must use its full syntactic relset, not just
584+ * its min_lefthand + min_righthand. This is because there might
585+ * be other OJs below this one that this one can commute with,
586+ * but we cannot commute with them if we don't with this one.)
587+ *
588+ * Note: I believe we have to insist on being strict for at least one
589+ * rel in the lower OJ's min_righthand, not its whole syn_righthand.
553590 */
554- if (bms_overlap (ojinfo -> min_lefthand ,otherinfo -> min_righthand )&&
591+ if (bms_overlap (left_rels ,otherinfo -> syn_righthand )&&
555592!bms_overlap (strict_relids ,otherinfo -> min_righthand ))
556593{
557- ojinfo -> min_lefthand = bms_add_members (ojinfo -> min_lefthand ,
558- otherinfo -> min_lefthand );
559- ojinfo -> min_lefthand = bms_add_members (ojinfo -> min_lefthand ,
560- otherinfo -> min_righthand );
594+ min_lefthand = bms_add_members (min_lefthand ,
595+ otherinfo -> syn_lefthand );
596+ min_lefthand = bms_add_members (min_lefthand ,
597+ otherinfo -> syn_righthand );
561598}
562599
563600/*
564601 * For a lower OJ in our RHS, if our join condition does not use the
565602 * lower join's RHS and the lower OJ's join condition is strict, we
566- * can interchange the ordering of the two OJs, so exclude the lower
567- *RHS from our min_righthand.
603+ * can interchange the ordering of the two OJs; otherwise we must
604+ *add lower OJ's full syntactic relset to min_righthand.
568605 *
569606 * Here, we have to consider that "our join condition" includes
570607 * any clauses that syntactically appeared above the lower OJ and
@@ -577,20 +614,38 @@ make_outerjoininfo(PlannerInfo *root,
577614 * effect is therefore sufficiently represented by the
578615 * delay_upper_joins flag saved for us by check_outerjoin_delay.
579616 */
580- if (bms_overlap (ojinfo -> min_righthand ,otherinfo -> min_righthand )&&
581- !bms_overlap (clause_relids ,otherinfo -> min_righthand )&&
582- otherinfo -> lhs_strict && !otherinfo -> delay_upper_joins )
617+ if (bms_overlap (right_rels ,otherinfo -> syn_righthand ))
583618{
584- ojinfo -> min_righthand = bms_del_members (ojinfo -> min_righthand ,
585- otherinfo -> min_righthand );
619+ if (bms_overlap (clause_relids ,otherinfo -> syn_righthand )||
620+ !otherinfo -> lhs_strict || otherinfo -> delay_upper_joins )
621+ {
622+ min_righthand = bms_add_members (min_righthand ,
623+ otherinfo -> syn_lefthand );
624+ min_righthand = bms_add_members (min_righthand ,
625+ otherinfo -> syn_righthand );
626+ }
586627}
587628}
588629
589- /* Neither set should be empty, else we might get confused later */
590- Assert (!bms_is_empty (ojinfo -> min_lefthand ));
591- Assert (!bms_is_empty (ojinfo -> min_righthand ));
630+ /*
631+ * If we found nothing to put in min_lefthand, punt and make it the full
632+ * LHS, to avoid having an empty min_lefthand which will confuse later
633+ * processing. (We don't try to be smart about such cases, just correct.)
634+ * Likewise for min_righthand.
635+ */
636+ if (bms_is_empty (min_lefthand ))
637+ min_lefthand = bms_copy (left_rels );
638+ if (bms_is_empty (min_righthand ))
639+ min_righthand = bms_copy (right_rels );
640+
641+ /* Now they'd better be nonempty */
642+ Assert (!bms_is_empty (min_lefthand ));
643+ Assert (!bms_is_empty (min_righthand ));
592644/* Shouldn't overlap either */
593- Assert (!bms_overlap (ojinfo -> min_lefthand ,ojinfo -> min_righthand ));
645+ Assert (!bms_overlap (min_lefthand ,min_righthand ));
646+
647+ ojinfo -> min_lefthand = min_lefthand ;
648+ ojinfo -> min_righthand = min_righthand ;
594649
595650return ojinfo ;
596651}