Skip to content

Commit 9688c4e

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 507069d commit 9688c4e

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
@@ -1840,6 +1840,11 @@ reduce_outer_joins_pass2(Node *jtnode,
18401840
* is that we pass either the local or the upper constraints,
18411841
* never both, to the children of an outer join.
18421842
*
1843+
* Note that a SEMI join works like an inner join here: it's okay
1844+
* to pass down both local and upper constraints. (There can't
1845+
* be any upper constraints affecting its inner side, but it's
1846+
* not worth having a separate code path to avoid passing them.)
1847+
*
18431848
* At a FULL join we just punt and pass nothing down --- is it
18441849
* possible to be smarter?
18451850
*/
@@ -1849,7 +1854,7 @@ reduce_outer_joins_pass2(Node *jtnode,
18491854
if (!computed_local_nonnullable_vars)
18501855
local_nonnullable_vars = find_nonnullable_vars(j->quals);
18511856
local_forced_null_vars = find_forced_null_vars(j->quals);
1852-
if (jointype == JOIN_INNER)
1857+
if (jointype == JOIN_INNER || jointype == JOIN_SEMI)
18531858
{
18541859
/* OK to merge upper and local constraints */
18551860
local_nonnullable_rels = bms_add_members(local_nonnullable_rels,
@@ -1869,14 +1874,14 @@ reduce_outer_joins_pass2(Node *jtnode,
18691874

18701875
if (left_state->contains_outer)
18711876
{
1872-
if (jointype == JOIN_INNER)
1877+
if (jointype == JOIN_INNER || jointype == JOIN_SEMI)
18731878
{
18741879
/* pass union of local and upper constraints */
18751880
pass_nonnullable_rels = local_nonnullable_rels;
18761881
pass_nonnullable_vars = local_nonnullable_vars;
18771882
pass_forced_null_vars = local_forced_null_vars;
18781883
}
1879-
else if (jointype != JOIN_FULL) /* ie, LEFT/SEMI/ANTI */
1884+
else if (jointype != JOIN_FULL) /* ie, LEFT or ANTI */
18801885
{
18811886
/* can't pass local constraints to non-nullable side */
18821887
pass_nonnullable_rels = nonnullable_rels;

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy