From 211164ff8ca4b9b00a1da80be3e36e55a09d22b8 Mon Sep 17 00:00:00 2001 From: Gleb Shchepa Date: Mon, 14 Jul 2008 14:06:49 +0500 Subject: [PATCH] Bug #37761: IN handles NULL differently for table-subquery and value-list The server returns unexpected results if a right side of the NOT IN clause consists of NULL value and some constants of the same type, for example: SELECT * FROM t WHERE NOT t.id IN (NULL, 1, 2) may return 3, 4, 5 etc if a table contains these values. The Item_func_in::val_int method has been modified: unnecessary resets of an Item_func_case::has_null field value has been moved outside of an argument comparison loop. (Also unnecessary re-initialization of the null_value field has been moved). --- mysql-test/r/func_in.result | 6 ++++++ mysql-test/t/func_in.test | 9 +++++++++ sql/item_cmpfunc.cc | 6 +++--- 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/func_in.result b/mysql-test/r/func_in.result index 6e1f9bd8188..e761fb851fb 100644 --- a/mysql-test/r/func_in.result +++ b/mysql-test/r/func_in.result @@ -569,4 +569,10 @@ insert into t1 values (),(),(),(),(),(),(),(),(),(); select a from t1 where a not in (a,a,a) group by a; a drop table t1; +create table t1 (id int); +select * from t1 where NOT id in (select null union all select 1); +id +select * from t1 where NOT id in (null, 1); +id +drop table t1; End of 5.1 tests diff --git a/mysql-test/t/func_in.test b/mysql-test/t/func_in.test index d8b0c89532e..d0d4dea0713 100644 --- a/mysql-test/t/func_in.test +++ b/mysql-test/t/func_in.test @@ -417,4 +417,13 @@ insert into t1 values (),(),(),(),(),(),(),(),(),(); select a from t1 where a not in (a,a,a) group by a; drop table t1; +# +# Bug #37761: IN handles NULL differently for table-subquery and value-list +# + +create table t1 (id int); +select * from t1 where NOT id in (select null union all select 1); +select * from t1 where NOT id in (null, 1); +drop table t1; + --echo End of 5.1 tests diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index f267ad39984..2db77eb7c56 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -3758,6 +3758,9 @@ longlong Item_func_in::val_int() return (longlong) (!null_value && tmp != negated); } + if ((null_value= args[0]->null_value)) + return 0; + have_null= 0; for (uint i= 1 ; i < arg_count ; i++) { Item_result cmp_type= item_cmp_type(left_result_type, args[i]->result_type()); @@ -3766,9 +3769,6 @@ longlong Item_func_in::val_int() if (!(value_added_map & (1 << (uint)cmp_type))) { in_item->store_value(args[0]); - if ((null_value=args[0]->null_value)) - return 0; - have_null= 0; value_added_map|= 1 << (uint)cmp_type; } if (!in_item->cmp(args[i]) && !args[i]->null_value)