Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitddb4015

Browse files
committed
Fix longstanding bug that would sometimes let the planner generate a bad plan
for an outer join; symptom is bogus error "RIGHT JOIN is only supported withmerge-joinable join conditions". Problem was that select_mergejoin_clausesdid its tests in the wrong order. We need to force left join not right joinfor a merge join when there are non-mergeable join clauses; but the test forthis only accounted for mergejoinability of the clause operator, and notwhether the left and right Vars were of the proper relations. Per reportfrom Jean-Pierre Pelletier.
1 parent62cfa0f commitddb4015

File tree

1 file changed

+37
-32
lines changed

1 file changed

+37
-32
lines changed

‎src/backend/optimizer/path/joinpath.c

Lines changed: 37 additions & 32 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.96 2005/10/15 02:49:20 momjian Exp $
11+
* $PostgreSQL: pgsql/src/backend/optimizer/path/joinpath.c,v 1.97 2005/10/25 20:30:30 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -795,6 +795,7 @@ select_mergejoin_clauses(RelOptInfo *joinrel,
795795
{
796796
List*result_list=NIL;
797797
boolisouterjoin=IS_OUTER_JOIN(jointype);
798+
boolhave_nonmergeable_joinclause= false;
798799
ListCell*l;
799800

800801
foreach(l,restrictlist)
@@ -803,42 +804,19 @@ select_mergejoin_clauses(RelOptInfo *joinrel,
803804

804805
/*
805806
* If processing an outer join, only use its own join clauses in the
806-
* merge. For inner joins we need not be so picky.
807-
*
808-
* Furthermore, if it is a right/full join then *all* the explicit join
809-
* clauses must be mergejoinable, else the executor will fail. If we
810-
* are asked for a right join then just return NIL to indicate no
811-
* mergejoin is possible (we can handle it as a left join instead). If
812-
* we are asked for a full join then emit an error, because there is
813-
* no fallback.
807+
* merge. For inner joins we can use pushed-down clauses too.
808+
* (Note: we don't set have_nonmergeable_joinclause here because
809+
* pushed-down clauses will become otherquals not joinquals.)
814810
*/
815-
if (isouterjoin)
816-
{
817-
if (restrictinfo->is_pushed_down)
818-
continue;
819-
switch (jointype)
820-
{
821-
caseJOIN_RIGHT:
822-
if (!restrictinfo->can_join||
823-
restrictinfo->mergejoinoperator==InvalidOid)
824-
returnNIL;/* not mergejoinable */
825-
break;
826-
caseJOIN_FULL:
827-
if (!restrictinfo->can_join||
828-
restrictinfo->mergejoinoperator==InvalidOid)
829-
ereport(ERROR,
830-
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
831-
errmsg("FULL JOIN is only supported with merge-joinable join conditions")));
832-
break;
833-
default:
834-
/* otherwise, it's OK to have nonmergeable join quals */
835-
break;
836-
}
837-
}
811+
if (isouterjoin&&restrictinfo->is_pushed_down)
812+
continue;
838813

839814
if (!restrictinfo->can_join||
840815
restrictinfo->mergejoinoperator==InvalidOid)
816+
{
817+
have_nonmergeable_joinclause= true;
841818
continue;/* not mergejoinable */
819+
}
842820

843821
/*
844822
* Check if clause is usable with these input rels. All the vars
@@ -856,10 +834,37 @@ select_mergejoin_clauses(RelOptInfo *joinrel,
856834
/* lefthand side is inner */
857835
}
858836
else
837+
{
838+
have_nonmergeable_joinclause= true;
859839
continue;/* no good for these input relations */
840+
}
860841

861842
result_list=lcons(restrictinfo,result_list);
862843
}
863844

845+
/*
846+
* If it is a right/full join then *all* the explicit join clauses must be
847+
* mergejoinable, else the executor will fail. If we are asked for a right
848+
* join then just return NIL to indicate no mergejoin is possible (we can
849+
* handle it as a left join instead). If we are asked for a full join then
850+
* emit an error, because there is no fallback.
851+
*/
852+
if (have_nonmergeable_joinclause)
853+
{
854+
switch (jointype)
855+
{
856+
caseJOIN_RIGHT:
857+
returnNIL;/* not mergejoinable */
858+
caseJOIN_FULL:
859+
ereport(ERROR,
860+
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
861+
errmsg("FULL JOIN is only supported with merge-joinable join conditions")));
862+
break;
863+
default:
864+
/* otherwise, it's OK to have nonmergeable join quals */
865+
break;
866+
}
867+
}
868+
864869
returnresult_list;
865870
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp