dbTalk Databases Forums  

[BUGS] RIGHT JOIN is only supported with merge-joinable join conditions, PostgreSQL 8.1 beta3

mailing.database.pgsql-bugs mailing.database.pgsql-bugs


Discuss [BUGS] RIGHT JOIN is only supported with merge-joinable join conditions, PostgreSQL 8.1 beta3 in the mailing.database.pgsql-bugs forum.



Reply
 
Thread Tools Display Modes
  #1  
Old   
Jean-Pierre Pelletier
 
Posts: n/a

Default [BUGS] RIGHT JOIN is only supported with merge-joinable join conditions, PostgreSQL 8.1 beta3 - 10-25-2005 , 11:06 AM






Hi,

I have a query that throws error "RIGHT JOIN is only supported with
merge-joinable join conditions".
This should allow it to be reproduce.

create table table1 (t1id integer not null, extension integer not null);
create table table2 (t1id integer not null, t3id integer not null, original
integer not null, replacement integer not null);
create table table3 (t3id integer not null);
create unique index table3ix1 on table3 (t3id);
insert into table3 select * from generate_series(1,10000);

select
count(table3.*)
from
table1

inner join table2
on table1.t1id = table2.t1id
and table1.extension in (table2.original, table2.replacement)

left outer join table3
on table2.t3id = table3.t3id
and table1.extension in (table2.replacement);

I am on PostgreSQL 8.1 beta3 under Windows XP Service Pack 2.

Thanks
Jean-Pierre Pelletier
e-djuster


---------------------------(end of broadcast)---------------------------
TIP 6: explain analyze is your friend

Reply With Quote
  #2  
Old   
Tom Lane
 
Posts: n/a

Default Re: [BUGS] RIGHT JOIN is only supported with merge-joinable join conditions, PostgreSQL 8.1 beta3 - 10-25-2005 , 01:22 PM






"Jean-Pierre Pelletier" <pelletier_32 (AT) sympatico (DOT) ca> writes:
Quote:
I have a query that throws error "RIGHT JOIN is only supported with
merge-joinable join conditions".
Wow, that's a goodie ... seems to fail all the way back to 7.2 ...
thanks for the report.

regards, tom lane

---------------------------(end of broadcast)---------------------------
TIP 5: don't forget to increase your free space map settings


Reply With Quote
  #3  
Old   
Tom Lane
 
Posts: n/a

Default Re: [BUGS] RIGHT JOIN is only supported with merge-joinable join conditions, PostgreSQL 8.1 beta3 - 10-25-2005 , 03:37 PM



"Jean-Pierre Pelletier" <pelletier_32 (AT) sympatico (DOT) ca> writes:
Quote:
select
count(table3.*)
from
table1
inner join table2
on table1.t1id = table2.t1id
and table1.extension in (table2.original, table2.replacement)
left outer join table3
on table2.t3id = table3.t3id
and table1.extension in (table2.replacement);
I've applied the attached patch (for 8.1, variants as needed for back
branches) to fix this failure.

BTW, I think the reason nobody saw this before is that using a condition
on table1 vs table2 in the outer-join condition for table3 is a bit, er,
weird. Are you sure that the original query will do what you really
wanted?

But anyway, many thanks for the test case!

regards, tom lane

