Skip to content

Commit f9845ac

Browse files
committed
Fix brain fade in join-removal patch: a pushed-down clause in the outer join's
restrict list is not just something to ignore, it's actually grounds to abandon the optimization entirely. Per bug #5255 from Matteo Beccati.
1 parent 666c845 commit f9845ac

File tree

1 file changed

+13
-5
lines changed

1 file changed

+13
-5
lines changed

src/backend/optimizer/path/joinpath.c

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/optimizer/path/joinpath.c,v 1.126 2009/09/19 17:48:09 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/optimizer/path/joinpath.c,v 1.127 2009/12/25 17:11:32 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -228,6 +228,11 @@ join_is_removable(PlannerInfo *root,
228228
* We can't remove the join if any inner-rel attributes are used above
229229
* the join.
230230
*
231+
* Note that this test only detects use of inner-rel attributes in
232+
* higher join conditions and the target list. There might be such
233+
* attributes in pushed-down conditions at this join, too. We check
234+
* that case below.
235+
*
231236
* As a micro-optimization, it seems better to start with max_attr and
232237
* count down rather than starting with min_attr and counting up, on the
233238
* theory that the system attributes are somewhat less likely to be wanted
@@ -253,13 +258,16 @@ join_is_removable(PlannerInfo *root,
253258
RestrictInfo *restrictinfo = (RestrictInfo *) lfirst(l);
254259

255260
/*
256-
* We are always considering an outer join here, so ignore pushed-down
257-
* clauses. Also ignore anything that doesn't have a mergejoinable
258-
* operator.
261+
* If we find a pushed-down clause, it must have come from above the
262+
* outer join and it must contain references to the inner rel. (If
263+
* it had only outer-rel variables, it'd have been pushed down into
264+
* the outer rel.) Therefore, we can conclude that join removal
265+
* is unsafe without any examination of the clause contents.
259266
*/
260267
if (restrictinfo->is_pushed_down)
261-
continue;
268+
return false;
262269

270+
/* Ignore if it's not a mergejoinable clause */
263271
if (!restrictinfo->can_join ||
264272
restrictinfo->mergeopfamilies == NIL)
265273
continue; /* not mergejoinable */

0 commit comments

Comments
 (0)