summaryrefslogtreecommitdiff
path: root/sql/item_cmpfunc.cc
diff options
context:
space:
mode:
authorAlexey Kopytov <Alexey.Kopytov@Sun.com>2010-06-22 22:53:08 +0400
committerAlexey Kopytov <Alexey.Kopytov@Sun.com>2010-06-22 22:53:08 +0400
commit07e95b39c46708b4aa7aa27459ecc3feee7aa61c (patch)
tree4117de34093af5542d2bdf21d6d8025797e56a14 /sql/item_cmpfunc.cc
parentf48306344ac2a17f19222d30ba8fc23b146bdf12 (diff)
downloadmariadb-git-07e95b39c46708b4aa7aa27459ecc3feee7aa61c.tar.gz
Bug#54477: Crash on IN / CASE with NULL arguments
Incorrect handling of NULL arguments could lead to a crash on the IN or CASE operations when either NULL arguments were passed explicitly as arguments (IN) or implicitly generated by the WITH ROLLUP modifier (both IN and CASE). Item_func_case::find_item() assumed all necessary comparators to be instantiated in fix_length_and_dec(). However, in the presence of WITH ROLLUP modifier, arguments could be substituted with an Item_null leading to an "unexpected" STRING_RESULT comparator being invoked. In addition to the problem identical to the above, Item_func_in::val_int() could crash even with explicitly passed NULL arguments due to an optimization in fix_length_and_dec() leading to NULL arguments being ignored during comparators creation.
Diffstat (limited to 'sql/item_cmpfunc.cc')
-rw-r--r--sql/item_cmpfunc.cc10
1 files changed, 10 insertions, 0 deletions
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index 6e38220abd1..9ff72d56050 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -2773,6 +2773,8 @@ Item *Item_func_case::find_item(String *str)
/* Compare every WHEN argument with it and return the first match */
for (uint i=0 ; i < ncases ; i+=2)
{
+ if (args[i]->real_item()->type() == NULL_ITEM)
+ continue;
cmp_type= item_cmp_type(left_result_type, args[i]->result_type());
DBUG_ASSERT(cmp_type != ROW_RESULT);
DBUG_ASSERT(cmp_items[(uint)cmp_type]);
@@ -4002,9 +4004,17 @@ longlong Item_func_in::val_int()
return (longlong) (!null_value && tmp != negated);
}
+ if ((null_value= args[0]->real_item()->type() == NULL_ITEM))
+ return 0;
+
have_null= 0;
for (uint i= 1 ; i < arg_count ; i++)
{
+ if (args[i]->real_item()->type() == NULL_ITEM)
+ {
+ have_null= TRUE;
+ continue;
+ }
Item_result cmp_type= item_cmp_type(left_result_type, args[i]->result_type());
in_item= cmp_items[(uint)cmp_type];
DBUG_ASSERT(in_item);