diff --git a/mysql-test/r/join_outer.result b/mysql-test/r/join_outer.result index eae023813b580426a7cd62566397b98d34c04ba2..7fc1f8b6489abc5845d493fa0e3d4306cce101d8 100644 --- a/mysql-test/r/join_outer.result +++ b/mysql-test/r/join_outer.result @@ -735,7 +735,7 @@ explain select s.*, '*', m.*, (s.match_1_h - m.home) UUX from (t2 s left join t1 m on m.match_id = 1) order by m.match_id desc; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE s ALL NULL NULL NULL NULL 10 +1 SIMPLE s ALL NULL NULL NULL NULL 10 Using temporary; Using filesort 1 SIMPLE m const match_id,match_id_2 match_id 1 const 1 explain select s.*, '*', m.*, (s.match_1_h - m.home) UUX from (t2 s left join t1 m on m.match_id = 1) diff --git a/mysql-test/r/order_by.result b/mysql-test/r/order_by.result index a36935a583db2ae310be0c257a873bcbd8e05765..69a5509b68cba97b6596583a837fec1fdb658b59 100644 --- a/mysql-test/r/order_by.result +++ b/mysql-test/r/order_by.result @@ -852,3 +852,40 @@ b a 20 1 10 2 DROP TABLE t1; +CREATE TABLE t1 (a int, b int, PRIMARY KEY (a)); +INSERT INTO t1 VALUES (1,1), (2,2), (3,3); +explain SELECT t1.b as a, t2.b as c FROM +t1 LEFT JOIN t1 t2 ON (t1.a = t2.a AND t2.a = 2) +ORDER BY c; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using temporary; Using filesort +1 SIMPLE t2 const PRIMARY PRIMARY 4 const 1 +SELECT t1.b as a, t2.b as c FROM +t1 LEFT JOIN t1 t2 ON (t1.a = t2.a AND t2.a = 2) +ORDER BY c; +a c +1 NULL +3 NULL +2 2 +explain SELECT t1.b as a, t2.b as c FROM +t1 JOIN t1 t2 ON (t1.a = t2.a AND t2.a = 2) +ORDER BY c; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1 +1 SIMPLE t2 const PRIMARY PRIMARY 4 const 1 +CREATE TABLE t2 LIKE t1; +INSERT INTO t2 SELECT * from t1; +CREATE TABLE t3 LIKE t1; +INSERT INTO t3 SELECT * from t1; +CREATE TABLE t4 LIKE t1; +INSERT INTO t4 SELECT * from t1; +INSERT INTO t1 values (0,0),(4,4); +SELECT t1.*,t2.* FROM t1 LEFT JOIN (t2, t3 LEFT JOIN t4 ON t3.a=t4.a) +ON (t1.a=t2.a AND t1.b=t3.b) order by t2.b; +a b a b +0 0 NULL NULL +4 4 NULL NULL +1 1 1 1 +2 2 2 2 +3 3 3 3 +DROP TABLE t1,t2,t3,t4; diff --git a/mysql-test/t/order_by.test b/mysql-test/t/order_by.test index 98e542dac9532a996bb0628df4bc85cc01c5b462..96b843ee699e44ba2ef4ff8772a07df636a32048 100644 --- a/mysql-test/t/order_by.test +++ b/mysql-test/t/order_by.test @@ -578,3 +578,35 @@ INSERT INTO t1 VALUES (1,30), (2,20), (1,10), (2,30), (1,20), (2,10); DROP TABLE t1; # End of 4.1 tests + +# +# Bug#21302: Result not properly sorted when using an ORDER BY on a second +# table in a join +# +CREATE TABLE t1 (a int, b int, PRIMARY KEY (a)); +INSERT INTO t1 VALUES (1,1), (2,2), (3,3); + +explain SELECT t1.b as a, t2.b as c FROM + t1 LEFT JOIN t1 t2 ON (t1.a = t2.a AND t2.a = 2) +ORDER BY c; +SELECT t1.b as a, t2.b as c FROM + t1 LEFT JOIN t1 t2 ON (t1.a = t2.a AND t2.a = 2) +ORDER BY c; + +# check that it still removes sort of const table +explain SELECT t1.b as a, t2.b as c FROM + t1 JOIN t1 t2 ON (t1.a = t2.a AND t2.a = 2) +ORDER BY c; + +CREATE TABLE t2 LIKE t1; +INSERT INTO t2 SELECT * from t1; +CREATE TABLE t3 LIKE t1; +INSERT INTO t3 SELECT * from t1; +CREATE TABLE t4 LIKE t1; +INSERT INTO t4 SELECT * from t1; +INSERT INTO t1 values (0,0),(4,4); + +SELECT t1.*,t2.* FROM t1 LEFT JOIN (t2, t3 LEFT JOIN t4 ON t3.a=t4.a) +ON (t1.a=t2.a AND t1.b=t3.b) order by t2.b; + +DROP TABLE t1,t2,t3,t4; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 2f16b350d04242757a82cde7b6d14cab8d70fdf2..adb7b66df8a9eedd8774532c7f02f83d39d3063b 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -5976,7 +5976,8 @@ eq_ref_table(JOIN *join, ORDER *start_order, JOIN_TAB *tab) if (tab->cached_eq_ref_table) // If cached return tab->eq_ref_table; tab->cached_eq_ref_table=1; - if (tab->type == JT_CONST) // We can skip const tables + /* We can skip const tables only if not an outer table */ + if (tab->type == JT_CONST && !tab->first_inner) return (tab->eq_ref_table=1); /* purecov: inspected */ if (tab->type != JT_EQ_REF || tab->table->maybe_null) return (tab->eq_ref_table=0); // We must use this