MySQL Lists are EOL. Please join:

List:Commits« Previous MessageNext Message »
From:Tatiana A. Nurnberg Date:February 13 2009 6:07pm
Subject:bzr commit into mysql-5.1-bugteam branch (azundris:2794) Bug#38435 Bug#42146
View as plain text  
#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 18:07:03 +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(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

=== 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 18:07:03 +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(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

=== 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 18:07:03 +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#42146Tatiana A. Nurnberg13 Feb