mirror of
https://git.postgresql.org/git/postgresql.git
synced 2025-01-18 18:44:06 +08:00
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.
This commit is contained in:
parent
d8221dfa6d
commit
4df8de7a68
@ -6,7 +6,7 @@
|
||||
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/geqo/geqo_eval.c,v 1.80 2006/03/05 15:58:28 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/geqo/geqo_eval.c,v 1.81 2006/10/24 17:50:22 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -262,23 +262,29 @@ desirable_join(PlannerInfo *root,
|
||||
return true;
|
||||
|
||||
/*
|
||||
* Join if the rels are members of the same outer-join RHS. This is needed
|
||||
* to improve the odds that we will find a valid solution in a case where
|
||||
* an OJ RHS has a clauseless join.
|
||||
* Join if the rels are members of the same outer-join side. This is
|
||||
* needed to ensure that we can find a valid solution in a case where
|
||||
* an OJ contains a clauseless join.
|
||||
*/
|
||||
foreach(l, root->oj_info_list)
|
||||
{
|
||||
OuterJoinInfo *ojinfo = (OuterJoinInfo *) lfirst(l);
|
||||
|
||||
/* ignore full joins --- other mechanisms preserve their ordering */
|
||||
if (ojinfo->is_full_join)
|
||||
continue;
|
||||
if (bms_is_subset(outer_rel->relids, ojinfo->min_righthand) &&
|
||||
bms_is_subset(inner_rel->relids, ojinfo->min_righthand))
|
||||
return true;
|
||||
if (bms_is_subset(outer_rel->relids, ojinfo->min_lefthand) &&
|
||||
bms_is_subset(inner_rel->relids, ojinfo->min_lefthand))
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Join if the rels are members of the same IN sub-select. This is needed
|
||||
* to improve the odds that we will find a valid solution in a case where
|
||||
* an IN sub-select has a clauseless join.
|
||||
* Join if the rels are members of the same IN sub-select. This is needed
|
||||
* to ensure that we can find a valid solution in a case where an IN
|
||||
* sub-select has a clauseless join.
|
||||
*/
|
||||
foreach(l, root->in_info_list)
|
||||
{
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/path/joinrels.c,v 1.80 2006/10/04 00:29:54 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/path/joinrels.c,v 1.81 2006/10/24 17:50:22 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -87,9 +87,9 @@ make_rels_by_joins(PlannerInfo *root, int level, List **joinrels)
|
||||
|
||||
/*
|
||||
* An exception occurs when there is a clauseless join inside a
|
||||
* construct that restricts join order, i.e., an outer join RHS or
|
||||
* construct that restricts join order, i.e., an outer join or
|
||||
* an IN (sub-SELECT) construct. Here, the rel may well have join
|
||||
* clauses against stuff outside the OJ RHS or IN sub-SELECT, but
|
||||
* clauses against stuff outside its OJ side or IN sub-SELECT, but
|
||||
* the clauseless join *must* be done before we can make use of
|
||||
* those join clauses. So do the clauseless join bit.
|
||||
*
|
||||
@ -331,7 +331,7 @@ make_rels_by_clauseless_joins(PlannerInfo *root,
|
||||
/*
|
||||
* has_join_restriction
|
||||
* Detect whether the specified relation has join-order restrictions
|
||||
* due to being inside an OJ RHS or an IN (sub-SELECT).
|
||||
* due to being inside an outer join or an IN (sub-SELECT).
|
||||
*/
|
||||
static bool
|
||||
has_join_restriction(PlannerInfo *root, RelOptInfo *rel)
|
||||
@ -342,8 +342,16 @@ has_join_restriction(PlannerInfo *root, RelOptInfo *rel)
|
||||
{
|
||||
OuterJoinInfo *ojinfo = (OuterJoinInfo *) lfirst(l);
|
||||
|
||||
/* ignore full joins --- other mechanisms preserve their ordering */
|
||||
if (ojinfo->is_full_join)
|
||||
continue;
|
||||
/* anything inside the RHS is definitely restricted */
|
||||
if (bms_is_subset(rel->relids, ojinfo->min_righthand))
|
||||
return true;
|
||||
/* if it's a proper subset of the LHS, it's also restricted */
|
||||
if (bms_is_subset(rel->relids, ojinfo->min_lefthand) &&
|
||||
!bms_equal(rel->relids, ojinfo->min_lefthand))
|
||||
return true;
|
||||
}
|
||||
|
||||
foreach(l, root->in_info_list)
|
||||
|
Loading…
Reference in New Issue
Block a user