Commit 593bed0d authored by unknown's avatar unknown

Fixed bug #15633: Evaluation of Item_equal for non-const table caused wrong

select result

Item equal objects are employed only at the optimize phase. Usually they are not
supposed to be evaluated.  Yet in some cases we call the method val_int() for
them. Here we have to take care of restricting the predicate such an object
represents f1=f2= ...=fn to the projection of known fields fi1=...=fik.

Added a check for field's table being const in Item_equal::val_int().
If the field's table is not const val_int() just skips that field when
evaluating Item_equal.


mysql-test/t/select.test:
  Added test case for bug #15633: Evaluation of Item_equal for non-const table caused wrong select result
mysql-test/r/select.result:
  Added test case for bug #15633: Evaluation of Item_equal for non-const table caused wrong select result
mysql-test/r/func_group.result:
  Corrected test result for bug #12882 after fix for bug#15633
sql/item_cmpfunc.h:
  Fixed bug #15633: Evaluation of Item_equal for non-const table caused wrong select result
  Added comment about fields from non-const tables in class description.
sql/item_cmpfunc.cc:
  Fixed bug #15633: Evaluation of Item_equal for non-const table caused wrong select result
  Added check for field's table being const in Item_equal::val_int().
parent 95cabee1
...@@ -865,6 +865,7 @@ select 1, min(a) from t1m where 1=99; ...@@ -865,6 +865,7 @@ select 1, min(a) from t1m where 1=99;
1 NULL 1 NULL
select 1, min(1) from t1m where a=99; select 1, min(1) from t1m where a=99;
1 min(1) 1 min(1)
1 NULL
select 1, min(1) from t1m where 1=99; select 1, min(1) from t1m where 1=99;
1 min(1) 1 min(1)
1 NULL 1 NULL
...@@ -876,6 +877,7 @@ select 1, max(a) from t1m where 1=99; ...@@ -876,6 +877,7 @@ select 1, max(a) from t1m where 1=99;
1 NULL 1 NULL
select 1, max(1) from t1m where a=99; select 1, max(1) from t1m where a=99;
1 max(1) 1 max(1)
1 NULL
select 1, max(1) from t1m where 1=99; select 1, max(1) from t1m where 1=99;
1 max(1) 1 max(1)
1 NULL 1 NULL
......
...@@ -3337,3 +3337,16 @@ id select_type table type possible_keys key key_len ref rows Extra ...@@ -3337,3 +3337,16 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 const PRIMARY PRIMARY 4 const 1 Using index 1 SIMPLE t2 const PRIMARY PRIMARY 4 const 1 Using index
1 SIMPLE t3 const PRIMARY PRIMARY 8 const,const 1 1 SIMPLE t3 const PRIMARY PRIMARY 8 const,const 1
DROP TABLE t1,t2,t3; DROP TABLE t1,t2,t3;
create table t1 (f1 int unique);
create table t2 (f2 int unique);
create table t3 (f3 int unique);
insert into t1 values(1),(2);
insert into t2 values(1),(2);
insert into t3 values(1),(NULL);
select * from t3 where f3 is null;
f3
NULL
select t2.f2 from t1 left join t2 on f1=f2 join t3 on f1=f3 where f1=1;
f2
1
drop table t1,t2,t3;
...@@ -2805,3 +2805,17 @@ EXPLAIN SELECT t2.key_a,foo ...@@ -2805,3 +2805,17 @@ EXPLAIN SELECT t2.key_a,foo
WHERE t2.key_a=2 and key_b=5; WHERE t2.key_a=2 and key_b=5;
DROP TABLE t1,t2,t3; DROP TABLE t1,t2,t3;
#
# Bug #15633 Evaluation of Item_equal for non-const table caused wrong
# select result
#
create table t1 (f1 int unique);
create table t2 (f2 int unique);
create table t3 (f3 int unique);
insert into t1 values(1),(2);
insert into t2 values(1),(2);
insert into t3 values(1),(NULL);
select * from t3 where f3 is null;
select t2.f2 from t1 left join t2 on f1=f2 join t3 on f1=f3 where f1=1;
drop table t1,t2,t3;
...@@ -3765,6 +3765,7 @@ void Item_equal::update_used_tables() ...@@ -3765,6 +3765,7 @@ void Item_equal::update_used_tables()
longlong Item_equal::val_int() longlong Item_equal::val_int()
{ {
Item_field *item_field;
if (cond_false) if (cond_false)
return 0; return 0;
List_iterator_fast<Item_field> it(fields); List_iterator_fast<Item_field> it(fields);
...@@ -3772,10 +3773,14 @@ longlong Item_equal::val_int() ...@@ -3772,10 +3773,14 @@ longlong Item_equal::val_int()
if ((null_value= item->null_value)) if ((null_value= item->null_value))
return 0; return 0;
eval_item->store_value(item); eval_item->store_value(item);
while ((item= it++)) while ((item_field= it++))
{ {
if ((null_value= item->null_value) || eval_item->cmp(item)) /* Skip fields of non-const tables. They haven't been read yet */
return 0; if (item_field->field->table->const_table)
{
if ((null_value= item_field->null_value) || eval_item->cmp(item_field))
return 0;
}
} }
return 1; return 1;
} }
......
...@@ -1150,6 +1150,11 @@ public: ...@@ -1150,6 +1150,11 @@ public:
are deleted in the end of execution. All changes made to these are deleted in the end of execution. All changes made to these
objects need not be registered in the list of changes of the parse objects need not be registered in the list of changes of the parse
tree and do not harm PS/SP re-execution. tree and do not harm PS/SP re-execution.
Item equal objects are employed only at the optimize phase. Usually they are
not supposed to be evaluated. Yet in some cases we call the method val_int()
for them. We have to take care of restricting the predicate such an
object represents f1=f2= ...=fn to the projection of known fields fi1=...=fik.
*/ */
class Item_equal: public Item_bool_func class Item_equal: public Item_bool_func
......
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