Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
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)