diff options
Diffstat (limited to 'src/backend/optimizer/plan/initsplan.c')
-rw-r--r-- | src/backend/optimizer/plan/initsplan.c | 28 |
1 files changed, 17 insertions, 11 deletions
diff --git a/src/backend/optimizer/plan/initsplan.c b/src/backend/optimizer/plan/initsplan.c index d1b590d0631..1764656da38 100644 --- a/src/backend/optimizer/plan/initsplan.c +++ b/src/backend/optimizer/plan/initsplan.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/optimizer/plan/initsplan.c,v 1.144 2008/10/25 19:51:32 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/optimizer/plan/initsplan.c,v 1.145 2008/11/22 22:47:06 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -851,16 +851,11 @@ distribute_qual_to_rels(PlannerInfo *root, Node *clause, maybe_equivalence = false; maybe_outer_join = false; } - else if (bms_overlap(relids, outerjoin_nonnullable) && - (jointype != JOIN_SEMI || - bms_nonempty_difference(relids, outerjoin_nonnullable))) + else if (bms_overlap(relids, outerjoin_nonnullable)) { /* * The qual is attached to an outer join and mentions (some of the) - * rels on the nonnullable side, so it's not degenerate. (For a - * JOIN_SEMI qual, we consider it non-degenerate only if it mentions - * both sides of the join --- if it mentions only one side, it can - * be pushed down.) + * rels on the nonnullable side, so it's not degenerate. * * We can't use such a clause to deduce equivalence (the left and * right sides might be unequal above the join because one of them has @@ -1062,6 +1057,7 @@ distribute_sublink_quals_to_rels(PlannerInfo *root, SpecialJoinInfo *sjinfo; Relids qualscope; Relids ojscope; + Relids outerjoin_nonnullable; ListCell *l; /* @@ -1076,17 +1072,27 @@ distribute_sublink_quals_to_rels(PlannerInfo *root, fslink->jointype, quals); + /* Treat as inner join if SEMI, outer join if ANTI */ qualscope = bms_union(sjinfo->syn_lefthand, sjinfo->syn_righthand); - ojscope = bms_union(sjinfo->min_lefthand, sjinfo->min_righthand); + if (fslink->jointype == JOIN_SEMI) + { + ojscope = outerjoin_nonnullable = NULL; + } + else + { + Assert(fslink->jointype == JOIN_ANTI); + ojscope = bms_union(sjinfo->min_lefthand, sjinfo->min_righthand); + outerjoin_nonnullable = fslink->lefthand; + } - /* Distribute the join quals much as for a regular LEFT JOIN */ + /* Distribute the join quals much as for a regular JOIN node */ foreach(l, quals) { Node *qual = (Node *) lfirst(l); distribute_qual_to_rels(root, qual, false, below_outer_join, fslink->jointype, - qualscope, ojscope, fslink->lefthand); + qualscope, ojscope, outerjoin_nonnullable); } /* Now we can add the SpecialJoinInfo to join_info_list */ |