Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 7920ed3

Browse files
committed
Simplify overcomplicated (and overly restrictive) test to see whether an
IS NULL condition is rendered redundant by detection of an antijoin. If we know that a join is an antijoin, then *any* Var coming out of its righthand side must be NULL, not only the joining column(s). Also, it's still gonna be null after being passed up through higher joins, whether they're outer joins or not. I was misled by a faulty analogy to reduce_outer_joins() in the original coding. But consider select * from a left join b on a.x = b.y where b.y is null and b.z is null; The first IS NULL condition justifies deciding that the join is an antijoin (if the = is strict) and then the second one is just plain redundant.
1 parent 233b8a9 commit 7920ed3

File tree

1 file changed

+8
-34
lines changed

1 file changed

+8
-34
lines changed

src/backend/optimizer/plan/initsplan.c

+8-34
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/optimizer/plan/initsplan.c,v 1.146 2009/01/01 17:23:44 momjian Exp $
11+
* $PostgreSQL: pgsql/src/backend/optimizer/plan/initsplan.c,v 1.147 2009/02/20 00:01:03 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -725,6 +725,9 @@ make_outerjoininfo(PlannerInfo *root,
725725
* 'qualscope' identifies what level of JOIN the qual came from syntactically.
726726
* 'ojscope' is needed if we decide to force the qual up to the outer-join
727727
* level, which will be ojscope not necessarily qualscope.
728+
*
729+
* At the time this is called, root->join_info_list must contain entries for
730+
* all and only those special joins that are syntactically below this qual.
728731
*/
729732
static void
730733
distribute_qual_to_rels(PlannerInfo *root, Node *clause,
@@ -1209,7 +1212,6 @@ check_redundant_nullability_qual(PlannerInfo *root, Node *clause)
12091212
{
12101213
Var *forced_null_var;
12111214
Index forced_null_rel;
1212-
SpecialJoinInfo *match_sjinfo = NULL;
12131215
ListCell *lc;
12141216

12151217
/* Check for IS NULL, and identify the Var forced to NULL */
@@ -1219,47 +1221,19 @@ check_redundant_nullability_qual(PlannerInfo *root, Node *clause)
12191221
forced_null_rel = forced_null_var->varno;
12201222

12211223
/*
1222-
* Search to see if there's a matching antijoin that is not masked by
1223-
* a higher outer join. Because we have to scan the join info bottom-up,
1224-
* we have to continue looking after finding a match to check for masking
1225-
* joins. This logic should agree with reduce_outer_joins's code
1226-
* to detect antijoins on the basis of IS NULL clauses. (It's tempting
1227-
* to consider adding some data structures to avoid redundant work,
1228-
* but in practice this code shouldn't get executed often enough to
1229-
* make it worth the trouble.)
1224+
* If the Var comes from the nullable side of a lower antijoin, the
1225+
* IS NULL condition is necessarily true.
12301226
*/
12311227
foreach(lc, root->join_info_list)
12321228
{
12331229
SpecialJoinInfo *sjinfo = (SpecialJoinInfo *) lfirst(lc);
12341230

1235-
/* Check for match ... */
12361231
if (sjinfo->jointype == JOIN_ANTI &&
12371232
bms_is_member(forced_null_rel, sjinfo->syn_righthand))
1238-
{
1239-
List *nonnullable_vars;
1240-
1241-
nonnullable_vars = find_nonnullable_vars((Node *) sjinfo->join_quals);
1242-
if (list_member(nonnullable_vars, forced_null_var))
1243-
{
1244-
match_sjinfo = sjinfo;
1245-
continue;
1246-
}
1247-
}
1248-
/*
1249-
* Else, if we had a lower match, check to see if the target var is
1250-
* from the nullable side of this OJ. If so, this OJ masks the
1251-
* lower one and we can no longer consider the IS NULL as redundant
1252-
* with the lower antijoin.
1253-
*/
1254-
if (!match_sjinfo)
1255-
continue;
1256-
if (bms_is_member(forced_null_rel, sjinfo->syn_righthand) ||
1257-
(sjinfo->jointype == JOIN_FULL &&
1258-
bms_is_member(forced_null_rel, sjinfo->syn_lefthand)))
1259-
match_sjinfo = NULL;
1233+
return true;
12601234
}
12611235

1262-
return (match_sjinfo != NULL);
1236+
return false;
12631237
}
12641238

12651239
/*

0 commit comments

Comments
 (0)