Index: joinpath.c
================================================== =================
RCS file: /cvsroot/pgsql/src/backend/optimizer/path/joinpath.c,v
retrieving revision 1.96
diff -c -r1.96 joinpath.c
*** joinpath.c 15 Oct 2005 02:49:20 -0000 1.96
--- joinpath.c 25 Oct 2005 19:52:54 -0000
***************
*** 795,800 ****
--- 795,801 ----
{
List *result_list = NIL;
bool isouterjoin = IS_OUTER_JOIN(jointype);
+ bool have_nonmergeable_joinclause = false;
ListCell *l;

foreach(l, restrictlist)
***************
*** 803,844 ****

/*
* If processing an outer join, only use its own join clauses in the
! * merge. For inner joins we need not be so picky.
! *
! * Furthermore, if it is a right/full join then *all* the explicit join
! * clauses must be mergejoinable, else the executor will fail. If we
! * are asked for a right join then just return NIL to indicate no
! * mergejoin is possible (we can handle it as a left join instead). If
! * we are asked for a full join then emit an error, because there is
! * no fallback.
*/
! if (isouterjoin)
! {
! if (restrictinfo->is_pushed_down)
! continue;
! switch (jointype)
! {
! case JOIN_RIGHT:
! if (!restrictinfo->can_join ||
! restrictinfo->mergejoinoperator == InvalidOid)
! return NIL; /* not mergejoinable */
! break;
! case JOIN_FULL:
! if (!restrictinfo->can_join ||
! restrictinfo->mergejoinoperator == InvalidOid)
! ereport(ERROR,
! (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
! errmsg("FULL JOIN is only supported with merge-joinable join conditions")));
! break;
! default:
! /* otherwise, it's OK to have nonmergeable join quals */
! break;
! }
! }

if (!restrictinfo->can_join ||
restrictinfo->mergejoinoperator == InvalidOid)
continue; /* not mergejoinable */

/*
* Check if clause is usable with these input rels. All the vars
--- 804,822 ----

/*
* If processing an outer join, only use its own join clauses in the
! * merge. For inner joins we can use pushed-down clauses too.
! * (Note: we don't set have_nonmergeable_joinclause here because
! * pushed-down clauses will become otherquals not joinquals.)
*/
! if (isouterjoin && restrictinfo->is_pushed_down)
! continue;

if (!restrictinfo->can_join ||
restrictinfo->mergejoinoperator == InvalidOid)
+ {
+ have_nonmergeable_joinclause = true;
continue; /* not mergejoinable */
+ }

/*
* Check if clause is usable with these input rels. All the vars
***************
*** 856,865 ****
--- 834,870 ----
/* lefthand side is inner */
}
else
+ {
+ have_nonmergeable_joinclause = true;
continue; /* no good for these input relations */
+ }

result_list = lcons(restrictinfo, result_list);
}

+ /*
+ * If it is a right/full join then *all* the explicit join clauses must be
+ * mergejoinable, else the executor will fail. If we are asked for a right
+ * join then just return NIL to indicate no mergejoin is possible (we can
+ * handle it as a left join instead). If we are asked for a full join then
+ * emit an error, because there is no fallback.
+ */
+ if (have_nonmergeable_joinclause)
+ {
+ switch (jointype)
+ {
+ case JOIN_RIGHT:
+ return NIL; /* not mergejoinable */
+ case JOIN_FULL:
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("FULL JOIN is only supported with merge-joinable join conditions")));
+ break;
+ default:
+ /* otherwise, it's OK to have nonmergeable join quals */
+ break;
+ }
+ }
+
return result_list;
}

---------------------------(end of broadcast)---------------------------
TIP 9: In versions below 8.0, the planner will ignore your desire to
choose an index scan if your joining column's datatypes do not
match


Reply With Quote
  #4  
Old   
Jean-Pierre Pelletier
 
Posts: n/a

Default Re: [BUGS] RIGHT JOIN is only supported with merge-joinable join conditions, PostgreSQL 8.1 beta3 - 10-25-2005 , 04:10 PM



Thanks for the speedy fix.

I agree that this is not a typical query, in it Table2.t3id and Table3.t3id
would always join
(a foreing key constraint ensure that) but columns from Table3 should
sometimes be excluded which is taken care by "table1.extension in
(table2.replacement)".

----- Original Message -----
From: "Tom Lane" <tgl (AT) sss (DOT) pgh.pa.us>
To: "Jean-Pierre Pelletier" <pelletier_32 (AT) sympatico (DOT) ca>
Cc: <pgsql-bugs (AT) postgresql (DOT) org>
Sent: Tuesday, October 25, 2005 4:34 PM
Subject: Re: [BUGS] RIGHT JOIN is only supported with merge-joinable join
conditions, PostgreSQL 8.1 beta3


Quote:
"Jean-Pierre Pelletier" <pelletier_32 (AT) sympatico (DOT) ca> writes:
select
count(table3.*)
from
table1
inner join table2
on table1.t1id = table2.t1id
and table1.extension in (table2.original, table2.replacement)
left outer join table3
on table2.t3id = table3.t3id
and table1.extension in (table2.replacement);

I've applied the attached patch (for 8.1, variants as needed for back
branches) to fix this failure.

