maria-developers team mailing list archive
-
maria-developers team
-
Mailing list archive
-
Message #06740
MDEV-5450 Assertion ... mysql_type_to_time_type(cached_field_type) == ltime.time_type' fails ...
Hi Sergei,
Please review a patch for mdev-5450.
Thanks.
=== modified file 'mysql-test/r/func_time.result'
--- mysql-test/r/func_time.result 2013-12-19 08:39:40 +0000
+++ mysql-test/r/func_time.result 2014-01-31 12:58:42 +0000
@@ -2382,3 +2382,60 @@ Catalog Database Table Table_alias Colum
def DATE_ADD('2011-01-02 12:13:14', INTERVAL 1 MINUTE) 254 19 19 Y 0 0 8
DATE_ADD('2011-01-02 12:13:14', INTERVAL 1 MINUTE)
2011-01-02 12:14:14
+#
+# MDEV-5450 Assertion `cached_field_ type == MYSQL_TYPE_STRING || ltime.time_type == MYSQL_TIMESTAMP_NONE || mysql_type_to_time_type(cached_field_type) == ltime.time_type' fails with IF, ISNULL, ADDDATE
+#
+CREATE TABLE t1 (a DATETIME, b DATE);
+INSERT INTO t1 VALUES (NULL, '2012-12-21');
+SELECT IF(1,ADDDATE(IFNULL(a,b),0),1) FROM t1;
+IF(1,ADDDATE(IFNULL(a,b),0),1)
+2012-12-21 00:00:00
+SELECT CAST(ADDDATE(IFNULL(a,b),0) AS CHAR) FROM t1;
+CAST(ADDDATE(IFNULL(a,b),0) AS CHAR)
+2012-12-21 00:00:00
+SELECT CAST(ADDDATE(COALESCE(a,b),0) AS CHAR) FROM t1;
+CAST(ADDDATE(COALESCE(a,b),0) AS CHAR)
+2012-12-21 00:00:00
+SELECT CAST(ADDDATE(CASE WHEN 0 THEN a ELSE b END,0) AS CHAR) FROM t1;
+CAST(ADDDATE(CASE WHEN 0 THEN a ELSE b END,0) AS CHAR)
+2012-12-21 00:00:00
+SELECT IF(1,ADDTIME(IFNULL(a,b),0),1) FROM t1;
+IF(1,ADDTIME(IFNULL(a,b),0),1)
+2012-12-21 00:00:00
+SELECT CAST(ADDTIME(IFNULL(a,b),0) AS CHAR) FROM t1;
+CAST(ADDTIME(IFNULL(a,b),0) AS CHAR)
+2012-12-21 00:00:00
+SELECT CAST(ADDTIME(COALESCE(a,b),0) AS CHAR) FROM t1;
+CAST(ADDTIME(COALESCE(a,b),0) AS CHAR)
+2012-12-21 00:00:00
+SELECT CAST(ADDTIME(CASE WHEN 0 THEN a ELSE b END,0) AS CHAR) FROM t1;
+CAST(ADDTIME(CASE WHEN 0 THEN a ELSE b END,0) AS CHAR)
+2012-12-21 00:00:00
+DROP TABLE t1;
+CREATE TABLE t1 (a DATETIME, b TIME);
+INSERT INTO t1 VALUES (NULL, '00:20:12');
+SELECT IF(1,ADDDATE(IFNULL(a,b),0),1) FROM t1;
+IF(1,ADDDATE(IFNULL(a,b),0),1)
+0000-00-00 00:20:12
+SELECT CAST(ADDDATE(IFNULL(a,b),0) AS CHAR) FROM t1;
+CAST(ADDDATE(IFNULL(a,b),0) AS CHAR)
+0000-00-00 00:20:12
+SELECT CAST(ADDDATE(COALESCE(a,b),0) AS CHAR) FROM t1;
+CAST(ADDDATE(COALESCE(a,b),0) AS CHAR)
+0000-00-00 00:20:12
+SELECT CAST(ADDDATE(CASE WHEN 0 THEN a ELSE b END,0) AS CHAR) FROM t1;
+CAST(ADDDATE(CASE WHEN 0 THEN a ELSE b END,0) AS CHAR)
+0000-00-00 00:20:12
+SELECT IF(1,ADDTIME(IFNULL(a,b),0),1) FROM t1;
+IF(1,ADDTIME(IFNULL(a,b),0),1)
+NULL
+SELECT CAST(ADDTIME(IFNULL(a,b),0) AS CHAR) FROM t1;
+CAST(ADDTIME(IFNULL(a,b),0) AS CHAR)
+NULL
+SELECT CAST(ADDTIME(COALESCE(a,b),0) AS CHAR) FROM t1;
+CAST(ADDTIME(COALESCE(a,b),0) AS CHAR)
+NULL
+SELECT CAST(ADDTIME(CASE WHEN 0 THEN a ELSE b END,0) AS CHAR) FROM t1;
+CAST(ADDTIME(CASE WHEN 0 THEN a ELSE b END,0) AS CHAR)
+NULL
+DROP TABLE t1;
=== modified file 'mysql-test/t/func_time.test'
--- mysql-test/t/func_time.test 2013-12-19 08:39:40 +0000
+++ mysql-test/t/func_time.test 2014-01-31 12:55:44 +0000
@@ -1457,3 +1457,31 @@ SELECT EXTRACT(DAY FROM TIME('1 02:00:00
--enable_metadata
SELECT DATE_ADD('2011-01-02 12:13:14', INTERVAL 1 MINUTE);
--disable_metadata
+
+--echo #
+--echo # MDEV-5450 Assertion `cached_field_ type == MYSQL_TYPE_STRING || ltime.time_type == MYSQL_TIMESTAMP_NONE || mysql_type_to_time_type(cached_field_type) == ltime.time_type' fails with IF, ISNULL, ADDDATE
+--echo #
+
+CREATE TABLE t1 (a DATETIME, b DATE);
+INSERT INTO t1 VALUES (NULL, '2012-12-21');
+SELECT IF(1,ADDDATE(IFNULL(a,b),0),1) FROM t1;
+SELECT CAST(ADDDATE(IFNULL(a,b),0) AS CHAR) FROM t1;
+SELECT CAST(ADDDATE(COALESCE(a,b),0) AS CHAR) FROM t1;
+SELECT CAST(ADDDATE(CASE WHEN 0 THEN a ELSE b END,0) AS CHAR) FROM t1;
+SELECT IF(1,ADDTIME(IFNULL(a,b),0),1) FROM t1;
+SELECT CAST(ADDTIME(IFNULL(a,b),0) AS CHAR) FROM t1;
+SELECT CAST(ADDTIME(COALESCE(a,b),0) AS CHAR) FROM t1;
+SELECT CAST(ADDTIME(CASE WHEN 0 THEN a ELSE b END,0) AS CHAR) FROM t1;
+DROP TABLE t1;
+
+CREATE TABLE t1 (a DATETIME, b TIME);
+INSERT INTO t1 VALUES (NULL, '00:20:12');
+SELECT IF(1,ADDDATE(IFNULL(a,b),0),1) FROM t1;
+SELECT CAST(ADDDATE(IFNULL(a,b),0) AS CHAR) FROM t1;
+SELECT CAST(ADDDATE(COALESCE(a,b),0) AS CHAR) FROM t1;
+SELECT CAST(ADDDATE(CASE WHEN 0 THEN a ELSE b END,0) AS CHAR) FROM t1;
+SELECT IF(1,ADDTIME(IFNULL(a,b),0),1) FROM t1;
+SELECT CAST(ADDTIME(IFNULL(a,b),0) AS CHAR) FROM t1;
+SELECT CAST(ADDTIME(COALESCE(a,b),0) AS CHAR) FROM t1;
+SELECT CAST(ADDTIME(CASE WHEN 0 THEN a ELSE b END,0) AS CHAR) FROM t1;
+DROP TABLE t1;
=== modified file 'sql/item_timefunc.cc'
--- sql/item_timefunc.cc 2013-12-16 12:02:21 +0000
+++ sql/item_timefunc.cc 2014-01-31 12:35:17 +0000
@@ -1480,12 +1480,42 @@ String *Item_temporal_func::val_str(Stri
}
+bool Item_temporal_hybrid_func::fix_temporal_type(MYSQL_TIME *ltime)
+{
+ if (ltime->time_type < 0) /* MYSQL_TIMESTAMP_NONE, MYSQL_TIMESTAMP_ERROR */
+ return false;
+ switch (field_type())
+ {
+ case MYSQL_TYPE_TIME:
+ ltime->year= ltime->month= ltime->day= 0;
+ ltime->time_type= MYSQL_TIMESTAMP_TIME;
+ return false;
+ case MYSQL_TYPE_DATETIME:
+ case MYSQL_TYPE_TIMESTAMP:
+ ltime->neg= 0;
+ ltime->time_type= MYSQL_TIMESTAMP_DATETIME;
+ return false;
+ case MYSQL_TYPE_DATE:
+ ltime->neg= 0;
+ ltime->hour= ltime->minute= ltime->second= ltime->second_part= 0;
+ ltime->time_type= MYSQL_TIMESTAMP_DATE;
+ return false;
+ case MYSQL_TYPE_STRING: /* DATE_ADD, ADDTIME can return VARCHAR */
+ return false;
+ default:
+ DBUG_ASSERT(0);
+ return true;
+ }
+ return false;
+}
+
+
String *Item_temporal_hybrid_func::val_str_ascii(String *str)
{
DBUG_ASSERT(fixed == 1);
MYSQL_TIME ltime;
- if (get_date(<ime, 0) ||
+ if (get_date(<ime, 0) || fix_temporal_type(<ime) ||
(null_value= my_TIME_to_str(<ime, str, decimals)))
return (String *) 0;
@@ -2599,16 +2629,18 @@ bool Item_func_add_time::get_date(MYSQL_
longlong seconds;
int l_sign= sign, was_cut= 0;
- if (is_date) // TIMESTAMP function
+ if (cached_field_type == MYSQL_TYPE_DATETIME)
{
+ // TIMESTAMP function OR the first argument is DATE/DATETIME/TIMESTAMP
if (get_arg0_date(&l_time1, 0) ||
args[1]->get_time(&l_time2) ||
l_time1.time_type == MYSQL_TIMESTAMP_TIME ||
l_time2.time_type != MYSQL_TIMESTAMP_TIME)
return (null_value= 1);
}
- else // ADDTIME function
+ else
{
+ // ADDTIME function AND the first argument is TIME
if (args[0]->get_time(&l_time1) ||
args[1]->get_time(&l_time2) ||
l_time2.time_type == MYSQL_TIMESTAMP_DATETIME)
=== modified file 'sql/item_timefunc.h'
--- sql/item_timefunc.h 2013-12-16 12:02:21 +0000
+++ sql/item_timefunc.h 2014-01-31 12:13:19 +0000
@@ -542,6 +542,11 @@ class Item_temporal_hybrid_func: public
collation.collation : &my_charset_bin;
}
/**
+ Fix the returned timestamp to match field_type(),
+ which is important for val_str().
+ */
+ bool fix_temporal_type(MYSQL_TIME *ltime);
+ /**
Return string value in ASCII character set.
*/
String *val_str_ascii(String *str);
Follow ups