8000 Make reduce_outer_joins() smarter about semijoins. · machack666/postgres@1df57f6 · GitHub 10000
[go: up one dir, main page]

Skip to content

Commit 1df57f6

Browse files
committed
Make reduce_outer_joins() smarter about semijoins.
reduce_outer_joins() mistakenly treated a semijoin like a left join for purposes of deciding whether not-null constraints created by the join's quals could be passed down into the join's left-hand side (possibly resulting in outer-join simplification there). Actually, semijoin works like inner join for this purpose, ie, we do not need to see any rows that can't possibly satisfy the quals. Hence, two-line fix to treat semi and inner joins alike. Per observation by Andres Freund about a performance gripe from Yazan Suleiman. Back-patch to 8.4, since this oversight has been there since the current handling of semijoins was implemented.
1 parent 2fb64d8 commit 1df57f6

File tree

1 file changed

+8
-3
lines changed

1 file changed

+8
-3
lines changed

src/backend/optimizer/prep/prepjointree.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1745,6 +1745,11 @@ reduce_outer_joins_pass2(Node *jtnode,
17451745
* is that we pass either the local or the upper constraints,
17461746
* never both, to the children of an outer join.
17471747
*
1748+
* Note that a SEMI join works like an inner join here: it's okay
1749+
* to pass down both local and upper constraints. (There can't
1750+
* be any upper constraints affecting its inner side, but it's
1751+
* not worth having a separate code path to avoid passing them.)
1752+
*
17481753
* At a FULL join we just punt and pass nothing down --- is it
17491754
* possible to be smarter?
17501755
*/
@@ -1754,7 +1759,7 @@ reduce_outer_joins_pass2(Node *jtnode,
17541759
if (!computed_local_nonnullable_vars)
17551760
local_nonnullable_vars = find_nonnullable_vars(j->quals);
17561761
local_forced_null_vars = find_forced_null_vars(j->quals);
1757-
if (jointype == JOIN_INNER)
1762+
if (jointype == JOIN_INNER || jointype == JOIN_SEMI)
17581763
{
17591764
/* OK to merge upper and local constraints */
17601765
local_nonnullable_rels = bms_add_members(local_nonnullable_rels,
@@ -1774,14 +1779,14 @@ reduce_outer_joins_pass2(Node *jtnode,
17741779

17751780
if (left_state->contains_outer)
17761781
{
1777-
if (jointype == JOIN_INNER)
1782+
if (jointype == JOIN_INNER || jointype == JOIN_SEMI)
17781783
{
17791784
/* pass union of local and upper constraints */
17801785
pass_nonnullable_rels = local_nonnullable_rels;
17811786
pass_nonnullable_vars = local_nonnullable_vars;
17821787
pass_forced_null_vars = local_forced_null_vars;
17831788
}
1784-
else if (jointype != JOIN_FULL) /* ie, LEFT/SEMI/ANTI */
1789+
else if (jointype != JOIN_FULL) /* ie, LEFT or ANTI */
17851790
{
17861791
/* can't pass local constraints to non-nullable side */
17871792
pass_nonnullable_rels = nonnullable_rels;

0 commit comments

Comments
 (0)
0