From d33b968f0304161bdd0c74764f71630862e33a9a Mon Sep 17 00:00:00 2001 From: unknown <timour@mysql.com> Date: Wed, 17 Aug 2005 17:19:31 +0300 Subject: [PATCH] WL#2486 - natural and using join according to SQL:2003 - fixed a problem with RIGHT JOIN ON and enabled corresponding tests in select.test - fixed a memory leak mysql-test/r/select.result: Fixed a problem with RIGHT JOIN ON queries, enabling the corresponding tests. mysql-test/t/select.test: Fixed a problem with RIGHT JOIN ON queries, enabling the corresponding tests. sql/sql_base.cc: Fixed a problem with RIGHT JOINs that have operand(s) which are NATURAL JOIN(s). sql/table.h: Inherit from Sql_alloc for proper memory allocation. The change fixes a memory leak. --- mysql-test/r/select.result | 17 +++++++++++++++++ mysql-test/t/select.test | 6 ++---- sql/sql_base.cc | 27 +++++++++++++++++++++++---- sql/table.h | 2 +- 4 files changed, 43 insertions(+), 9 deletions(-) diff --git a/mysql-test/r/select.result b/mysql-test/r/select.result index 580ccc44a7..1b35df534a 100644 --- a/mysql-test/r/select.result +++ b/mysql-test/r/select.result @@ -2218,6 +2218,23 @@ a 1 2 3 +select * from (t1 as t2 left join t1 as t3 using (a)) right join t1 on t1.a>1; +a a +NULL 1 +1 2 +2 2 +3 2 +1 3 +2 3 +3 3 +select * from t1 right join (t1 as t2 left join t1 as t3 using (a)) on t1.a>1; +a a +2 1 +3 1 +2 2 +3 2 +2 3 +3 3 select * from (t1 as t2 left join t1 as t3 using (a)) right outer join t1 using ( a ); a 1 diff --git a/mysql-test/t/select.test b/mysql-test/t/select.test index e0c4d66633..390c4372f1 100644 --- a/mysql-test/t/select.test +++ b/mysql-test/t/select.test @@ -1850,10 +1850,8 @@ select * from t1 left join (t1 as t2 left join t1 as t3 using (a)) using ( a ); select * from (t1 as t2 left join t1 as t3 using (a)) natural left join t1; select * from t1 natural left join (t1 as t2 left join t1 as t3 using (a)); # right join on -# TODO: WL#2486 - there is a problem in the order of tables in RIGHT JOIN -# check how we set next_name_resolution_table -# select * from (t1 as t2 left join t1 as t3 using (a)) right join t1 on t1.a>1; -# select * from t1 right join (t1 as t2 left join t1 as t3 using (a)) on t1.a>1; +select * from (t1 as t2 left join t1 as t3 using (a)) right join t1 on t1.a>1; +select * from t1 right join (t1 as t2 left join t1 as t3 using (a)) on t1.a>1; # right [outer] joing using select * from (t1 as t2 left join t1 as t3 using (a)) right outer join t1 using ( a ); select * from t1 right outer join (t1 as t2 left join t1 as t3 using (a)) using ( a ); diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 4d4f9ae48d..98ce12eb7d 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -3790,10 +3790,29 @@ store_top_level_join_columns(THD *thd, TABLE_LIST *table_ref, { TABLE_LIST *cur_table_ref= cur_left_neighbor; cur_left_neighbor= nested_it++; - if (cur_table_ref->nested_join && - store_top_level_join_columns(thd, cur_table_ref, - cur_left_neighbor, cur_right_neighbor)) - DBUG_RETURN(TRUE); + /* + The order of RIGHT JOIN operands is reversed in 'join list' to + transform it into a LEFT JOIN. However, in this procedure we need + the join operands in their lexical order, so below we reverse the + join operands. Notice that this happens only in the first loop, and + not in the second one, as in the second loop cur_left_neighbor == NULL. + This is the correct behavior, because the second loop + sets cur_table_ref reference correctly after the join operands are + swapped in the first loop. + */ + if (cur_left_neighbor && + cur_table_ref->outer_join & JOIN_TYPE_RIGHT) + { + DBUG_ASSERT(cur_table_ref); + /* This can happen only for JOIN ... ON. */ + DBUG_ASSERT(table_ref->nested_join->join_list.elements == 2); + swap_variables(TABLE_LIST*, cur_left_neighbor, cur_table_ref); + } + + if (cur_table_ref->nested_join && + store_top_level_join_columns(thd, cur_table_ref, + cur_left_neighbor, cur_right_neighbor)) + DBUG_RETURN(TRUE); cur_right_neighbor= cur_table_ref; } } diff --git a/sql/table.h b/sql/table.h index bb9de5dc86..3d4f02e389 100644 --- a/sql/table.h +++ b/sql/table.h @@ -374,7 +374,7 @@ struct Field_translator Field (for tables), or a Field_translator (for views). */ -class Natural_join_column +class Natural_join_column: public Sql_alloc { public: Field_translator *view_field; /* Column reference of merge view. */ -- 2.30.9