diff options
author | Alexander Barkov <bar@mnogosearch.org> | 2014-01-24 16:50:39 +0400 |
---|---|---|
committer | Alexander Barkov <bar@mnogosearch.org> | 2014-01-24 16:50:39 +0400 |
commit | d106dc059746157239d951551093fec049a7b73a (patch) | |
tree | 61b1e9cb2cf21293196b23b7dcad345c6a41a930 | |
parent | 519c7305ac4e1e4bafe0acc56764fa40a0e621ab (diff) | |
download | mariadb-git-d106dc059746157239d951551093fec049a7b73a.tar.gz |
MDEV-5504 Server crashes in String::length on SELECT with MONTHNAME, GROUP BY, ROLLUP
The crash happened because Item_func_monthname was derived from
Item_func_month, so Item_func_monthname::is_null() did not work fine.
Backporting a change from 5.5: Item_func_monthname is now derived from
Item_str_func.
-rw-r--r-- | mysql-test/r/func_time.result | 12 | ||||
-rw-r--r-- | mysql-test/t/func_time.test | 9 | ||||
-rw-r--r-- | sql/item_timefunc.cc | 13 | ||||
-rw-r--r-- | sql/item_timefunc.h | 5 |
4 files changed, 27 insertions, 12 deletions
diff --git a/mysql-test/r/func_time.result b/mysql-test/r/func_time.result index 7020007f940..ddbf42c8060 100644 --- a/mysql-test/r/func_time.result +++ b/mysql-test/r/func_time.result @@ -162,7 +162,7 @@ dayname("1962-03-03") dayname("1962-03-03")+0 Saturday 5 select monthname("1972-03-04"),monthname("1972-03-04")+0; monthname("1972-03-04") monthname("1972-03-04")+0 -March 3 +March 0 select time_format(000000,'%H|%I|%k|%l|%i|%p|%r|%S|%T'),date_format(19980131000000,'%H|%I|%k|%l|%i|%p|%r|%S|%T'); time_format(000000,'%H|%I|%k|%l|%i|%p|%r|%S|%T') date_format(19980131000000,'%H|%I|%k|%l|%i|%p|%r|%S|%T') 00|12|0|12|00|AM|12:00:00 AM|00|00:00:00 00|12|0|12|00|AM|12:00:00 AM|00|00:00:00 @@ -2347,3 +2347,13 @@ EXTRACT(HOUR FROM TIME('1 02:00:00')) EXTRACT(HOUR FROM TIME('26:00:00')) SELECT EXTRACT(DAY FROM TIME('1 02:00:00')), EXTRACT(DAY FROM TIME('26:00:00')); EXTRACT(DAY FROM TIME('1 02:00:00')) EXTRACT(DAY FROM TIME('26:00:00')) 1 1 +# +# MDEV-5504 Server crashes in String::length on SELECT with MONTHNAME, GROUP BY, ROLLUP +# +CREATE TABLE t1 (i INT); +INSERT INTO t1 VALUES (1),(2); +SELECT 1 FROM t1 GROUP BY MONTHNAME(0) WITH ROLLUP; +1 +1 +1 +DROP TABLE t1; diff --git a/mysql-test/t/func_time.test b/mysql-test/t/func_time.test index 91ccb06655e..2e8716f3297 100644 --- a/mysql-test/t/func_time.test +++ b/mysql-test/t/func_time.test @@ -1417,3 +1417,12 @@ SELECT EXTRACT(HOUR FROM '1 02:00:00'), EXTRACT(HOUR FROM '26:00:00'); SELECT EXTRACT(HOUR FROM TIME'1 02:00:00'), EXTRACT(HOUR FROM TIME'26:00:00'); SELECT EXTRACT(HOUR FROM TIME('1 02:00:00')), EXTRACT(HOUR FROM TIME('26:00:00')); SELECT EXTRACT(DAY FROM TIME('1 02:00:00')), EXTRACT(DAY FROM TIME('26:00:00')); + + +--echo # +--echo # MDEV-5504 Server crashes in String::length on SELECT with MONTHNAME, GROUP BY, ROLLUP +--echo # +CREATE TABLE t1 (i INT); +INSERT INTO t1 VALUES (1),(2); +SELECT 1 FROM t1 GROUP BY MONTHNAME(0) WITH ROLLUP; +DROP TABLE t1; diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index b618ec038f2..b5d43786248 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -883,16 +883,13 @@ String* Item_func_monthname::val_str(String* str) { DBUG_ASSERT(fixed == 1); const char *month_name; - uint month= (uint) val_int(); uint err; + MYSQL_TIME ltime; - if (null_value || !month) - { - null_value=1; - return (String*) 0; - } - null_value=0; - month_name= locale->month_names->type_names[month-1]; + if ((null_value= (get_arg0_date(<ime, 0) || !ltime.month))) + return (String *) 0; + + month_name= locale->month_names->type_names[ltime.month - 1]; str->copy(month_name, (uint) strlen(month_name), &my_charset_utf8_bin, collation.collation, &err); return str; diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h index d97a5fbc903..7d865df8fea 100644 --- a/sql/item_timefunc.h +++ b/sql/item_timefunc.h @@ -134,14 +134,13 @@ public: }; -class Item_func_monthname :public Item_func_month +class Item_func_monthname :public Item_str_func { MY_LOCALE *locale; public: - Item_func_monthname(Item *a) :Item_func_month(a) {} + Item_func_monthname(Item *a) :Item_str_func(a) {} const char *func_name() const { return "monthname"; } String *val_str(String *str); - enum Item_result result_type () const { return STRING_RESULT; } void fix_length_and_dec(); bool check_partition_func_processor(uchar *int_arg) {return TRUE;} bool check_vcol_func_processor(uchar *int_arg) {return FALSE;} |