Commit a6aac0a2 authored by unknown's avatar unknown

Merge with 4.0 (Fix bug in LEFT JOIN and EXPLAIN on empty table)


mysql-test/r/explain.result:
  Auto merged
mysql-test/t/explain.test:
  Auto merged
mysql-test/t/join.test:
  Auto merged
parents a74659dd cd5cca0d
drop table if exists t1; drop table if exists t1;
create table t1 (id int not null, str char(10), unique(str)); create table t1 (id int not null, str char(10), unique(str));
explain select * from t1;
table type possible_keys key key_len ref rows Extra
t1 system NULL NULL NULL NULL 0 const row not found
insert into t1 values (1, null),(2, null),(3, "foo"),(4, "bar"); insert into t1 values (1, null),(2, null),(3, "foo"),(4, "bar");
select * from t1 where str is null; select * from t1 where str is null;
id str id str
......
...@@ -14,8 +14,7 @@ insert into t1 values (101); ...@@ -14,8 +14,7 @@ insert into t1 values (101);
insert into t1 values (105); insert into t1 values (105);
insert into t1 values (106); insert into t1 values (106);
insert into t1 values (107); insert into t1 values (107);
insert into t2 values (107); insert into t2 values (107),(75),(1000);
insert into t2 values (75);
select t1.id, t2.id from t1, t2 where t2.id = t1.id; select t1.id, t2.id from t1, t2 where t2.id = t1.id;
id id id id
107 107 107 107
...@@ -28,6 +27,16 @@ select t1.id, count(t2.id) from t1,t2 where t2.id = t1.id group by t2.id; ...@@ -28,6 +27,16 @@ select t1.id, count(t2.id) from t1,t2 where t2.id = t1.id group by t2.id;
id count(t2.id) id count(t2.id)
75 1 75 1
107 1 107 1
select t1.id,t2.id from t2 left join t1 on t1.id>=74 and t1.id<=0 where t2.id=75 and t1.id is null;
id id
NULL 75
explain select t1.id,t2.id from t2 left join t1 on t1.id>=74 and t1.id<=0 where t2.id=75 and t1.id is null;
table type possible_keys key key_len ref rows Extra
t1 const PRIMARY NULL NULL NULL 1 Impossible ON condition
t2 ALL NULL NULL NULL NULL 3 Using where
explain select t1.id, t2.id from t1, t2 where t2.id = t1.id and t1.id <0 and t1.id > 0;
Comment
Impossible WHERE noticed after reading const tables
drop table t1,t2; drop table t1,t2;
CREATE TABLE t1 ( CREATE TABLE t1 (
id int(11) NOT NULL auto_increment, id int(11) NOT NULL auto_increment,
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
drop table if exists t1; drop table if exists t1;
--enable_warnings --enable_warnings
create table t1 (id int not null, str char(10), unique(str)); create table t1 (id int not null, str char(10), unique(str));
explain select * from t1;
insert into t1 values (1, null),(2, null),(3, "foo"),(4, "bar"); insert into t1 values (1, null),(2, null),(3, "foo"),(4, "bar");
select * from t1 where str is null; select * from t1 where str is null;
select * from t1 where str="foo"; select * from t1 where str="foo";
...@@ -14,8 +15,10 @@ explain select * from t1 ignore key (str) where str="foo"; ...@@ -14,8 +15,10 @@ explain select * from t1 ignore key (str) where str="foo";
explain select * from t1 use key (str,str) where str="foo"; explain select * from t1 use key (str,str) where str="foo";
#The following should give errors #The following should give errors
!$1072 explain select * from t1 use key (str,str,foo) where str="foo"; --error 1072
!$1072 explain select * from t1 ignore key (str,str,foo) where str="foo"; explain select * from t1 use key (str,str,foo) where str="foo";
--error 1072
explain select * from t1 ignore key (str,str,foo) where str="foo";
drop table t1; drop table t1;
explain select 1; explain select 1;
...@@ -21,13 +21,18 @@ insert into t1 values (105); ...@@ -21,13 +21,18 @@ insert into t1 values (105);
insert into t1 values (106); insert into t1 values (106);
insert into t1 values (107); insert into t1 values (107);
insert into t2 values (107); insert into t2 values (107),(75),(1000);
insert into t2 values (75);
select t1.id, t2.id from t1, t2 where t2.id = t1.id; select t1.id, t2.id from t1, t2 where t2.id = t1.id;
select t1.id, count(t2.id) from t1,t2 where t2.id = t1.id group by t1.id; select t1.id, count(t2.id) from t1,t2 where t2.id = t1.id group by t1.id;
select t1.id, count(t2.id) from t1,t2 where t2.id = t1.id group by t2.id; select t1.id, count(t2.id) from t1,t2 where t2.id = t1.id group by t2.id;
#
# Test problems with impossible ON or WHERE
#
select t1.id,t2.id from t2 left join t1 on t1.id>=74 and t1.id<=0 where t2.id=75 and t1.id is null;
explain select t1.id,t2.id from t2 left join t1 on t1.id>=74 and t1.id<=0 where t2.id=75 and t1.id is null;
explain select t1.id, t2.id from t1, t2 where t2.id = t1.id and t1.id <0 and t1.id > 0;
drop table t1,t2; drop table t1,t2;
# #
......
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB /* Copyright (C) 2000-2003 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
...@@ -1256,7 +1256,6 @@ make_join_statistics(JOIN *join,TABLE_LIST *tables,COND *conds, ...@@ -1256,7 +1256,6 @@ make_join_statistics(JOIN *join,TABLE_LIST *tables,COND *conds,
table_map found_const_table_map,all_table_map; table_map found_const_table_map,all_table_map;
TABLE **table_vector; TABLE **table_vector;
JOIN_TAB *stat,*stat_end,*s,**stat_ref; JOIN_TAB *stat,*stat_end,*s,**stat_ref;
SQL_SELECT *select;
KEYUSE *keyuse,*start_keyuse; KEYUSE *keyuse,*start_keyuse;
table_map outer_join=0; table_map outer_join=0;
JOIN_TAB *stat_vector[MAX_TABLES+1]; JOIN_TAB *stat_vector[MAX_TABLES+1];
...@@ -1268,7 +1267,6 @@ make_join_statistics(JOIN *join,TABLE_LIST *tables,COND *conds, ...@@ -1268,7 +1267,6 @@ make_join_statistics(JOIN *join,TABLE_LIST *tables,COND *conds,
table_vector=(TABLE**) join->thd->alloc(sizeof(TABLE*)*(table_count*2)); table_vector=(TABLE**) join->thd->alloc(sizeof(TABLE*)*(table_count*2));
if (!stat || !stat_ref || !table_vector) if (!stat || !stat_ref || !table_vector)
DBUG_RETURN(1); // Eom /* purecov: inspected */ DBUG_RETURN(1); // Eom /* purecov: inspected */
select=0;
join->best_ref=stat_vector; join->best_ref=stat_vector;
...@@ -1452,7 +1450,7 @@ make_join_statistics(JOIN *join,TABLE_LIST *tables,COND *conds, ...@@ -1452,7 +1450,7 @@ make_join_statistics(JOIN *join,TABLE_LIST *tables,COND *conds,
{ // Found everything for ref. { // Found everything for ref.
int tmp; int tmp;
ref_changed = 1; ref_changed = 1;
s->type=JT_CONST; s->type= JT_CONST;
join->const_table_map|=table->map; join->const_table_map|=table->map;
set_position(join,const_count++,s,start_keyuse); set_position(join,const_count++,s,start_keyuse);
if (create_ref_for_key(join, s, start_keyuse, if (create_ref_for_key(join, s, start_keyuse,
...@@ -1503,23 +1501,44 @@ make_join_statistics(JOIN *join,TABLE_LIST *tables,COND *conds, ...@@ -1503,23 +1501,44 @@ make_join_statistics(JOIN *join,TABLE_LIST *tables,COND *conds,
if (s->const_keys) if (s->const_keys)
{ {
ha_rows records; ha_rows records;
if (!select) SQL_SELECT *select;
select=make_select(s->table, found_const_table_map, select= make_select(s->table, found_const_table_map,
found_const_table_map, found_const_table_map,
and_conds(conds,s->on_expr),&error); s->on_expr ? s->on_expr : conds,
records=get_quick_record_count(select,s->table, s->const_keys, &error);
records= get_quick_record_count(select,s->table, s->const_keys,
join->row_limit); join->row_limit);
s->quick=select->quick; s->quick=select->quick;
s->needed_reg=select->needed_reg; s->needed_reg=select->needed_reg;
select->quick=0; select->quick=0;
if (records == 0 && s->table->reginfo.impossible_range)
{
/*
Impossible WHERE or ON expression
In case of ON, we mark that the we match one empty NULL row.
In case of WHERE, don't set found_const_table_map to get the
caller to abort with a zero row result.
*/
join->const_table_map|= s->table->map;
set_position(join,const_count++,s,(KEYUSE*) 0);
s->type= JT_CONST;
if (s->on_expr)
{
/* Generate empty row */
s->info= "Impossible ON condition";
found_const_table_map|= s->table->map;
s->type= JT_CONST;
mark_as_null_row(s->table); // All fields are NULL
}
}
if (records != HA_POS_ERROR) if (records != HA_POS_ERROR)
{ {
s->found_records=records; s->found_records=records;
s->read_time= (ha_rows) (s->quick ? s->quick->read_time : 0.0); s->read_time= (ha_rows) (s->quick ? s->quick->read_time : 0.0);
} }
delete select;
} }
} }
delete select;
/* Find best combination and return it */ /* Find best combination and return it */
join->join_tab=stat; join->join_tab=stat;
...@@ -2615,7 +2634,7 @@ static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, KEYUSE *org_keyuse, ...@@ -2615,7 +2634,7 @@ static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, KEYUSE *org_keyuse,
keyparts != keyinfo->key_parts) keyparts != keyinfo->key_parts)
j->type=JT_REF; /* Must read with repeat */ j->type=JT_REF; /* Must read with repeat */
else if (ref_key == j->ref.key_copy) else if (ref_key == j->ref.key_copy)
{ /* Should never be reached */ {
/* /*
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
of an LEFT JOIN. of an LEFT JOIN.
...@@ -7729,7 +7748,9 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order, ...@@ -7729,7 +7748,9 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
if (tab->info) if (tab->info)
item_list.push_back(new Item_string(tab->info,strlen(tab->info), item_list.push_back(new Item_string(tab->info,strlen(tab->info),
default_charset_info)); default_charset_info));
else if (tab->select) else
{
if (tab->select)
{ {
if (tab->use_quick == 2) if (tab->use_quick == 2)
{ {
...@@ -7760,6 +7781,7 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order, ...@@ -7760,6 +7781,7 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
buff_ptr+= 2; // Skip inital "; " buff_ptr+= 2; // Skip inital "; "
item_list.push_back(new Item_string(buff+2,(uint) (buff_ptr - buff)-2, item_list.push_back(new Item_string(buff+2,(uint) (buff_ptr - buff)-2,
default_charset_info)); default_charset_info));
}
// For next iteration // For next iteration
used_tables|=table->map; used_tables|=table->map;
if (result->send_data(item_list)) if (result->send_data(item_list))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment