List:Commits« Previous MessageNext Message »
From:Tatjana A Nuernberg Date:January 16 2007 6:21pm
Subject:bk commit into 5.1 tree (tnurnberg:1.2390) BUG#23093
View as plain text  
Below is the list of changes that have just been committed into a local
5.1 repository of tnurnberg. When tnurnberg does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet@stripped, 2007-01-16 18:21:29+01:00, tnurnberg@stripped +3 -0
  Bug #23093 Implicit conversion of 9912101 to date does not match cast(9912101 as date)
  
  For dates given as integers, INSERT and friends parse as integers
  (meaning, dates with an odd number of digits are parsed right to left,
  zero-padding from the left), while CAST(), YEAR() etc. parse as strings
  (left-to-right). This can lead to counter-intuitive results for invalid
  dates (dates with no separators and an odd number of digits). Have the
  second group also throw an error on those dates.

  mysql-test/r/func_time.result@stripped, 2007-01-16 18:21:23+01:00, tnurnberg@stripped +18
-0
    Bug #23093 Implicit conversion of 9912101 to date does not match cast(9912101 as date)
    
    Show that we throw on dates with a odd number of digits
    (not counting 'T' in ISO-datetime) not just on INSERT, but on YEAR(),
    CAST() and everything else that goes through str_to_datetime() rather
    than number_to_datetime() as well.

  mysql-test/t/func_time.test@stripped, 2007-01-16 18:21:23+01:00, tnurnberg@stripped +16 -0
    Bug #23093 Implicit conversion of 9912101 to date does not match cast(9912101 as date)
    
    Show that we throw on dates with a odd number of digits
    (not counting 'T' in ISO-datetime) not just on INSERT, but on YEAR(),
    CAST() and everything else that goes through str_to_datetime() rather
    than number_to_datetime() as well.

  sql-common/my_time.c@stripped, 2007-01-16 18:21:23+01:00, tnurnberg@stripped +11 -5
    Bug #23093 Implicit conversion of 9912101 to date does not match cast(9912101 as date)
    
    For dates given as integers, INSERT and friends go through
    number_to_datetime(), while while CAST(), YEAR() etc. go through
    string_to_datetime(). Have string_to_datetime() reject numeric dates
    (those with no separators except, optionally, T for ISO-datetimes)
    with an odd number of digits.

# This is a BitKeeper patch.  What follows are the unified diffs for the
# set of deltas contained in the patch.  The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User:	tnurnberg
# Host:	sin.azundris.com
# Root:	/home/tnurnberg/work/mysql-5.1-maint-23093

