diff options
author | unknown <monty@mashka.mysql.fi> | 2003-01-19 17:15:14 +0200 |
---|---|---|
committer | unknown <monty@mashka.mysql.fi> | 2003-01-19 17:15:14 +0200 |
commit | 09b1e7d6076748b198f54008495cf4e60e156b86 (patch) | |
tree | debffe8500d53e9050a799b81caa446a02b631d9 | |
parent | 88df4e732605df862dd264f65788ab1d58a9b153 (diff) | |
download | mariadb-git-09b1e7d6076748b198f54008495cf4e60e156b86.tar.gz |
Fixed bug in LEFT JOIN with impossible ON/WHERE expression
mysql-test/r/join.result:
Test of LEFT JOIN bug
mysql-test/t/join.test:
Test of LEFT JOIN bug
-rw-r--r-- | mysql-test/r/join.result | 13 | ||||
-rw-r--r-- | mysql-test/t/join.test | 9 | ||||
-rw-r--r-- | sql/sql_select.cc | 43 |
3 files changed, 49 insertions, 16 deletions
diff --git a/mysql-test/r/join.result b/mysql-test/r/join.result index 96113dcdc8b..ff608825b9c 100644 --- a/mysql-test/r/join.result +++ b/mysql-test/r/join.result @@ -14,8 +14,7 @@ insert into t1 values (101); insert into t1 values (105); insert into t1 values (106); insert into t1 values (107); -insert into t2 values (107); -insert into t2 values (75); +insert into t2 values (107),(75),(1000); select t1.id, t2.id from t1, t2 where t2.id = t1.id; id id 107 107 @@ -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) 75 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; CREATE TABLE t1 ( id int(11) NOT NULL auto_increment, diff --git a/mysql-test/t/join.test b/mysql-test/t/join.test index 18006e8fd22..f58281af003 100644 --- a/mysql-test/t/join.test +++ b/mysql-test/t/join.test @@ -19,13 +19,18 @@ insert into t1 values (105); insert into t1 values (106); insert into t1 values (107); -insert into t2 values (107); -insert into t2 values (75); +insert into t2 values (107),(75),(1000); 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 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; # diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 237197ba6be..4bae58d70cd 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -1,4 +1,4 @@ -/* 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 it under the terms of the GNU General Public License as published by @@ -1009,7 +1009,6 @@ make_join_statistics(JOIN *join,TABLE_LIST *tables,COND *conds, table_map found_const_table_map,all_table_map; TABLE **table_vector; JOIN_TAB *stat,*stat_end,*s,**stat_ref; - SQL_SELECT *select; KEYUSE *keyuse,*start_keyuse; table_map outer_join=0; JOIN_TAB *stat_vector[MAX_TABLES+1]; @@ -1021,7 +1020,6 @@ make_join_statistics(JOIN *join,TABLE_LIST *tables,COND *conds, table_vector=(TABLE**) join->thd->alloc(sizeof(TABLE*)*(table_count*2)); if (!stat || !stat_ref || !table_vector) DBUG_RETURN(1); // Eom /* purecov: inspected */ - select=0; join->best_ref=stat_vector; @@ -1205,7 +1203,7 @@ make_join_statistics(JOIN *join,TABLE_LIST *tables,COND *conds, { // Found everything for ref. int tmp; ref_changed = 1; - s->type=JT_CONST; + s->type= JT_CONST; join->const_table_map|=table->map; set_position(join,const_count++,s,start_keyuse); if (create_ref_for_key(join, s, start_keyuse, @@ -1256,23 +1254,44 @@ make_join_statistics(JOIN *join,TABLE_LIST *tables,COND *conds, if (s->const_keys) { ha_rows records; - if (!select) - select=make_select(s->table, found_const_table_map, - found_const_table_map, - and_conds(conds,s->on_expr),&error); - records=get_quick_record_count(select,s->table, s->const_keys, - join->row_limit); + SQL_SELECT *select; + select= make_select(s->table, found_const_table_map, + found_const_table_map, + s->on_expr ? s->on_expr : conds, + &error); + records= get_quick_record_count(select,s->table, s->const_keys, + join->row_limit); s->quick=select->quick; s->needed_reg=select->needed_reg; 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) { s->found_records=records; s->read_time= (ha_rows) (s->quick ? s->quick->read_time : 0.0); } + delete select; } } - delete select; /* Find best combination and return it */ join->join_tab=stat; @@ -2367,7 +2386,7 @@ static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, KEYUSE *org_keyuse, keyparts != keyinfo->key_parts) j->type=JT_REF; /* Must read with repeat */ 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 of an LEFT JOIN. |