summaryrefslogtreecommitdiff
path: root/sql-common
diff options
context:
space:
mode:
authorTatiana A. Nurnberg <azundris@mysql.com>2009-02-13 19:07:03 +0100
committerTatiana A. Nurnberg <azundris@mysql.com>2009-02-13 19:07:03 +0100
commiteeef9533faa7275eed5da0dce74472900be3ae4f (patch)
treeb60043708db1a36d28b28295e1b49bba84498391 /sql-common
parent3ff6608722bc33cff72b13f919b54f70815ee21e (diff)
downloadmariadb-git-eeef9533faa7275eed5da0dce74472900be3ae4f.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.c13
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++;