Commit 6bea77ae authored by Georgi Kodinov's avatar Georgi Kodinov

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.
parent 9ab59902
...@@ -2507,4 +2507,17 @@ LOCK TABLES t1 READ; ...@@ -2507,4 +2507,17 @@ LOCK TABLES t1 READ;
ALTER TABLE t1 COMMENT 'test'; ALTER TABLE t1 COMMENT 'test';
UNLOCK TABLES; UNLOCK TABLES;
DROP TABLE t1; 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 End of 5.1 tests
...@@ -751,4 +751,19 @@ UNLOCK TABLES; ...@@ -751,4 +751,19 @@ UNLOCK TABLES;
DROP TABLE t1; 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 --echo End of 5.1 tests
...@@ -2263,7 +2263,7 @@ void Item_func_min_max::fix_length_and_dec() ...@@ -2263,7 +2263,7 @@ void Item_func_min_max::fix_length_and_dec()
stored to the value pointer, if latter is provided. stored to the value pointer, if latter is provided.
RETURN 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 # index of the least/greatest argument
*/ */
...@@ -2277,6 +2277,14 @@ uint Item_func_min_max::cmp_datetimes(ulonglong *value) ...@@ -2277,6 +2277,14 @@ uint Item_func_min_max::cmp_datetimes(ulonglong *value)
Item **arg= args + i; Item **arg= args + i;
bool is_null; bool is_null;
longlong res= get_datetime_value(thd, &arg, 0, datetime_item, &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)) if ((null_value= args[i]->null_value))
return 0; return 0;
if (i == 0 || (res < min_max ? cmp_sign : -cmp_sign) > 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) ...@@ -2305,6 +2313,12 @@ String *Item_func_min_max::val_str(String *str)
if (null_value) if (null_value)
return 0; return 0;
str_res= args[min_max_idx]->val_str(str); 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); str_res->set_charset(collation.collation);
return str_res; return str_res;
} }
......
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