Commit 15639990 authored by Alexander Barkov's avatar Alexander Barkov

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
parent 4d5f5f4c
...@@ -2382,3 +2382,60 @@ Catalog Database Table Table_alias Column Column_alias Type Length Max length Is ...@@ -2382,3 +2382,60 @@ Catalog Database Table Table_alias Column Column_alias Type Length Max length Is
def DATE_ADD('2011-01-02 12:13:14', INTERVAL 1 MINUTE) 254 19 19 Y 0 0 8 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) DATE_ADD('2011-01-02 12:13:14', INTERVAL 1 MINUTE)
2011-01-02 12:14:14 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;
...@@ -1457,3 +1457,31 @@ SELECT EXTRACT(DAY FROM TIME('1 02:00:00')), EXTRACT(DAY FROM TIME('26:00:00')); ...@@ -1457,3 +1457,31 @@ SELECT EXTRACT(DAY FROM TIME('1 02:00:00')), EXTRACT(DAY FROM TIME('26:00:00'));
--enable_metadata --enable_metadata
SELECT DATE_ADD('2011-01-02 12:13:14', INTERVAL 1 MINUTE); SELECT DATE_ADD('2011-01-02 12:13:14', INTERVAL 1 MINUTE);
--disable_metadata --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;
...@@ -1480,12 +1480,42 @@ String *Item_temporal_func::val_str(String *str) ...@@ -1480,12 +1480,42 @@ String *Item_temporal_func::val_str(String *str)
} }
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) String *Item_temporal_hybrid_func::val_str_ascii(String *str)
{ {
DBUG_ASSERT(fixed == 1); DBUG_ASSERT(fixed == 1);
MYSQL_TIME ltime; MYSQL_TIME ltime;
if (get_date(&ltime, 0) || if (get_date(&ltime, 0) || fix_temporal_type(&ltime) ||
(null_value= my_TIME_to_str(&ltime, str, decimals))) (null_value= my_TIME_to_str(&ltime, str, decimals)))
return (String *) 0; return (String *) 0;
...@@ -2599,16 +2629,18 @@ bool Item_func_add_time::get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date) ...@@ -2599,16 +2629,18 @@ bool Item_func_add_time::get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date)
longlong seconds; longlong seconds;
int l_sign= sign, was_cut= 0; 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) || if (get_arg0_date(&l_time1, 0) ||
args[1]->get_time(&l_time2) || args[1]->get_time(&l_time2) ||
l_time1.time_type == MYSQL_TIMESTAMP_TIME || l_time1.time_type == MYSQL_TIMESTAMP_TIME ||
l_time2.time_type != MYSQL_TIMESTAMP_TIME) l_time2.time_type != MYSQL_TIMESTAMP_TIME)
return (null_value= 1); return (null_value= 1);
} }
else // ADDTIME function else
{ {
// ADDTIME function AND the first argument is TIME
if (args[0]->get_time(&l_time1) || if (args[0]->get_time(&l_time1) ||
args[1]->get_time(&l_time2) || args[1]->get_time(&l_time2) ||
l_time2.time_type == MYSQL_TIMESTAMP_DATETIME) l_time2.time_type == MYSQL_TIMESTAMP_DATETIME)
......
...@@ -541,6 +541,11 @@ public: ...@@ -541,6 +541,11 @@ public:
return cached_field_type == MYSQL_TYPE_STRING ? return cached_field_type == MYSQL_TYPE_STRING ?
collation.collation : &my_charset_bin; 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. Return string value in ASCII character set.
*/ */
......
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