diff options
author | Tatiana A. Nurnberg <azundris@mysql.com> | 2009-02-13 19:07:03 +0100 |
---|---|---|
committer | Tatiana A. Nurnberg <azundris@mysql.com> | 2009-02-13 19:07:03 +0100 |
commit | 694323952aafe3030cf2d9bdc5cae77c3d817fbc (patch) | |
tree | b60043708db1a36d28b28295e1b49bba84498391 /sql-common | |
parent | 461cad77b4e068ecc2534150170a029e6f425407 (diff) | |
download | mariadb-git-694323952aafe3030cf2d9bdc5cae77c3d817fbc.tar.gz |
Bug#42146 - DATETIME fractional seconds parse error
Bug#38435 - LONG Microseconds cause MySQL to fail a CAST to DATETIME or DATE
Parsing of optional microsecond part in datetime did not
fail gracefully when field width was larger than the allowed
six places.
Now handles up to the correct six places, and disregards
any extra digits without messing up what we've already got.
mysql-test/r/type_datetime.result:
show graceful handling of overly long microsecond parts
(correct truncation).
mysql-test/t/type_datetime.test:
show graceful handling of overly long microsecond parts
(correct truncation).
sql-common/my_time.c:
Special case for time-parsing: for microsecond part,
leading zeroes are actually meaningful! Also, don't
break the entire date on more than the allowed six
digits in microsecond part, just truncate the extra
digits.
Diffstat (limited to 'sql-common')
-rw-r--r-- | sql-common/my_time.c | 13 |
1 files changed, 12 insertions, 1 deletions
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++; |