*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/optimizer/plan/initsplan.c,v 1.143 2008/10/21 20:42:53 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/optimizer/plan/initsplan.c,v 1.144 2008/10/25 19:51:32 tgl Exp $
*
*-------------------------------------------------------------------------
*/
static void distribute_qual_to_rels(PlannerInfo *root, Node *clause,
bool is_deduced,
bool below_outer_join,
+ JoinType jointype,
Relids qualscope,
Relids ojscope,
Relids outerjoin_nonnullable);
below_outer_join);
else
distribute_qual_to_rels(root, qual,
- false, below_outer_join,
+ false, below_outer_join, JOIN_INNER,
*qualscope, NULL, NULL);
}
}
below_outer_join);
else
distribute_qual_to_rels(root, qual,
- false, below_outer_join,
+ false, below_outer_join, j->jointype,
*qualscope,
ojscope, nonnullable_rels);
}
* 'is_deduced': TRUE if the qual came from implied-equality deduction
* 'below_outer_join': TRUE if the qual is from a JOIN/ON that is below the
* nullable side of a higher-level outer join
+ * 'jointype': type of join the qual is from (JOIN_INNER for a WHERE clause)
* 'qualscope': set of baserels the qual's syntactic scope covers
* 'ojscope': NULL if not an outer-join qual, else the minimum set of baserels
* needed to form this join
distribute_qual_to_rels(PlannerInfo *root, Node *clause,
bool is_deduced,
bool below_outer_join,
+ JoinType jointype,
Relids qualscope,
Relids ojscope,
Relids outerjoin_nonnullable)
maybe_equivalence = false;
maybe_outer_join = false;
}
- else if (bms_overlap(relids, outerjoin_nonnullable))
+ else if (bms_overlap(relids, outerjoin_nonnullable) &&
+ (jointype != JOIN_SEMI ||
+ bms_nonempty_difference(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.
+ * 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.)
*
* 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
restrictinfo);
return;
}
- if (bms_equal(outerjoin_nonnullable, qualscope))
+ if (jointype == JOIN_FULL)
{
/* FULL JOIN (above tests cannot match in this case) */
root->full_join_clauses = lappend(root->full_join_clauses,
Node *qual = (Node *) lfirst(l);
distribute_qual_to_rels(root, qual,
- false, below_outer_join,
- qualscope, ojscope,
- fslink->lefthand);
+ false, below_outer_join, fslink->jointype,
+ qualscope, ojscope, fslink->lefthand);
}
/* Now we can add the SpecialJoinInfo to join_info_list */
* Push the new clause into all the appropriate restrictinfo lists.
*/
distribute_qual_to_rels(root, (Node *) clause,
- true, below_outer_join,
+ true, below_outer_join, JOIN_INNER,
qualscope, NULL, NULL);
}