mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
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: Testcase for bug#5088 mysql-test/t/join_outer.test: Testcase for bug#5088
This commit is contained in:
@ -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;
|
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
|
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 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;
|
select * from t2 left join t1 on t1.fooID = t2.fooID and t1.fooID = 30;
|
||||||
fooID barID fooID
|
fooID barID fooID
|
||||||
10 1 NULL
|
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 t2 ALL NULL NULL NULL NULL 2
|
||||||
1 SIMPLE t3 ALL NULL NULL NULL NULL 2
|
1 SIMPLE t3 ALL NULL NULL NULL NULL 2
|
||||||
drop table t1, t2, t3;
|
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;
|
||||||
|
@ -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;
|
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;
|
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;
|
||||||
|
@ -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;
|
store_key **ref_key= j->ref.key_copy;
|
||||||
byte *key_buff=j->ref.key_buff, *null_ref_key= 0;
|
byte *key_buff=j->ref.key_buff, *null_ref_key= 0;
|
||||||
|
bool keyuse_uses_no_tables= true;
|
||||||
if (ftkey)
|
if (ftkey)
|
||||||
{
|
{
|
||||||
j->ref.items[0]=((Item_func*)(keyuse->val))->key_item();
|
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);
|
uint maybe_null= test(keyinfo->key_part[i].null_bit);
|
||||||
j->ref.items[i]=keyuse->val; // Save for cond removal
|
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 &&
|
if (!keyuse->used_tables &&
|
||||||
!(join->select_options & SELECT_DESCRIBE))
|
!(join->select_options & SELECT_DESCRIBE))
|
||||||
{ // Compare against constant
|
{ // 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->type= null_ref_key ? JT_REF_OR_NULL : JT_REF;
|
||||||
j->ref.null_ref_key= null_ref_key;
|
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
|
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 ((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()));
|
DBUG_PRINT("info",("removing: %s", order->item[0]->full_name()));
|
||||||
continue;
|
continue;
|
||||||
|
Reference in New Issue
Block a user