summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <monty@mashka.mysql.fi>2003-01-19 17:15:14 +0200
committerunknown <monty@mashka.mysql.fi>2003-01-19 17:15:14 +0200
commit09b1e7d6076748b198f54008495cf4e60e156b86 (patch)
treedebffe8500d53e9050a799b81caa446a02b631d9
parent88df4e732605df862dd264f65788ab1d58a9b153 (diff)
downloadmariadb-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.result13
-rw-r--r--mysql-test/t/join.test9
-rw-r--r--sql/sql_select.cc43
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.