Commit 68a91293 authored by unknown's avatar unknown
Browse files

Fix for BUG#13597 - columns in ON condition not resolved if references a table...

Fix for BUG#13597 - columns in ON condition not resolved if references a table in a nested right join.

The problem was in that when finding the last table reference in a nested join tree,
the procedure doing the iteration over the right-most branches of a join tree
was testing for RIGHT JOINs the table reference that represents the join, and not
the second operand of the JOIN. Currently the information whether a join is LEFT/RIGHT
is stored not on the join object itself, but on one of its operands.


mysql-test/r/select.result:
  Added test for BUG#13597
mysql-test/t/select.test:
  Added test for BUG#13597
sql/table.cc:
  - test whether a table reference is a right join by testing the
    rigth join operand (first in the list of operands), and not
    the table reference that represents the join itself.
  - clearer comments
parent 3a806cd6
Loading
Loading
Loading
Loading
+23 −0
Original line number Diff line number Diff line
@@ -3038,3 +3038,26 @@ id
102
drop table t1, t2;
drop view v1, v2, v3;
create table a (
id int(11) not null default '0'
) engine=myisam default charset=latin1;
insert into a values (123),(191),(192);
create table b (
id char(16) character set utf8 not null default ''
) engine=myisam default charset=latin1;
insert into b values ('58013'),('58014'),('58015'),('58016');
create table c (
a_id int(11) not null default '0',
b_id char(16) character set utf8 default null
) engine=myisam default charset=latin1;
insert into c values
(123,null),(123,null),(123,null),(123,null),(123,null),(123,'58013');
select count(*)
from a inner join (c left join b on b.id = c.b_id) on a.id = c.a_id;
count(*)
6
select count(*)
from a inner join (b right join c on b.id = c.b_id) on a.id = c.a_id;
count(*)
6
drop table a, b, c;
+34 −0
Original line number Diff line number Diff line
@@ -2575,3 +2575,37 @@ select * from v1 left join v3 using (id);

drop table t1, t2;
drop view v1, v2, v3;

#
# Bug #13597 Column in ON condition not resolved if references a table in
# nested right join.
#

create table a (
  id int(11) not null default '0'
) engine=myisam default charset=latin1;

insert into a values (123),(191),(192);

create table b (
  id char(16) character set utf8 not null default ''
) engine=myisam default charset=latin1;

insert into b values ('58013'),('58014'),('58015'),('58016');

create table c (
  a_id int(11) not null default '0',
  b_id char(16) character set utf8 default null
) engine=myisam default charset=latin1;

insert into c values
(123,null),(123,null),(123,null),(123,null),(123,null),(123,'58013');

-- both queries are equivalent
select count(*)
from a inner join (c left join b on b.id = c.b_id) on a.id = c.a_id;

select count(*)
from a inner join (b right join c on b.id = c.b_id) on a.id = c.a_id;

drop table a, b, c;
+8 −6
Original line number Diff line number Diff line
@@ -2291,8 +2291,10 @@ TABLE_LIST *st_table_list::first_leaf_for_name_resolution()
    List_iterator_fast<TABLE_LIST> it(cur_nested_join->join_list);
    cur_table_ref= it++;
    /*
      If 'this' is a RIGHT JOIN, the operands in 'join_list' are in reverse
      order, thus the first operand is already at the front of the list.
      If the current nested join is a RIGHT JOIN, the operands in
      'join_list' are in reverse order, thus the first operand is
      already at the front of the list. Otherwise the first operand
      is in the end of the list of join operands.
    */
    if (!(cur_table_ref->outer_join & JOIN_TYPE_RIGHT))
    {
@@ -2343,9 +2345,11 @@ TABLE_LIST *st_table_list::last_leaf_for_name_resolution()
       cur_nested_join;
       cur_nested_join= cur_table_ref->nested_join)
  {
    cur_table_ref= cur_nested_join->join_list.head();
    /*
      If 'this' is a RIGHT JOIN, the operands in 'join_list' are in reverse
      order, thus the last operand is in the end of the list.
      If the current nested is a RIGHT JOIN, the operands in
      'join_list' are in reverse order, thus the last operand is in the
      end of the list.
    */
    if ((cur_table_ref->outer_join & JOIN_TYPE_RIGHT))
    {
@@ -2355,8 +2359,6 @@ TABLE_LIST *st_table_list::last_leaf_for_name_resolution()
      while ((next= it++))
        cur_table_ref= next;
    }
    else
      cur_table_ref= cur_nested_join->join_list.head();
    if (cur_table_ref->is_leaf_for_name_resolution())
      break;
  }