Skip to content

Commit 4df8de7

Browse files
committed
Fix check for whether a clauseless join has to be forced in the presence of
outer joins. Originally it was only looking for overlap of the righthand side of a left join, but we have to do it on the lefthand side too. Per example from Jean-Pierre Pelletier.
1 parent d8221df commit 4df8de7

File tree

2 files changed

+25
-11
lines changed

2 files changed

+25
-11
lines changed

src/backend/optimizer/geqo/geqo_eval.c

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
77
* Portions Copyright (c) 1994, Regents of the University of California
88
*
9-
* $PostgreSQL: pgsql/src/backend/optimizer/geqo/geqo_eval.c,v 1.80 2006/03/05 15:58:28 momjian Exp $
9+
* $PostgreSQL: pgsql/src/backend/optimizer/geqo/geqo_eval.c,v 1.81 2006/10/24 17:50:22 tgl Exp $
1010
*
1111
*-------------------------------------------------------------------------
1212
*/
@@ -262,23 +262,29 @@ desirable_join(PlannerInfo *root,
262262
return true;
263263

264264
/*
265-
* Join if the rels are members of the same outer-join RHS. This is needed
266-
* to improve the odds that we will find a valid solution in a case where
267-
* an OJ RHS has a clauseless join.
265+
* Join if the rels are members of the same outer-join side. This is
266+
* needed to ensure that we can find a valid solution in a case where
267+
* an OJ contains a clauseless join.
268268
*/
269269
foreach(l, root->oj_info_list)
270270
{
271271
OuterJoinInfo *ojinfo = (OuterJoinInfo *) lfirst(l);
272272

273+
/* ignore full joins --- other mechanisms preserve their ordering */
274+
if (ojinfo->is_full_join)
275+
continue;
273276
if (bms_is_subset(outer_rel->relids, ojinfo->min_righthand) &&
274277
bms_is_subset(inner_rel->relids, ojinfo->min_righthand))
275278
return true;
279+
if (bms_is_subset(outer_rel->relids, ojinfo->min_lefthand) &&
280+
bms_is_subset(inner_rel->relids, ojinfo->min_lefthand))
281+
return true;
276282
}
277283

278284
/*
279-
* Join if the rels are members of the same IN sub-select. This is needed
280-
* to improve the odds that we will find a valid solution in a case where
281-
* an IN sub-select has a clauseless join.
285+
* Join if the rels are members of the same IN sub-select. This is needed
286+
* to ensure that we can find a valid solution in a case where an IN
287+
* sub-select has a clauseless join.
282288
*/
283289
foreach(l, root->in_info_list)
284290
{

src/backend/optimizer/path/joinrels.c

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/optimizer/path/joinrels.c,v 1.80 2006/10/04 00:29:54 momjian Exp $
11+
* $PostgreSQL: pgsql/src/backend/optimizer/path/joinrels.c,v 1.81 2006/10/24 17:50:22 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -87,9 +87,9 @@ make_rels_by_joins(PlannerInfo *root, int level, List **joinrels)
8787

8888
/*
8989
* An exception occurs when there is a clauseless join inside a
90-
* construct that restricts join order, i.e., an outer join RHS or
90+
* construct that restricts join order, i.e., an outer join or
9191
* an IN (sub-SELECT) construct. Here, the rel may well have join
92-
* clauses against stuff outside the OJ RHS or IN sub-SELECT, but
92+
* clauses against stuff outside its OJ side or IN sub-SELECT, but
9393
* the clauseless join *must* be done before we can make use of
9494
* those join clauses. So do the clauseless join bit.
9595
*
@@ -331,7 +331,7 @@ make_rels_by_clauseless_joins(PlannerInfo *root,
331331
/*
332332
* has_join_restriction
333333
* Detect whether the specified relation has join-order restrictions
334-
* due to being inside an OJ RHS or an IN (sub-SELECT).
334+
* due to being inside an outer join or an IN (sub-SELECT).
335335
*/
336336
static bool
337337
has_join_restriction(PlannerInfo *root, RelOptInfo *rel)
@@ -342,8 +342,16 @@ has_join_restriction(PlannerInfo *root, RelOptInfo *rel)
342342
{
343343
OuterJoinInfo *ojinfo = (OuterJoinInfo *) lfirst(l);
344344

345+
/* ignore full joins --- other mechanisms preserve their ordering */
346+
if (ojinfo->is_full_join)
347+
continue;
348+
/* anything inside the RHS is definitely restricted */
345349
if (bms_is_subset(rel->relids, ojinfo->min_righthand))
346350
return true;
351+
/* if it's a proper subset of the LHS, it's also restricted */
352+
if (bms_is_subset(rel->relids, ojinfo->min_lefthand) &&
353+
!bms_equal(rel->relids, ojinfo->min_lefthand))
354+
return true;
347355
}
348356

349357
foreach(l, root->in_info_list)

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