BTW, I think the reason nobody saw this before is that using a condition
on table1 vs table2 in the outer-join condition for table3 is a bit, er,
weird. Are you sure that the original query will do what you really
wanted?

But anyway, many thanks for the test case!

regards, tom lane

Index: joinpath.c
================================================== =================
RCS file: /cvsroot/pgsql/src/backend/optimizer/path/joinpath.c,v
retrieving revision 1.96
diff -c -r1.96 joinpath.c
*** joinpath.c 15 Oct 2005 02:49:20 -0000 1.96
--- joinpath.c 25 Oct 2005 19:52:54 -0000
***************
*** 795,800 ****
--- 795,801 ----
{
List *result_list = NIL;
bool isouterjoin = IS_OUTER_JOIN(jointype);
+ bool have_nonmergeable_joinclause = false;
ListCell *l;

foreach(l, restrictlist)
***************
*** 803,844 ****

/*
* If processing an outer join, only use its own join clauses in the
! * merge. For inner joins we need not be so picky.
! *
! * Furthermore, if it is a right/full join then *all* the explicit join
! * clauses must be mergejoinable, else the executor will fail. If we
! * are asked for a right join then just return NIL to indicate no
! * mergejoin is possible (we can handle it as a left join instead). If
! * we are asked for a full join then emit an error, because there is
! * no fallback.
*/
! if (isouterjoin)
! {
! if (restrictinfo->is_pushed_down)
! continue;
! switch (jointype)
! {
! case JOIN_RIGHT:
! if (!restrictinfo->can_join ||
! restrictinfo->mergejoinoperator == InvalidOid)
! return NIL; /* not mergejoinable */
! break;
! case JOIN_FULL:
! if (!restrictinfo->can_join ||
! restrictinfo->mergejoinoperator == InvalidOid)
! ereport(ERROR,
! (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
! errmsg("FULL JOIN is only supported with merge-joinable join
conditions")));
! break;
! default:
! /* otherwise, it's OK to have nonmergeable join quals */
! break;
! }
! }

if (!restrictinfo->can_join ||
restrictinfo->mergejoinoperator == InvalidOid)
continue; /* not mergejoinable */

/*
* Check if clause is usable with these input rels. All the vars
--- 804,822 ----

/*
* If processing an outer join, only use its own join clauses in the
! * merge. For inner joins we can use pushed-down clauses too.
! * (Note: we don't set have_nonmergeable_joinclause here because
! * pushed-down clauses will become otherquals not joinquals.)
*/
! if (isouterjoin && restrictinfo->is_pushed_down)
! continue;

if (!restrictinfo->can_join ||
restrictinfo->mergejoinoperator == InvalidOid)
+ {
+ have_nonmergeable_joinclause = true;
continue; /* not mergejoinable */
+ }

/*
* Check if clause is usable with these input rels. All the vars
***************
*** 856,865 ****
--- 834,870 ----
/* lefthand side is inner */
}
else
+ {
+ have_nonmergeable_joinclause = true;
continue; /* no good for these input relations */
+ }

result_list = lcons(restrictinfo, result_list);
}

+ /*
+ * If it is a right/full join then *all* the explicit join clauses must
be
+ * mergejoinable, else the executor will fail. If we are asked for a
right
+ * join then just return NIL to indicate no mergejoin is possible (we can
+ * handle it as a left join instead). If we are asked for a full join
then
+ * emit an error, because there is no fallback.
+ */
+ if (have_nonmergeable_joinclause)
+ {
+ switch (jointype)
+ {
+ case JOIN_RIGHT:
+ return NIL; /* not mergejoinable */
+ case JOIN_FULL:
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("FULL JOIN is only supported with merge-joinable join
conditions")));
+ break;
+ default:
+ /* otherwise, it's OK to have nonmergeable join quals */
+ break;
+ }
+ }
+
return result_list;
}

---------------------------(end of broadcast)---------------------------
TIP 9: In versions below 8.0, the planner will ignore your desire to
choose an index scan if your joining column's datatypes do not
match

---------------------------(end of broadcast)---------------------------
TIP 2: Don't 'kill -9' the postmaster


Reply With Quote
Reply




Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off



Powered by vBulletin Version 3.5.3
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.