88 *
99 *
1010 * IDENTIFICATION
11- * $PostgreSQL: pgsql/src/backend/optimizer/plan/initsplan.c,v 1.143 2008/10/21 20:42:53 tgl Exp $
11+ * $PostgreSQL: pgsql/src/backend/optimizer/plan/initsplan.c,v 1.144 2008/10/25 19:51:32 tgl Exp $
1212 *
1313 *-------------------------------------------------------------------------
1414 */
@@ -48,6 +48,7 @@ static SpecialJoinInfo *make_outerjoininfo(PlannerInfo *root,
4848static void distribute_qual_to_rels (PlannerInfo * root ,Node * clause ,
4949bool is_deduced ,
5050bool below_outer_join ,
51+ JoinType jointype ,
5152Relids qualscope ,
5253Relids ojscope ,
5354Relids outerjoin_nonnullable );
@@ -342,7 +343,7 @@ deconstruct_recurse(PlannerInfo *root, Node *jtnode, bool below_outer_join,
342343below_outer_join );
343344else
344345distribute_qual_to_rels (root ,qual ,
345- false,below_outer_join ,
346+ false,below_outer_join ,JOIN_INNER ,
346347* qualscope ,NULL ,NULL );
347348}
348349}
@@ -452,7 +453,7 @@ deconstruct_recurse(PlannerInfo *root, Node *jtnode, bool below_outer_join,
452453below_outer_join );
453454else
454455distribute_qual_to_rels (root ,qual ,
455- false,below_outer_join ,
456+ false,below_outer_join ,j -> jointype ,
456457* qualscope ,
457458ojscope ,nonnullable_rels );
458459}
@@ -712,6 +713,7 @@ make_outerjoininfo(PlannerInfo *root,
712713 * 'is_deduced': TRUE if the qual came from implied-equality deduction
713714 * 'below_outer_join': TRUE if the qual is from a JOIN/ON that is below the
714715 *nullable side of a higher-level outer join
716+ * 'jointype': type of join the qual is from (JOIN_INNER for a WHERE clause)
715717 * 'qualscope': set of baserels the qual's syntactic scope covers
716718 * 'ojscope': NULL if not an outer-join qual, else the minimum set of baserels
717719 *needed to form this join
@@ -728,6 +730,7 @@ static void
728730distribute_qual_to_rels (PlannerInfo * root ,Node * clause ,
729731bool is_deduced ,
730732bool below_outer_join ,
733+ JoinType jointype ,
731734Relids qualscope ,
732735Relids ojscope ,
733736Relids outerjoin_nonnullable )
@@ -848,11 +851,16 @@ distribute_qual_to_rels(PlannerInfo *root, Node *clause,
848851maybe_equivalence = false;
849852maybe_outer_join = false;
850853}
851- else if (bms_overlap (relids ,outerjoin_nonnullable ))
854+ else if (bms_overlap (relids ,outerjoin_nonnullable )&&
855+ (jointype != JOIN_SEMI ||
856+ bms_nonempty_difference (relids ,outerjoin_nonnullable )))
852857{
853858/*
854859 * The qual is attached to an outer join and mentions (some of the)
855- * rels on the nonnullable side, so it's not degenerate.
860+ * rels on the nonnullable side, so it's not degenerate. (For a
861+ * JOIN_SEMI qual, we consider it non-degenerate only if it mentions
862+ * both sides of the join --- if it mentions only one side, it can
863+ * be pushed down.)
856864 *
857865 * We can't use such a clause to deduce equivalence (the left and
858866 * right sides might be unequal above the join because one of them has
@@ -1024,7 +1032,7 @@ distribute_qual_to_rels(PlannerInfo *root, Node *clause,
10241032restrictinfo );
10251033return ;
10261034}
1027- if (bms_equal ( outerjoin_nonnullable , qualscope ) )
1035+ if (jointype == JOIN_FULL )
10281036{
10291037/* FULL JOIN (above tests cannot match in this case) */
10301038root -> full_join_clauses = lappend (root -> full_join_clauses ,
@@ -1077,9 +1085,8 @@ distribute_sublink_quals_to_rels(PlannerInfo *root,
10771085Node * qual = (Node * )lfirst (l );
10781086
10791087distribute_qual_to_rels (root ,qual ,
1080- false,below_outer_join ,
1081- qualscope ,ojscope ,
1082- fslink -> lefthand );
1088+ false,below_outer_join ,fslink -> jointype ,
1089+ qualscope ,ojscope ,fslink -> lefthand );
10831090}
10841091
10851092/* Now we can add the SpecialJoinInfo to join_info_list */
@@ -1373,7 +1380,7 @@ process_implied_equality(PlannerInfo *root,
13731380 * Push the new clause into all the appropriate restrictinfo lists.
13741381 */
13751382distribute_qual_to_rels (root , (Node * )clause ,
1376- true,below_outer_join ,
1383+ true,below_outer_join ,JOIN_INNER ,
13771384qualscope ,NULL ,NULL );
13781385}
13791386