diff options
-rw-r--r-- | mysql-test/r/type_datetime.result | 19 | ||||
-rw-r--r-- | mysql-test/t/type_datetime.test | 19 | ||||
-rw-r--r-- | sql-common/my_time.c | 13 |
3 files changed, 50 insertions, 1 deletions
diff --git a/mysql-test/r/type_datetime.result b/mysql-test/r/type_datetime.result index 6a692ed58e4..b6281443751 100644 --- a/mysql-test/r/type_datetime.result +++ b/mysql-test/r/type_datetime.result @@ -619,3 +619,22 @@ ERROR 42000: Invalid default value for 'da' create table t1 (t time default '916:00:00 a'); ERROR 42000: Invalid default value for 't' set @@sql_mode= @org_mode; +SELECT CAST(CAST('2006-08-10 10:11:12.0123450' AS DATETIME) AS DECIMAL(30,7)); +CAST(CAST('2006-08-10 10:11:12.0123450' AS DATETIME) AS DECIMAL(30,7)) +20060810101112.0123450 +Warnings: +Warning 1292 Truncated incorrect datetime value: '2006-08-10 10:11:12.0123450' +SELECT CAST(CAST('00000002006-000008-0000010 000010:0000011:00000012.0123450' AS DATETIME) AS DECIMAL(30,7)); +CAST(CAST('00000002006-000008-0000010 000010:0000011:00000012.0123450' AS DATETIME) AS DECIMAL(30,7)) +20060810101112.0123450 +Warnings: +Warning 1292 Truncated incorrect datetime value: '00000002006-000008-0000010 000010:0000011:00000012.0123450' +SELECT CAST(CAST('00000002006-000008-0000010 000010:0000011:00000012.012345' AS DATETIME) AS DECIMAL(30,7)); +CAST(CAST('00000002006-000008-0000010 000010:0000011:00000012.012345' AS DATETIME) AS DECIMAL(30,7)) +20060810101112.0123450 +SELECT CAST(CAST('2008-07-29T10:42:51.1234567' AS DateTime) AS DECIMAL(30,7)); +CAST(CAST('2008-07-29T10:42:51.1234567' AS DateTime) AS DECIMAL(30,7)) +20080729104251.1234560 +Warnings: +Warning 1292 Truncated incorrect datetime value: '2008-07-29T10:42:51.1234567' +End of 5.1 tests diff --git a/mysql-test/t/type_datetime.test b/mysql-test/t/type_datetime.test index eb1b7bde844..d4fa6bed186 100644 --- a/mysql-test/t/type_datetime.test +++ b/mysql-test/t/type_datetime.test @@ -427,3 +427,22 @@ create table t1 (da date default '1962-03-32 23:33:34', dt datetime default '196 --error 1067 create table t1 (t time default '916:00:00 a'); set @@sql_mode= @org_mode; + +# +# Bug #42146 - DATETIME fractional seconds parse error +# +# show we trucate microseconds from the right -- special case: leftmost is 0 +SELECT CAST(CAST('2006-08-10 10:11:12.0123450' AS DATETIME) AS DECIMAL(30,7)); + +# show that we ignore leading zeroes for all other fields +SELECT CAST(CAST('00000002006-000008-0000010 000010:0000011:00000012.0123450' AS DATETIME) AS DECIMAL(30,7)); +# once more with feeling (but no warnings) +SELECT CAST(CAST('00000002006-000008-0000010 000010:0000011:00000012.012345' AS DATETIME) AS DECIMAL(30,7)); + +# +# Bug #38435 - LONG Microseconds cause MySQL to fail a CAST to DATETIME or DATE +# +# show we truncate microseconds from the right +SELECT CAST(CAST('2008-07-29T10:42:51.1234567' AS DateTime) AS DECIMAL(30,7)); + +--echo End of 5.1 tests diff --git a/sql-common/my_time.c b/sql-common/my_time.c index 155e0237e3c..747c5797ed4 100644 --- a/sql-common/my_time.c +++ b/sql-common/my_time.c @@ -264,8 +264,19 @@ str_to_datetime(const char *str, uint length, MYSQL_TIME *l_time, { const char *start= str; ulong tmp_value= (uint) (uchar) (*str++ - '0'); + + /* + Internal format means no delimiters; every field has a fixed + width. Otherwise, we scan until we find a delimiter and discard + leading zeroes -- except for the microsecond part, where leading + zeroes are significant, and where we never process more than six + digits. + */ + my_bool scan_until_delim= !is_internal_format && + ((i != format_position[6])); + while (str != end && my_isdigit(&my_charset_latin1,str[0]) && - (!is_internal_format || --field_length)) + (scan_until_delim || --field_length)) { tmp_value=tmp_value*10 + (ulong) (uchar) (*str - '0'); str++; |