maria-developers team mailing list archive
-
maria-developers team
-
Mailing list archive
-
Message #09417
Please review MDEV-9604 crash in Item::save_in_field with empty enum value
Hi Sergei,
It fixes the reported crash, and additionally
inconsistencies when comparing temporal columns to empty strings:
In some cases it returned rows, in other cases it returned no rows,
depending on:
- the engine
- the type of comparison arguments (columns vs literals).
- presence of an index
Now everything works in the same way.
Note, this additional problem is not 10.1 specific, it existed in 10.0.
But 10.0 and 10.1 worked differently in certain cases.
Thanks!
diff --git a/mysql-test/r/type_datetime.result b/mysql-test/r/type_datetime.result
index 155e953..16990c2 100644
--- a/mysql-test/r/type_datetime.result
+++ b/mysql-test/r/type_datetime.result
@@ -747,7 +747,7 @@ EXPLAIN EXTENDED SELECT * FROM t1 FORCE INDEX(attime) WHERE AtTime = '2010-02-22
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ref AtTime AtTime 6 const 1 100.00
Warnings:
-Note 1003 select `test`.`t1`.`Id` AS `Id`,`test`.`t1`.`AtTime` AS `AtTime` from `test`.`t1` FORCE INDEX (`attime`) where (`test`.`t1`.`AtTime` = '2010-02-22 18:40:07')
+Note 1003 select `test`.`t1`.`Id` AS `Id`,`test`.`t1`.`AtTime` AS `AtTime` from `test`.`t1` FORCE INDEX (`attime`) where (`test`.`t1`.`AtTime` = TIMESTAMP'2010-02-22 18:40:07')
DROP TABLE t1;
SET NAMES latin1;
#
@@ -963,21 +963,20 @@ a
2001-01-01 00:00:00
Warnings:
Warning 1292 Truncated incorrect datetime value: '2001-01-01 00:00:00x'
-Warning 1292 Truncated incorrect datetime value: '2001-01-01 00:00:00x'
EXPLAIN EXTENDED
SELECT * FROM t1 WHERE LENGTH(a) != 20 AND a='2001-01-01 00:00:00x';
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
Warning 1292 Truncated incorrect datetime value: '2001-01-01 00:00:00x'
-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` = '2001-01-01 00:00:00x')
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` = TIMESTAMP'2001-01-01 00:00:00')
EXPLAIN EXTENDED
SELECT * FROM t1 WHERE LENGTH(a)!=30+RAND() AND a='2001-01-01 00:00:00x';
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
Warning 1292 Truncated incorrect datetime value: '2001-01-01 00:00:00x'
-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where ((`test`.`t1`.`a` = '2001-01-01 00:00:00x') and (<cache>(length(TIMESTAMP'2001-01-01 00:00:00')) <> (30 + rand())))
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where ((`test`.`t1`.`a` = TIMESTAMP'2001-01-01 00:00:00') and (<cache>(length(TIMESTAMP'2001-01-01 00:00:00')) <> (30 + rand())))
DROP TABLE t1;
CREATE TABLE t1 (a DATETIME);;
INSERT INTO t1 VALUES ('2001-01-01 00:00:00'),('2001-01-01 00:00:01');
@@ -993,20 +992,20 @@ SELECT * FROM t1 WHERE LENGTH(a)=19 AND a=' 2001-01-01 00:00:00';
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` = ' 2001-01-01 00:00:00')
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` = TIMESTAMP'2001-01-01 00:00:00')
EXPLAIN EXTENDED
SELECT * FROM t1 WHERE LENGTH(a)=19+RAND() AND a=' 2001-01-01 00:00:00';
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where ((`test`.`t1`.`a` = ' 2001-01-01 00:00:00') and (<cache>(length(TIMESTAMP'2001-01-01 00:00:00')) = (19 + rand())))
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where ((`test`.`t1`.`a` = TIMESTAMP'2001-01-01 00:00:00') and (<cache>(length(TIMESTAMP'2001-01-01 00:00:00')) = (19 + rand())))
EXPLAIN EXTENDED
SELECT * FROM t1 WHERE LENGTH(a)=30+RAND() AND a=' garbage ';
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
Warning 1292 Incorrect datetime value: ' garbage '
-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where ((`test`.`t1`.`a` = ' garbage ') and (length(`test`.`t1`.`a`) = (30 + rand())))
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where ((`test`.`t1`.`a` = TIMESTAMP'0000-00-00 00:00:00') and (<cache>(length(TIMESTAMP'0000-00-00 00:00:00')) = (30 + rand())))
DROP TABLE t1;
CREATE TABLE t1 (a DATETIME);;
INSERT INTO t1 VALUES ('2001-01-01 00:00:00'),('2001-01-01 00:00:01');
@@ -1076,13 +1075,13 @@ SELECT * FROM t1 WHERE LENGTH(a)=19 AND a=TIME'00:00:00';
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` = TIME'00:00:00')
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` = TIMESTAMP'2001-01-01 00:00:00')
EXPLAIN EXTENDED
SELECT * FROM t1 WHERE LENGTH(a)=40+RAND() AND a=TIME'00:00:00';
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where ((`test`.`t1`.`a` = TIME'00:00:00') and (<cache>(length(TIMESTAMP'2001-01-01 00:00:00')) = (40 + rand())))
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where ((`test`.`t1`.`a` = TIMESTAMP'2001-01-01 00:00:00') and (<cache>(length(TIMESTAMP'2001-01-01 00:00:00')) = (40 + rand())))
DROP TABLE t1;
#
# MDEV-8795 Equal expression propagation does not work for temporal literals
diff --git a/mysql-test/r/type_temporal_innodb.result b/mysql-test/r/type_temporal_innodb.result
new file mode 100644
index 0000000..425e499a
--- /dev/null
+++ b/mysql-test/r/type_temporal_innodb.result
@@ -0,0 +1,156 @@
+#
+# MDEV-9604 crash in Item::save_in_field with empty enum value
+#
+SELECT TIME'00:00:00'='';
+TIME'00:00:00'=''
+1
+Warnings:
+Warning 1292 Truncated incorrect time value: ''
+CREATE TABLE t1 (a ENUM('a'), b TIME, c INT, KEY(b)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES ('','00:00:00',0);
+Warnings:
+Warning 1265 Data truncated for column 'a' at row 1
+SELECT * FROM t1 WHERE b='';
+a b c
+ 00:00:00 0
+Warnings:
+Warning 1292 Truncated incorrect time value: ''
+SELECT * FROM t1 IGNORE KEY (b) WHERE b='';
+a b c
+ 00:00:00 0
+Warnings:
+Warning 1292 Truncated incorrect time value: ''
+SELECT * FROM t1 WHERE a=b;
+a b c
+ 00:00:00 0
+Warnings:
+Warning 1292 Truncated incorrect time value: ''
+SELECT 1 FROM t1 WHERE (SELECT a FROM t1 group by c) = b;
+1
+1
+Warnings:
+Warning 1292 Truncated incorrect time value: ''
+ALTER TABLE t1 ENGINE=MyISAM;
+SELECT * FROM t1 WHERE b='';
+a b c
+ 00:00:00 0
+Warnings:
+Warning 1292 Truncated incorrect time value: ''
+SELECT * FROM t1 IGNORE KEY (b) WHERE b='';
+a b c
+ 00:00:00 0
+Warnings:
+Warning 1292 Truncated incorrect time value: ''
+SELECT * FROM t1 WHERE a=b;
+a b c
+ 00:00:00 0
+Warnings:
+Warning 1292 Truncated incorrect time value: ''
+SELECT 1 FROM t1 WHERE (SELECT a FROM t1 group by c) = b;
+1
+1
+Warnings:
+Warning 1292 Truncated incorrect time value: ''
+DROP TABLE t1;
+SELECT DATE'0000-00-00'='';
+DATE'0000-00-00'=''
+1
+Warnings:
+Warning 1292 Incorrect datetime value: ''
+CREATE TABLE t1 (a ENUM('a'), b DATE, c INT, KEY(b)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES ('','0000-00-00',0);
+Warnings:
+Warning 1265 Data truncated for column 'a' at row 1
+SELECT * FROM t1 WHERE b='';
+a b c
+ 0000-00-00 0
+Warnings:
+Warning 1292 Incorrect datetime value: ''
+SELECT * FROM t1 IGNORE KEY (b) WHERE b='';
+a b c
+ 0000-00-00 0
+Warnings:
+Warning 1292 Incorrect datetime value: ''
+SELECT * FROM t1 WHERE a=b;
+a b c
+ 0000-00-00 0
+Warnings:
+Warning 1292 Incorrect datetime value: ''
+SELECT 1 FROM t1 WHERE (SELECT a FROM t1 group by c) = b;
+1
+1
+Warnings:
+Warning 1292 Incorrect datetime value: ''
+ALTER TABLE t1 ENGINE=MyISAM;
+SELECT * FROM t1 WHERE b='';
+a b c
+ 0000-00-00 0
+Warnings:
+Warning 1292 Incorrect datetime value: ''
+SELECT * FROM t1 IGNORE KEY (b) WHERE b='';
+a b c
+ 0000-00-00 0
+Warnings:
+Warning 1292 Incorrect datetime value: ''
+SELECT * FROM t1 WHERE a=b;
+a b c
+ 0000-00-00 0
+Warnings:
+Warning 1292 Incorrect datetime value: ''
+SELECT 1 FROM t1 WHERE (SELECT a FROM t1 group by c) = b;
+1
+1
+Warnings:
+Warning 1292 Incorrect datetime value: ''
+DROP TABLE t1;
+SELECT TIMESTAMP'0000-00-00 00:00:00'='';
+TIMESTAMP'0000-00-00 00:00:00'=''
+1
+Warnings:
+Warning 1292 Incorrect datetime value: ''
+CREATE TABLE t1 (a ENUM('a'), b DATETIME, c INT, KEY(b)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES ('','0000-00-00 00:00:00',0);
+Warnings:
+Warning 1265 Data truncated for column 'a' at row 1
+SELECT * FROM t1 WHERE b='';
+a b c
+ 0000-00-00 00:00:00 0
+Warnings:
+Warning 1292 Incorrect datetime value: ''
+SELECT * FROM t1 IGNORE KEY (b) WHERE b='';
+a b c
+ 0000-00-00 00:00:00 0
+Warnings:
+Warning 1292 Incorrect datetime value: ''
+SELECT * FROM t1 WHERE a=b;
+a b c
+ 0000-00-00 00:00:00 0
+Warnings:
+Warning 1292 Incorrect datetime value: ''
+SELECT 1 FROM t1 WHERE (SELECT a FROM t1 group by c) = b;
+1
+1
+Warnings:
+Warning 1292 Incorrect datetime value: ''
+ALTER TABLE t1 ENGINE=MyISAM;
+SELECT * FROM t1 WHERE b='';
+a b c
+ 0000-00-00 00:00:00 0
+Warnings:
+Warning 1292 Incorrect datetime value: ''
+SELECT * FROM t1 IGNORE KEY (b) WHERE b='';
+a b c
+ 0000-00-00 00:00:00 0
+Warnings:
+Warning 1292 Incorrect datetime value: ''
+SELECT * FROM t1 WHERE a=b;
+a b c
+ 0000-00-00 00:00:00 0
+Warnings:
+Warning 1292 Incorrect datetime value: ''
+SELECT 1 FROM t1 WHERE (SELECT a FROM t1 group by c) = b;
+1
+1
+Warnings:
+Warning 1292 Incorrect datetime value: ''
+DROP TABLE t1;
diff --git a/mysql-test/r/type_timestamp.result b/mysql-test/r/type_timestamp.result
index fcdef62..a579f69 100644
--- a/mysql-test/r/type_timestamp.result
+++ b/mysql-test/r/type_timestamp.result
@@ -818,21 +818,20 @@ a
2001-01-01 00:00:00
Warnings:
Warning 1292 Truncated incorrect datetime value: '2001-01-01 00:00:00x'
-Warning 1292 Truncated incorrect datetime value: '2001-01-01 00:00:00x'
EXPLAIN EXTENDED
SELECT * FROM t1 WHERE LENGTH(a) != 20 AND a='2001-01-01 00:00:00x';
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
Warning 1292 Truncated incorrect datetime value: '2001-01-01 00:00:00x'
-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` = '2001-01-01 00:00:00x')
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` = TIMESTAMP'2001-01-01 00:00:00')
EXPLAIN EXTENDED
SELECT * FROM t1 WHERE LENGTH(a)!=30+RAND() AND a='2001-01-01 00:00:00x';
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
Warning 1292 Truncated incorrect datetime value: '2001-01-01 00:00:00x'
-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where ((`test`.`t1`.`a` = '2001-01-01 00:00:00x') and (<cache>(length(TIMESTAMP'2001-01-01 00:00:00')) <> (30 + rand())))
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where ((`test`.`t1`.`a` = TIMESTAMP'2001-01-01 00:00:00') and (<cache>(length(TIMESTAMP'2001-01-01 00:00:00')) <> (30 + rand())))
DROP TABLE t1;
CREATE TABLE t1 (a TIMESTAMP);;
INSERT INTO t1 VALUES ('2001-01-01 00:00:00'),('2001-01-01 00:00:01');
@@ -848,20 +847,20 @@ SELECT * FROM t1 WHERE LENGTH(a)=19 AND a=' 2001-01-01 00:00:00';
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` = ' 2001-01-01 00:00:00')
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` = TIMESTAMP'2001-01-01 00:00:00')
EXPLAIN EXTENDED
SELECT * FROM t1 WHERE LENGTH(a)=19+RAND() AND a=' 2001-01-01 00:00:00';
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where ((`test`.`t1`.`a` = ' 2001-01-01 00:00:00') and (<cache>(length(TIMESTAMP'2001-01-01 00:00:00')) = (19 + rand())))
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where ((`test`.`t1`.`a` = TIMESTAMP'2001-01-01 00:00:00') and (<cache>(length(TIMESTAMP'2001-01-01 00:00:00')) = (19 + rand())))
EXPLAIN EXTENDED
SELECT * FROM t1 WHERE LENGTH(a)=30+RAND() AND a=' garbage ';
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
Warning 1292 Incorrect datetime value: ' garbage '
-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where ((`test`.`t1`.`a` = ' garbage ') and (length(`test`.`t1`.`a`) = (30 + rand())))
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where ((`test`.`t1`.`a` = TIMESTAMP'0000-00-00 00:00:00') and (<cache>(length(TIMESTAMP'0000-00-00 00:00:00')) = (30 + rand())))
DROP TABLE t1;
CREATE TABLE t1 (a TIMESTAMP);;
INSERT INTO t1 VALUES ('2001-01-01 00:00:00'),('2001-01-01 00:00:01');
@@ -931,13 +930,13 @@ SELECT * FROM t1 WHERE LENGTH(a)=19 AND a=TIME'00:00:00';
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` = TIME'00:00:00')
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` = TIMESTAMP'2001-01-01 00:00:00')
EXPLAIN EXTENDED
SELECT * FROM t1 WHERE LENGTH(a)=40+RAND() AND a=TIME'00:00:00';
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where ((`test`.`t1`.`a` = TIME'00:00:00') and (<cache>(length(TIMESTAMP'2001-01-01 00:00:00')) = (40 + rand())))
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where ((`test`.`t1`.`a` = TIMESTAMP'2001-01-01 00:00:00') and (<cache>(length(TIMESTAMP'2001-01-01 00:00:00')) = (40 + rand())))
DROP TABLE t1;
#
# End of 10.1 tests
diff --git a/mysql-test/t/type_temporal_innodb.test b/mysql-test/t/type_temporal_innodb.test
new file mode 100644
index 0000000..ac5daca
--- /dev/null
+++ b/mysql-test/t/type_temporal_innodb.test
@@ -0,0 +1,60 @@
+--source include/have_innodb.inc
+
+#
+# testing of temporal data types with InnoDB
+#
+
+
+--echo #
+--echo # MDEV-9604 crash in Item::save_in_field with empty enum value
+--echo #
+
+SELECT TIME'00:00:00'='';
+
+CREATE TABLE t1 (a ENUM('a'), b TIME, c INT, KEY(b)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES ('','00:00:00',0);
+SELECT * FROM t1 WHERE b='';
+SELECT * FROM t1 IGNORE KEY (b) WHERE b='';
+SELECT * FROM t1 WHERE a=b;
+SELECT 1 FROM t1 WHERE (SELECT a FROM t1 group by c) = b;
+
+ALTER TABLE t1 ENGINE=MyISAM;
+SELECT * FROM t1 WHERE b='';
+SELECT * FROM t1 IGNORE KEY (b) WHERE b='';
+SELECT * FROM t1 WHERE a=b;
+SELECT 1 FROM t1 WHERE (SELECT a FROM t1 group by c) = b;
+DROP TABLE t1;
+
+
+SELECT DATE'0000-00-00'='';
+
+CREATE TABLE t1 (a ENUM('a'), b DATE, c INT, KEY(b)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES ('','0000-00-00',0);
+SELECT * FROM t1 WHERE b='';
+SELECT * FROM t1 IGNORE KEY (b) WHERE b='';
+SELECT * FROM t1 WHERE a=b;
+SELECT 1 FROM t1 WHERE (SELECT a FROM t1 group by c) = b;
+
+ALTER TABLE t1 ENGINE=MyISAM;
+SELECT * FROM t1 WHERE b='';
+SELECT * FROM t1 IGNORE KEY (b) WHERE b='';
+SELECT * FROM t1 WHERE a=b;
+SELECT 1 FROM t1 WHERE (SELECT a FROM t1 group by c) = b;
+DROP TABLE t1;
+
+
+SELECT TIMESTAMP'0000-00-00 00:00:00'='';
+
+CREATE TABLE t1 (a ENUM('a'), b DATETIME, c INT, KEY(b)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES ('','0000-00-00 00:00:00',0);
+SELECT * FROM t1 WHERE b='';
+SELECT * FROM t1 IGNORE KEY (b) WHERE b='';
+SELECT * FROM t1 WHERE a=b;
+SELECT 1 FROM t1 WHERE (SELECT a FROM t1 group by c) = b;
+
+ALTER TABLE t1 ENGINE=MyISAM;
+SELECT * FROM t1 WHERE b='';
+SELECT * FROM t1 IGNORE KEY (b) WHERE b='';
+SELECT * FROM t1 WHERE a=b;
+SELECT 1 FROM t1 WHERE (SELECT a FROM t1 group by c) = b;
+DROP TABLE t1;
diff --git a/sql/field.cc b/sql/field.cc
index 895f8a0..ffa7beb 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -5624,6 +5624,18 @@ Item *Field_temporal::get_equal_const_item_datetime(THD *thd,
}
break;
case ANY_SUBST:
+ if (!is_temporal_type_with_date(const_item->field_type()))
+ {
+ MYSQL_TIME ltime;
+ if (const_item->get_date_with_conversion(<ime,
+ TIME_FUZZY_DATES |
+ TIME_INVALID_DATES))
+ return NULL;
+ return new (thd->mem_root)
+ Item_datetime_literal_for_invalid_dates(thd, <ime,
+ ltime.second_part ?
+ TIME_SECOND_PART_DIGITS : 0);
+ }
break;
}
return const_item;
@@ -5932,7 +5944,10 @@ Item *Field_time::get_equal_const_item(THD *thd, const Context &ctx,
{
MYSQL_TIME ltime;
// Get the value of const_item with conversion from DATETIME to TIME
- if (const_item->get_time_with_conversion(thd, <ime, TIME_TIME_ONLY))
+ if (const_item->get_time_with_conversion(thd, <ime,
+ TIME_TIME_ONLY |
+ TIME_FUZZY_DATES |
+ TIME_INVALID_DATES))
return NULL;
/*
Replace a DATE/DATETIME constant to a TIME constant:
diff --git a/sql/item.cc b/sql/item.cc
index a330cee..fe49ce4 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -1301,6 +1301,22 @@ bool Item::get_date(MYSQL_TIME *ltime,ulonglong fuzzydate)
if allowed, otherwise - null.
*/
bzero((char*) ltime,sizeof(*ltime));
+ if (fuzzydate & TIME_TIME_ONLY)
+ {
+ /*
+ In the following scenario:
+ - The caller expected to get a TIME value
+ - Item returned a not NULL string or numeric value
+ - But then conversion from string or number to TIME failed
+ we need to change the default time_type from MYSQL_TIMESTAMP_DATE
+ (which was set in bzero) to MYSQL_TIMESTAMP_TIME and therefore
+ return TIME'00:00:00' rather than DATE'0000-00-00'.
+ If we don't do this, methods like Item::get_time_with_conversion()
+ will erroneously subtract CURRENT_DATE from '0000-00-00 00:00:00'
+ and return TIME'-838:59:59' instead of TIME'00:00:00' as a result.
+ */
+ ltime->time_type= MYSQL_TIMESTAMP_TIME;
+ }
return null_value|= !(fuzzydate & TIME_FUZZY_DATES);
}
Follow ups