From 3b36a677ba839448a25b4e4f90a1bf1caf99bb76 Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Fri, 20 Aug 2010 11:52:16 +0300 Subject: [PATCH] Bug #55826: create table .. select crashes with when KILL_BAD_DATA is returned Two problems discovered with the LEAST()/GREATEST() functions: 1. The check for a null value should happen even after the second call to val_str() in the args. This is important because two subsequent calls to the same Item::val_str() may yield different results. Fixed by checking for NULL value before dereferencing the string result. 2. While looping over the arguments and evaluating them the loop should stop if there was an error evaluating so far or the statement was killed. Fixed by checking for error and bailing out. --- mysql-test/suite/innodb/r/innodb_mysql.result | 13 +++++++++++++ mysql-test/suite/innodb/t/innodb_mysql.test | 15 +++++++++++++++ sql/item_func.cc | 16 +++++++++++++++- 3 files changed, 43 insertions(+), 1 deletion(-) diff --git a/mysql-test/suite/innodb/r/innodb_mysql.result b/mysql-test/suite/innodb/r/innodb_mysql.result index 8765f58b120..cb0e2a35e34 100644 --- a/mysql-test/suite/innodb/r/innodb_mysql.result +++ b/mysql-test/suite/innodb/r/innodb_mysql.result @@ -2507,4 +2507,17 @@ LOCK TABLES t1 READ; ALTER TABLE t1 COMMENT 'test'; UNLOCK TABLES; DROP TABLE t1; +# +# Bug#55826: create table .. select crashes with when KILL_BAD_DATA +# is returned +# +CREATE TABLE t1(a INT) ENGINE=innodb; +INSERT INTO t1 VALUES (0); +SET SQL_MODE='STRICT_ALL_TABLES'; +CREATE TABLE t2 +SELECT LEAST((SELECT '' FROM t1),NOW()) FROM `t1`; +ERROR 22007: Incorrect datetime value: '' for column 'NOW()' at row 1 +DROP TABLE t1,t2; +ERROR 42S02: Unknown table 't2' +SET SQL_MODE=DEFAULT; End of 5.1 tests diff --git a/mysql-test/suite/innodb/t/innodb_mysql.test b/mysql-test/suite/innodb/t/innodb_mysql.test index 80f14d32eb8..c8acc6813e8 100644 --- a/mysql-test/suite/innodb/t/innodb_mysql.test +++ b/mysql-test/suite/innodb/t/innodb_mysql.test @@ -751,4 +751,19 @@ UNLOCK TABLES; DROP TABLE t1; +--echo # +--echo # Bug#55826: create table .. select crashes with when KILL_BAD_DATA +--echo # is returned +--echo # + +CREATE TABLE t1(a INT) ENGINE=innodb; +INSERT INTO t1 VALUES (0); +SET SQL_MODE='STRICT_ALL_TABLES'; +--error ER_TRUNCATED_WRONG_VALUE +CREATE TABLE t2 + SELECT LEAST((SELECT '' FROM t1),NOW()) FROM `t1`; +DROP TABLE t1,t2; +SET SQL_MODE=DEFAULT; + + --echo End of 5.1 tests diff --git a/sql/item_func.cc b/sql/item_func.cc index eecdc801512..f022a218889 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -2263,7 +2263,7 @@ void Item_func_min_max::fix_length_and_dec() stored to the value pointer, if latter is provided. RETURN - 0 If one of arguments is NULL + 0 If one of arguments is NULL or there was a execution error # index of the least/greatest argument */ @@ -2277,6 +2277,14 @@ uint Item_func_min_max::cmp_datetimes(ulonglong *value) Item **arg= args + i; bool is_null; longlong res= get_datetime_value(thd, &arg, 0, datetime_item, &is_null); + + /* Check if we need to stop (because of error or KILL) and stop the loop */ + if (thd->is_error()) + { + null_value= 1; + return 0; + } + if ((null_value= args[i]->null_value)) return 0; if (i == 0 || (res < min_max ? cmp_sign : -cmp_sign) > 0) @@ -2305,6 +2313,12 @@ String *Item_func_min_max::val_str(String *str) if (null_value) return 0; str_res= args[min_max_idx]->val_str(str); + if (args[min_max_idx]->null_value) + { + // check if the call to val_str() above returns a NULL value + null_value= 1; + return NULL; + } str_res->set_charset(collation.collation); return str_res; }