--- 1.38/sql-common/my_time.c	2006-12-31 01:06:37 +01:00
+++ 1.39/sql-common/my_time.c	2007-01-16 18:21:23 +01:00
@@ -123,7 +123,7 @@ my_bool check_date(const MYSQL_TIME *lti
 			2	Date part was within ranges but date was wrong
 
   DESCRIPTION
-    At least the following formats are recogniced (based on number of digits)
+    At least the following formats are recognised (based on number of digits)
     YYMMDD, YYYYMMDD, YYMMDDHHMMSS, YYYYMMDDHHMMSS
     YY-MM-DD, YYYY-MM-DD, YY-MM-DD HH.MM.SS
     YYYYMMDDTHHMMSS  where T is a the character T (ISO8601)
@@ -169,7 +169,7 @@ str_to_datetime(const char *str, uint le
   const char *pos, *last_field_pos;
   const char *end=str+length;
   const uchar *format_position;
-  my_bool found_delimitier= 0, found_space= 0;
+  my_bool found_delimiter= 0, found_space= 0, found_t= 0;
   uint frac_pos, frac_len;
   DBUG_ENTER("str_to_datetime");
   DBUG_PRINT("ENTER",("str: %.*s",length,str));
@@ -199,7 +199,8 @@ str_to_datetime(const char *str, uint le
     (YYYY-MM-DD,  YYYYMMDD, YYYYYMMDDHHMMSS)
   */
   for (pos=str;
-       pos != end && (my_isdigit(&my_charset_latin1,*pos) || *pos == 'T');
+       pos != end && (my_isdigit(&my_charset_latin1,*pos) ||
+                      ((*pos == 'T') && (found_t= 1)));
        pos++)
     ;
 
@@ -213,9 +214,14 @@ str_to_datetime(const char *str, uint le
     field_length= year_length;
     is_internal_format= 1;
     format_position= internal_format_positions;
+
+    if((digits + found_t) % 2)
+      DBUG_RETURN(MYSQL_TIMESTAMP_ERROR);       /* odd number of digits, can't be a valid
date */
   }
   else
   {
+    found_t= 0;
+
     if (format_position[0] >= 3)                /* If year is after HHMMDD */
     {
       /*
@@ -320,7 +326,7 @@ str_to_datetime(const char *str, uint le
         found_space= 1;
       }
       str++;
-      found_delimitier= 1;                      /* Should be a 'normal' date */
+      found_delimiter= 1;                       /* Should be a 'normal' date */
     }
     /* Check if next position is AM/PM */
     if (i == format_position[6])                /* Seconds, time for AM/PM */
@@ -343,7 +349,7 @@ str_to_datetime(const char *str, uint le
     }
     last_field_pos= str;
   }
-  if (found_delimitier && !found_space && (flags &
TIME_DATETIME_ONLY))
+  if (found_delimiter && !found_space && (flags &
TIME_DATETIME_ONLY))
   {
     *was_cut= 1;
     DBUG_RETURN(MYSQL_TIMESTAMP_NONE);          /* Can't be a datetime */

--- 1.92/mysql-test/r/func_time.result	2006-11-29 21:30:58 +01:00
+++ 1.93/mysql-test/r/func_time.result	2007-01-16 18:21:23 +01:00
@@ -1217,4 +1217,22 @@ NULL
 select date_sub("0169-01-01 00:00:01",INTERVAL 2 SECOND);
 date_sub("0169-01-01 00:00:01",INTERVAL 2 SECOND)
 NULL
+select @d:=9912101, year(@d), month(@d), day(@d), cast(@d as date);
+@d:=9912101	year(@d)	month(@d)	day(@d)	cast(@d as date)
+9912101	NULL	NULL	NULL	NULL
+Warnings:
+Warning	1292	Incorrect datetime value: '9912101'
+Warning	1292	Incorrect datetime value: '9912101'
+Warning	1292	Incorrect datetime value: '9912101'
+Warning	1292	Incorrect datetime value: '9912101'
+create table t1 (d date, dt datetime, ts timestamp);
+insert into  t1 values (9912101,9912101,9912101) ;
+Warnings:
+Warning	1264	Out of range value for column 'd' at row 1
+Warning	1264	Out of range value for column 'dt' at row 1
+Warning	1265	Data truncated for column 'ts' at row 1
+select * from t1;
+d	dt	ts
+0000-00-00	0000-00-00 00:00:00	0000-00-00 00:00:00
+drop table t1;
 End of 5.1 tests

--- 1.77/mysql-test/t/func_time.test	2006-11-29 21:30:58 +01:00
+++ 1.78/mysql-test/t/func_time.test	2007-01-16 18:21:23 +01:00
@@ -710,5 +710,21 @@ select date_sub("90-01-01 00:00:01",INTE
 select date_sub("0069-01-01 00:00:01",INTERVAL 2 SECOND);
 select date_sub("0169-01-01 00:00:01",INTERVAL 2 SECOND);
 
+#
+# Bug #23093 - Implicit conversion of 9912101 to date
+#              does not match cast(9912101 as date)
+#
+
+# show that we throw error for odd number of digits in string dates without separator
+select @d:=9912101, year(@d), month(@d), day(@d), cast(@d as date);
+
+# show that ISO dates with 'T' delimiter still work
+select @d:="991210T1011", year(@d), month(@d), day(@d), cast(@d as date);
+
+# show that we throw for INSERT (integer date parsed by number_to_datetime())
+create table t1 (d date, dt datetime, ts timestamp);
+insert into  t1 values (9912101,9912101,9912101) ;
+select * from t1;
+drop table t1;
 
 --echo End of 5.1 tests
Thread
bk commit into 5.1 tree (tnurnberg:1.2390) BUG#23093Tatjana A Nuernberg16 Jan