]> granicus.if.org Git - postgresql/commit
Rewrite make_outerjoininfo's construction of min_lefthand and min_righthand
authorTom Lane <tgl@sss.pgh.pa.us>
Fri, 31 Aug 2007 01:44:14 +0000 (01:44 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Fri, 31 Aug 2007 01:44:14 +0000 (01:44 +0000)
commite257e6095fac2eebdb1cc5d6c29968486b2b8c56
tree933a87bf04f39e92a30feeab9eabfc32ccad95f3
parented2af67b7ad796d3309bcb53987adf5e075cd0e0
Rewrite make_outerjoininfo's construction of min_lefthand and min_righthand
sets for outer joins, in the light of bug #3588 and additional thought and
experimentation.  The original methodology was fatally flawed for nests of
more than two outer joins: it got the relationships between adjacent joins
right, but didn't always come to the right conclusions about whether a join
could be interchanged with one two or more levels below it.  This was largely
caused by a mistaken idea that we should use the min_lefthand + min_righthand
sets of a sub-join as the minimum left or right input set of an upper join
when we conclude that the sub-join can't commute with the upper one.  If
there's a still-lower join that the sub-join *can* commute with, this method
led us to think that that one could commute with the topmost join; which it
can't.  Another problem (not directly connected to bug #3588) was that
make_outerjoininfo's processing-order-dependent method for enforcing outer
join identity #3 didn't work right: if we decided that join A could safely
commute with lower join B, we dropped all information about sub-joins under B
that join A could perhaps not safely commute with, because we removed B's
entire min_righthand from A's.

To fix, make an explicit computation of all inner join combinations that occur
below an outer join, and add to that the full syntactic relsets of any lower
outer joins that we determine it can't commute with.  This method gives much
more direct enforcement of the outer join rearrangement identities, and it
turns out not to cost a lot of additional bookkeeping.

Thanks to Richard Harris for the bug report and test case.
src/backend/nodes/copyfuncs.c
src/backend/nodes/equalfuncs.c
src/backend/nodes/outfuncs.c
src/backend/optimizer/plan/initsplan.c
src/include/nodes/relation.h
src/test/regress/expected/join.out
src/test/regress/expected/join_1.out
src/test/regress/sql/join.sql