From 263f2e3fe2d0fe6e9c7fa5b7a1e40551bf2bca15 Mon Sep 17 00:00:00 2001 From: "sergefp@mysql.com" <> Date: Mon, 23 Aug 2004 12:31:56 +0400 Subject: [PATCH] Fix for bug#5088: * When executing EXPLAIN, do the same as for the query: convert join type to JT_CONST if keyuse array covers all key parts and all of them are constants. * In remove_const, don't remove conditions that depend on some-const-table and current-table. --- mysql-test/r/join_outer.result | 71 +++++++++++++++++++++++++++++++++- mysql-test/t/join_outer.test | 50 ++++++++++++++++++++++++ sql/sql_select.cc | 6 ++- 3 files changed, 124 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/join_outer.result b/mysql-test/r/join_outer.result index d6f2b7a72d8..75bf96cb401 100644 --- a/mysql-test/r/join_outer.result +++ b/mysql-test/r/join_outer.result @@ -634,7 +634,7 @@ insert into t2 values (10,1),(20,2),(30,3); explain select * from t2 left join t1 on t1.fooID = t2.fooID and t1.fooID = 30; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 index NULL PRIMARY 4 NULL 3 Using index -1 SIMPLE t1 eq_ref PRIMARY PRIMARY 2 const 1 Using where; Using index +1 SIMPLE t1 const PRIMARY PRIMARY 2 const 1 Using where; Using index select * from t2 left join t1 on t1.fooID = t2.fooID and t1.fooID = 30; fooID barID fooID 10 1 NULL @@ -682,3 +682,72 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 ALL NULL NULL NULL NULL 2 1 SIMPLE t3 ALL NULL NULL NULL NULL 2 drop table t1, t2, t3; +create table t1 ( +match_id tinyint(3) unsigned not null auto_increment, +home tinyint(3) unsigned default '0', +unique key match_id (match_id), +key match_id_2 (match_id) +); +insert into t1 values("1", "2"); +create table t2 ( +player_id tinyint(3) unsigned default '0', +match_1_h tinyint(3) unsigned default '0', +key player_id (player_id) +); +insert into t2 values("1", "5"); +insert into t2 values("2", "9"); +insert into t2 values("3", "3"); +insert into t2 values("4", "7"); +insert into t2 values("5", "6"); +insert into t2 values("6", "8"); +insert into t2 values("7", "4"); +insert into t2 values("8", "12"); +insert into t2 values("9", "11"); +insert into t2 values("10", "10"); +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 m const match_id,match_id_2 match_id 1 const 1 Using where +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 UUX desc; +id select_type table type possible_keys key key_len ref rows Extra +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 Using where +select s.*, '*', m.*, (s.match_1_h - m.home) UUX from +(t2 s left join t1 m on m.match_id = 1) +order by UUX desc; +player_id match_1_h * match_id home UUX +8 12 * 1 2 10 +9 11 * 1 2 9 +10 10 * 1 2 8 +2 9 * 1 2 7 +6 8 * 1 2 6 +4 7 * 1 2 5 +5 6 * 1 2 4 +1 5 * 1 2 3 +7 4 * 1 2 2 +3 3 * 1 2 1 +explain select s.*, '*', m.*, (s.match_1_h - m.home) UUX from +t2 s straight_join t1 m where m.match_id = 1 +order by UUX desc; +id select_type table type possible_keys key key_len ref rows Extra +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 Using where +select s.*, '*', m.*, (s.match_1_h - m.home) UUX from +t2 s straight_join t1 m where m.match_id = 1 +order by UUX desc; +player_id match_1_h * match_id home UUX +8 12 * 1 2 10 +9 11 * 1 2 9 +10 10 * 1 2 8 +2 9 * 1 2 7 +6 8 * 1 2 6 +4 7 * 1 2 5 +5 6 * 1 2 4 +1 5 * 1 2 3 +7 4 * 1 2 2 +3 3 * 1 2 1 +drop table t1, t2; diff --git a/mysql-test/t/join_outer.test b/mysql-test/t/join_outer.test index 4ffe1c075b6..0c4c9614d88 100644 --- a/mysql-test/t/join_outer.test +++ b/mysql-test/t/join_outer.test @@ -451,3 +451,53 @@ select * from t1 left join t2 on b1 = a1 left join t3 on c1 = a1 and b1 is explain select * from t1 left join t2 on b1 = a1 left join t3 on c1 = a1 and b1 is null; drop table t1, t2, t3; + +# Test for BUG#5088 + +create table t1 ( + match_id tinyint(3) unsigned not null auto_increment, + home tinyint(3) unsigned default '0', + unique key match_id (match_id), + key match_id_2 (match_id) +); + +insert into t1 values("1", "2"); + +create table t2 ( + player_id tinyint(3) unsigned default '0', + match_1_h tinyint(3) unsigned default '0', + key player_id (player_id) +); + +insert into t2 values("1", "5"); +insert into t2 values("2", "9"); +insert into t2 values("3", "3"); +insert into t2 values("4", "7"); +insert into t2 values("5", "6"); +insert into t2 values("6", "8"); +insert into t2 values("7", "4"); +insert into t2 values("8", "12"); +insert into t2 values("9", "11"); +insert into t2 values("10", "10"); + +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; + +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 UUX desc; + +select s.*, '*', m.*, (s.match_1_h - m.home) UUX from + (t2 s left join t1 m on m.match_id = 1) + order by UUX desc; + +explain select s.*, '*', m.*, (s.match_1_h - m.home) UUX from + t2 s straight_join t1 m where m.match_id = 1 + order by UUX desc; + +select s.*, '*', m.*, (s.match_1_h - m.home) UUX from + t2 s straight_join t1 m where m.match_id = 1 + order by UUX desc; + +drop table t1, t2; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index fdea963b3ca..8830b2b2d17 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -3215,6 +3215,7 @@ static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, KEYUSE *org_keyuse, store_key **ref_key= j->ref.key_copy; byte *key_buff=j->ref.key_buff, *null_ref_key= 0; + bool keyuse_uses_no_tables= true; if (ftkey) { j->ref.items[0]=((Item_func*)(keyuse->val))->key_item(); @@ -3234,6 +3235,7 @@ static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, KEYUSE *org_keyuse, uint maybe_null= test(keyinfo->key_part[i].null_bit); j->ref.items[i]=keyuse->val; // Save for cond removal + keyuse_uses_no_tables= keyuse_uses_no_tables & !keyuse->used_tables; if (!keyuse->used_tables && !(join->select_options & SELECT_DESCRIBE)) { // Compare against constant @@ -3273,7 +3275,7 @@ static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, KEYUSE *org_keyuse, j->type= null_ref_key ? JT_REF_OR_NULL : JT_REF; j->ref.null_ref_key= null_ref_key; } - else if (ref_key == j->ref.key_copy) + else if (keyuse_uses_no_tables) { /* This happen if we are using a constant expression in the ON part @@ -4062,7 +4064,7 @@ remove_const(JOIN *join,ORDER *first_order, COND *cond, bool *simple_order) } if ((ref=order_tables & (not_const_tables ^ first_table))) { - if (only_eq_ref_tables(join,first_order,ref)) + if (!(order_tables & first_table) && only_eq_ref_tables(join,first_order,ref)) { DBUG_PRINT("info",("removing: %s", order->item[0]->full_name())); continue;