Commit 577b7345 authored by Igor Babaev's avatar Igor Babaev

Fixed bug #49600.

The problem could be demonstrated with an outer join of two single-row
tables where the values of the join attributes were null. Any query
with such a join could return a wrong result set if the where
condition of the query was not empty. For queries with empty
where conditions the result sets were correct.
This was the consequence of two bugs in the code:
 - Item_equal objects for on conditions of outer joins were
   not built if the processed query had no where condition
 - the check for null values in the code that evaluated constant 
   Item_equal objects was incorrect.
Fixed both above problems.
Added a test case for the bug and adjusted results for some other
test cases.
parent 6f59c41d
This diff is collapsed.
...@@ -1397,4 +1397,18 @@ id select_type table type possible_keys key key_len ref rows filtered Extra ...@@ -1397,4 +1397,18 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
Warnings: Warnings:
Note 1003 select straight_join `test`.`jt1`.`f1` AS `f1` from `test`.`t1` `jt6` left join (`test`.`t1` `jt3` join `test`.`t1` `jt4` left join `test`.`t1` `jt5` on(1) left join `test`.`t1` `jt2` on(1)) on((`test`.`jt6`.`f1` and 1)) left join `test`.`t1` `jt1` on(1) where 1 Note 1003 select straight_join `test`.`jt1`.`f1` AS `f1` from `test`.`t1` `jt6` left join (`test`.`t1` `jt3` join `test`.`t1` `jt4` left join `test`.`t1` `jt5` on(1) left join `test`.`t1` `jt2` on(1)) on((`test`.`jt6`.`f1` and 1)) left join `test`.`t1` `jt1` on(1) where 1
DROP TABLE t1; DROP TABLE t1;
#
# Bug#49600: outer join of two single-row tables with joining attributes
# evaluated to nulls
create table t1 (a int, b int);
create table t2 (a int, b int);
insert into t1 values (1, NULL);
insert into t2 values (2, NULL);
select * from t1 left join t2 on t1.b=t2.b;
a b a b
1 NULL NULL NULL
select * from t1 left join t2 on t1.b=t2.b where 1=1;
a b a b
1 NULL NULL NULL
drop table t1,t2;
End of 5.1 tests End of 5.1 tests
...@@ -60,7 +60,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra ...@@ -60,7 +60,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t0 ALL NULL NULL NULL NULL 4 100.00 1 SIMPLE t0 ALL NULL NULL NULL NULL 4 100.00
1 SIMPLE t1 ALL NULL NULL NULL NULL 4 100.00 1 SIMPLE t1 ALL NULL NULL NULL NULL 4 100.00
Warnings: Warnings:
Note 1003 select `test`.`t0`.`a` AS `a` from `test`.`t0` left join (`test`.`t1`) on((`test`.`t0`.`a` = `test`.`t1`.`a`)) where 1 Note 1003 select `test`.`t0`.`a` AS `a` from `test`.`t0` left join (`test`.`t1`) on((`test`.`t1`.`a` = `test`.`t0`.`a`)) where 1
# Elimination with aggregate functions # Elimination with aggregate functions
explain select count(*) from t1 left join t2 on t2.a=t1.a; explain select count(*) from t1 left join t2 on t2.a=t1.a;
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
......
...@@ -1418,7 +1418,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra ...@@ -1418,7 +1418,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00
1 SIMPLE t2 ALL NULL NULL NULL NULL 2 100.00 1 SIMPLE t2 ALL NULL NULL NULL NULL 2 100.00
Warnings: Warnings:
Note 1003 select `test`.`t3`.`a` AS `a`,`test`.`t1`.`a` AS `a`,`test`.`t2`.`a` AS `b` from `test`.`t3` left join (`test`.`t1` left join `test`.`t2` on((`test`.`t1`.`a` = `test`.`t2`.`a`))) on((`test`.`t3`.`a` = `test`.`t1`.`a`)) where 1 Note 1003 select `test`.`t3`.`a` AS `a`,`test`.`t1`.`a` AS `a`,`test`.`t2`.`a` AS `b` from `test`.`t3` left join (`test`.`t1` left join `test`.`t2` on(((`test`.`t1`.`a` = `test`.`t3`.`a`) and (`test`.`t2`.`a` = `test`.`t3`.`a`)))) on((`test`.`t1`.`a` = `test`.`t3`.`a`)) where 1
create view v1 (a) as select a from t1; create view v1 (a) as select a from t1;
create view v2 (a) as select a from t2; create view v2 (a) as select a from t2;
create view v4 (a,b) as select v1.a as a, v2.a as b from v1 left join v2 on (v1.a=v2.a); create view v4 (a,b) as select v1.a as a, v2.a as b from v1 left join v2 on (v1.a=v2.a);
...@@ -1433,7 +1433,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra ...@@ -1433,7 +1433,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00
1 SIMPLE t2 ALL NULL NULL NULL NULL 2 100.00 1 SIMPLE t2 ALL NULL NULL NULL NULL 2 100.00
Warnings: Warnings:
Note 1003 select `test`.`t3`.`a` AS `a`,`test`.`t1`.`a` AS `a`,`test`.`t2`.`a` AS `b` from `test`.`t3` left join (`test`.`t1` left join (`test`.`t2`) on((`test`.`t1`.`a` = `test`.`t2`.`a`))) on((`test`.`t3`.`a` = `test`.`t1`.`a`)) where 1 Note 1003 select `test`.`t3`.`a` AS `a`,`test`.`t1`.`a` AS `a`,`test`.`t2`.`a` AS `b` from `test`.`t3` left join (`test`.`t1` left join (`test`.`t2`) on(((`test`.`t1`.`a` = `test`.`t3`.`a`) and (`test`.`t2`.`a` = `test`.`t3`.`a`)))) on((`test`.`t1`.`a` = `test`.`t3`.`a`)) where 1
prepare stmt1 from "select * from t3 left join v4 on (t3.a = v4.a);"; prepare stmt1 from "select * from t3 left join v4 on (t3.a = v4.a);";
execute stmt1; execute stmt1;
a a b a a b
......
...@@ -981,4 +981,19 @@ EXPLAIN EXTENDED SELECT STRAIGHT_JOIN jt1.f1 FROM t1 AS jt1 ...@@ -981,4 +981,19 @@ EXPLAIN EXTENDED SELECT STRAIGHT_JOIN jt1.f1 FROM t1 AS jt1
DROP TABLE t1; DROP TABLE t1;
--echo #
--echo # Bug#49600: outer join of two single-row tables with joining attributes
--echo # evaluated to nulls
create table t1 (a int, b int);
create table t2 (a int, b int);
insert into t1 values (1, NULL);
insert into t2 values (2, NULL);
select * from t1 left join t2 on t1.b=t2.b;
select * from t1 left join t2 on t1.b=t2.b where 1=1;
drop table t1,t2;
--echo End of 5.1 tests --echo End of 5.1 tests
...@@ -5507,7 +5507,7 @@ longlong Item_equal::val_int() ...@@ -5507,7 +5507,7 @@ longlong Item_equal::val_int()
return 0; return 0;
List_iterator_fast<Item_field> it(fields); List_iterator_fast<Item_field> it(fields);
Item *item= const_item ? const_item : it++; Item *item= const_item ? const_item : it++;
if ((null_value= item->null_value)) if ((null_value= item->is_null()))
return 0; return 0;
eval_item->store_value(item); eval_item->store_value(item);
while ((item_field= it++)) while ((item_field= it++))
...@@ -5515,7 +5515,7 @@ longlong Item_equal::val_int() ...@@ -5515,7 +5515,7 @@ longlong Item_equal::val_int()
/* Skip fields of non-const tables. They haven't been read yet */ /* Skip fields of non-const tables. They haven't been read yet */
if (item_field->field->table->const_table) if (item_field->field->table->const_table)
{ {
if ((null_value= item_field->null_value) || eval_item->cmp(item_field)) if ((null_value= item_field->is_null()) || eval_item->cmp(item_field))
return 0; return 0;
} }
} }
......
...@@ -9315,7 +9315,10 @@ optimize_cond(JOIN *join, COND *conds, List<TABLE_LIST> *join_list, ...@@ -9315,7 +9315,10 @@ optimize_cond(JOIN *join, COND *conds, List<TABLE_LIST> *join_list,
DBUG_ENTER("optimize_cond"); DBUG_ENTER("optimize_cond");
if (!conds) if (!conds)
{
*cond_value= Item::COND_TRUE; *cond_value= Item::COND_TRUE;
build_equal_items(join->thd, NULL, NULL, join_list, &join->cond_equal);
}
else else
{ {
/* /*
......
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