#At file:///misc/mysql/forest/42146_/51-42146_/ based on revid:vvaintroub@stripped
2794 Tatiana A. Nurnberg 2009-02-13
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.
modified:
mysql-test/r/type_datetime.result
mysql-test/t/type_datetime.test
sql-common/my_time.c
per-file messages:
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.
=== modified file 'mysql-test/r/type_datetime.result'
--- a/mysql-test/r/type_datetime.result 2008-09-09 15:52:38 +0000
+++ b/mysql-test/r/type_datetime.result 2009-02-13 07:05:20 +0000
@@ -619,3 +619,22 @@ ERROR 42000: Invalid default value for '
create table t1 (t time default '916:00:00 a');
ERROR 42000: Invalid default value for 't'
set @@sql_mode= @org_mode;
+SELECT CAST('2006-08-10 10:11:12.0123450' AS DATETIME);
+CAST('2006-08-10 10:11:12.0123450' AS DATETIME)
+2006-08-10 10:11:12.012345
+Warnings:
+Warning 1292 Truncated incorrect datetime value: '2006-08-10 10:11:12.0123450'
+SELECT CAST('00000002006-000008-0000010 000010:0000011:00000012.0123450' AS DATETIME);
+CAST('00000002006-000008-0000010 000010:0000011:00000012.0123450' AS DATETIME)
+2006-08-10 10:11:12.012345
+Warnings:
+Warning 1292 Truncated incorrect datetime value: '00000002006-000008-0000010 000010:0000011:00000012.0123450'
+SELECT CAST('00000002006-000008-0000010 000010:0000011:00000012.012345' AS DATETIME);
+CAST('00000002006-000008-0000010 000010:0000011:00000012.012345' AS DATETIME)
+2006-08-10 10:11:12.012345
+SELECT CAST('2008-07-29T10:42:51.1234567' AS DateTime);
+CAST('2008-07-29T10:42:51.1234567' AS DateTime)
+2008-07-29 10:42:51.123456
+Warnings:
+Warning 1292 Truncated incorrect datetime value: '2008-07-29T10:42:51.1234567'
+End of 5.1 tests
=== modified file 'mysql-test/t/type_datetime.test'
--- a/mysql-test/t/type_datetime.test 2008-09-09 15:52:38 +0000
+++ b/mysql-test/t/type_datetime.test 2009-02-13 07:05:20 +0000
@@ -427,3 +427,22 @@ create table t1 (da date default '1962-0
--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('2006-08-10 10:11:12.0123450' AS DATETIME);
+
+# show that we ignore leading zeroes for all other fields
+SELECT CAST('00000002006-000008-0000010 000010:0000011:00000012.0123450' AS DATETIME);
+# once more with feeling (but no warnings)
+SELECT CAST('00000002006-000008-0000010 000010:0000011:00000012.012345' AS DATETIME);
+
+#
+# Bug #38435 - LONG Microseconds cause MySQL to fail a CAST to DATETIME or DATE
+#
+# show we truncate microseconds from the right
+SELECT CAST('2008-07-29T10:42:51.1234567' AS DateTime);
+
+--echo End of 5.1 tests
=== modified file 'sql-common/my_time.c'
--- a/sql-common/my_time.c 2009-01-09 13:22:15 +0000
+++ b/sql-common/my_time.c 2009-02-13 07:05:20 +0000
@@ -264,8 +264,19 @@ str_to_datetime(const char *str, uint le
{
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++;
| Thread |
|---|
| • bzr commit into mysql-5.1-bugteam branch (azundris:2794) Bug#38435 Bug#42146 | Tatiana A. Nurnberg | 13 Feb |