diff options
Diffstat (limited to 'src/backend')
-rw-r--r-- | src/backend/nodes/copyfuncs.c | 3 | ||||
-rw-r--r-- | src/backend/nodes/equalfuncs.c | 3 | ||||
-rw-r--r-- | src/backend/nodes/outfuncs.c | 3 | ||||
-rw-r--r-- | src/backend/optimizer/plan/initsplan.c | 22 |
4 files changed, 26 insertions, 5 deletions
diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c index c1858e6746d..a9cb0416c34 100644 --- a/src/backend/nodes/copyfuncs.c +++ b/src/backend/nodes/copyfuncs.c @@ -15,7 +15,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.353 2006/11/05 22:42:08 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.353.2.1 2007/05/22 23:24:08 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -1318,6 +1318,7 @@ _copyOuterJoinInfo(OuterJoinInfo *from) COPY_BITMAPSET_FIELD(min_righthand); COPY_SCALAR_FIELD(is_full_join); COPY_SCALAR_FIELD(lhs_strict); + COPY_SCALAR_FIELD(delay_upper_joins); return newnode; } diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c index a42afb77a3d..13be0e0f9c8 100644 --- a/src/backend/nodes/equalfuncs.c +++ b/src/backend/nodes/equalfuncs.c @@ -18,7 +18,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.287 2006/11/05 22:42:08 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.287.2.1 2007/05/22 23:24:08 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -614,6 +614,7 @@ _equalOuterJoinInfo(OuterJoinInfo *a, OuterJoinInfo *b) COMPARE_BITMAPSET_FIELD(min_righthand); COMPARE_SCALAR_FIELD(is_full_join); COMPARE_SCALAR_FIELD(lhs_strict); + COMPARE_SCALAR_FIELD(delay_upper_joins); return true; } diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c index fdcc2cdc5f6..f80a333b7e2 100644 --- a/src/backend/nodes/outfuncs.c +++ b/src/backend/nodes/outfuncs.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.285.2.1 2007/05/22 01:40:42 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.285.2.2 2007/05/22 23:24:08 tgl Exp $ * * NOTES * Every node type that can appear in stored rules' parsetrees *must* @@ -1293,6 +1293,7 @@ _outOuterJoinInfo(StringInfo str, OuterJoinInfo *node) WRITE_BITMAPSET_FIELD(min_righthand); WRITE_BOOL_FIELD(is_full_join); WRITE_BOOL_FIELD(lhs_strict); + WRITE_BOOL_FIELD(delay_upper_joins); } static void diff --git a/src/backend/optimizer/plan/initsplan.c b/src/backend/optimizer/plan/initsplan.c index ef131fba0ee..0b315f2cd7d 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.123.2.4 2007/02/16 20:57:26 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/optimizer/plan/initsplan.c,v 1.123.2.5 2007/05/22 23:24:08 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -495,6 +495,9 @@ make_outerjoininfo(PlannerInfo *root, errmsg("SELECT FOR UPDATE/SHARE cannot be applied to the nullable side of an outer join"))); } + /* this always starts out false */ + ojinfo->delay_upper_joins = false; + /* If it's a full join, no need to be very smart */ ojinfo->is_full_join = is_full_join; if (is_full_join) @@ -564,10 +567,21 @@ make_outerjoininfo(PlannerInfo *root, * lower join's RHS and the lower OJ's join condition is strict, we * can interchange the ordering of the two OJs, so exclude the lower * RHS from our min_righthand. + * + * Here, we have to consider that "our join condition" includes + * any clauses that syntactically appeared above the lower OJ and + * below ours; those are equivalent to degenerate clauses in our + * OJ and must be treated as such. Such clauses obviously can't + * reference our LHS, and they must be non-strict for the lower OJ's + * RHS (else reduce_outer_joins would have reduced the lower OJ to + * a plain join). Hence the other ways in which we handle clauses + * within our join condition are not affected by them. The net + * effect is therefore sufficiently represented by the + * delay_upper_joins flag saved for us by distribute_qual_to_rels. */ if (bms_overlap(ojinfo->min_righthand, otherinfo->min_righthand) && !bms_overlap(clause_relids, otherinfo->min_righthand) && - otherinfo->lhs_strict) + otherinfo->lhs_strict && !otherinfo->delay_upper_joins) { ojinfo->min_righthand = bms_del_members(ojinfo->min_righthand, otherinfo->min_righthand); @@ -829,6 +843,10 @@ distribute_qual_to_rels(PlannerInfo *root, Node *clause, /* we'll need another iteration */ found_some = true; } + /* set delay_upper_joins if needed */ + if (!ojinfo->is_full_join && + bms_overlap(relids, ojinfo->min_lefthand)) + ojinfo->delay_upper_joins = true; } } } while (found_some); |