From 1b0f0b0afc6cf33db2b39bf2653bf6f6ddef015b Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 6 Aug 2004 10:01:29 +0400 Subject: [PATCH] Fix for bug #4756 "STR_TO_DATE() returning bad results with AM/PM". Added support of converion specifiers mentioned in manual but missing in code. mysql-test/r/date_formats.result: Added tests of str_to_date() with new %T, %r and %V, %v conversion specifiers, and also some other specifiers for which tests were missing previously. mysql-test/t/date_formats.test: Added tests of str_to_date() and new %T, %r and %V, %v conversion specifiers, and also some other specifiers for which tests were missing previously. sql/item_timefunc.cc: Added support for %T, %r, %V, %v, %X, %x conversion specifiers to extract_date_time() function. Also simplified a bit calculation of dates from week number. --- mysql-test/r/date_formats.result | 72 ++++++++++++++-- mysql-test/t/date_formats.test | 18 +++- sql/item_timefunc.cc | 140 ++++++++++++++++++++++++------- 3 files changed, 189 insertions(+), 41 deletions(-) diff --git a/mysql-test/r/date_formats.result b/mysql-test/r/date_formats.result index 6a4935ef3f8..23da99f38bb 100644 --- a/mysql-test/r/date_formats.result +++ b/mysql-test/r/date_formats.result @@ -90,16 +90,23 @@ insert into t1 values ('2003-01-02 11:11:12Pm', '%Y-%m-%d %h:%i:%S%p'), ('10:20:10', '%H:%i:%s'), ('10:20:10', '%h:%i:%s.%f'), +('10:20:10', '%T'), ('10:20:10AM', '%h:%i:%s%p'), +('10:20:10AM', '%r'), ('10:20:10.44AM', '%h:%i:%s.%f%p'), ('15-01-2001 12:59:58', '%d-%m-%Y %H:%i:%S'), ('15 September 2001', '%d %M %Y'), ('15 SEPTEMB 2001', '%d %M %Y'), ('15 MAY 2001', '%d %b %Y'), +('15th May 2001', '%D %b %Y'), ('Sunday 15 MAY 2001', '%W %d %b %Y'), ('Sund 15 MAY 2001', '%W %d %b %Y'), ('Tuesday 00 2002', '%W %U %Y'), ('Thursday 53 1998', '%W %u %Y'), +('Sunday 01 2001', '%W %v %x'), +('Tuesday 52 2001', '%W %V %X'), +('060 2004', '%j %Y'), +('4 53 1998', '%w %u %Y'), ('15-01-2001', '%d-%m-%Y %H:%i:%S'), ('15-01-20', '%d-%m-%y'), ('15-2001-1', '%d-%Y-%c'); @@ -114,16 +121,23 @@ date format str_to_date 2003-01-02 11:11:12Pm %Y-%m-%d %h:%i:%S%p 2003-01-02 23:11:12 10:20:10 %H:%i:%s 0000-00-00 10:20:10 10:20:10 %h:%i:%s.%f 0000-00-00 10:20:10 +10:20:10 %T 0000-00-00 10:20:10 10:20:10AM %h:%i:%s%p 0000-00-00 10:20:10 +10:20:10AM %r 0000-00-00 10:20:10 10:20:10.44AM %h:%i:%s.%f%p 0000-00-00 10:20:10.440000 15-01-2001 12:59:58 %d-%m-%Y %H:%i:%S 2001-01-15 12:59:58 15 September 2001 %d %M %Y 2001-09-15 00:00:00 15 SEPTEMB 2001 %d %M %Y 2001-09-15 00:00:00 15 MAY 2001 %d %b %Y 2001-05-15 00:00:00 +15th May 2001 %D %b %Y 2001-05-15 00:00:00 Sunday 15 MAY 2001 %W %d %b %Y 2001-05-15 00:00:00 Sund 15 MAY 2001 %W %d %b %Y 2001-05-15 00:00:00 Tuesday 00 2002 %W %U %Y 2002-01-01 00:00:00 Thursday 53 1998 %W %u %Y 1998-12-31 00:00:00 +Sunday 01 2001 %W %v %x 2001-01-07 00:00:00 +Tuesday 52 2001 %W %V %X 2002-01-01 00:00:00 +060 2004 %j %Y 2004-02-29 00:00:00 +4 53 1998 %w %u %Y 1998-12-31 00:00:00 15-01-2001 %d-%m-%Y %H:%i:%S 2001-01-15 00:00:00 15-01-20 %d-%m-%y 2020-01-15 00:00:00 15-2001-1 %d-%Y-%c 2001-01-15 00:00:00 @@ -138,16 +152,23 @@ date format con 2003-01-02 11:11:12Pm %Y-%m-%d %h:%i:%S%p 2003-01-02 23:11:12 10:20:10 %H:%i:%s 0000-00-00 10:20:10 10:20:10 %h:%i:%s.%f 0000-00-00 10:20:10 +10:20:10 %T 0000-00-00 10:20:10 10:20:10AM %h:%i:%s%p 0000-00-00 10:20:10 +10:20:10AM %r 0000-00-00 10:20:10 10:20:10.44AM %h:%i:%s.%f%p 0000-00-00 10:20:10.440000 15-01-2001 12:59:58 %d-%m-%Y %H:%i:%S 2001-01-15 12:59:58 15 September 2001 %d %M %Y 2001-09-15 00:00:00 15 SEPTEMB 2001 %d %M %Y 2001-09-15 00:00:00 15 MAY 2001 %d %b %Y 2001-05-15 00:00:00 +15th May 2001 %D %b %Y 2001-05-15 00:00:00 Sunday 15 MAY 2001 %W %d %b %Y 2001-05-15 00:00:00 Sund 15 MAY 2001 %W %d %b %Y 2001-05-15 00:00:00 Tuesday 00 2002 %W %U %Y 2002-01-01 00:00:00 Thursday 53 1998 %W %u %Y 1998-12-31 00:00:00 +Sunday 01 2001 %W %v %x 2001-01-07 00:00:00 +Tuesday 52 2001 %W %V %X 2002-01-01 00:00:00 +060 2004 %j %Y 2004-02-29 00:00:00 +4 53 1998 %w %u %Y 1998-12-31 00:00:00 15-01-2001 %d-%m-%Y %H:%i:%S 2001-01-15 00:00:00 15-01-20 %d-%m-%y 2020-01-15 00:00:00 15-2001-1 %d-%Y-%c 2001-01-15 00:00:00 @@ -162,16 +183,23 @@ date format datetime 2003-01-02 11:11:12Pm %Y-%m-%d %h:%i:%S%p 2003-01-02 23:11:12 10:20:10 %H:%i:%s 0000-00-00 10:20:10 10:20:10 %h:%i:%s.%f 0000-00-00 10:20:10 +10:20:10 %T 0000-00-00 10:20:10 10:20:10AM %h:%i:%s%p 0000-00-00 10:20:10 +10:20:10AM %r 0000-00-00 10:20:10 10:20:10.44AM %h:%i:%s.%f%p 0000-00-00 10:20:10.440000 15-01-2001 12:59:58 %d-%m-%Y %H:%i:%S 2001-01-15 12:59:58 15 September 2001 %d %M %Y 2001-09-15 00:00:00 15 SEPTEMB 2001 %d %M %Y 2001-09-15 00:00:00 15 MAY 2001 %d %b %Y 2001-05-15 00:00:00 +15th May 2001 %D %b %Y 2001-05-15 00:00:00 Sunday 15 MAY 2001 %W %d %b %Y 2001-05-15 00:00:00 Sund 15 MAY 2001 %W %d %b %Y 2001-05-15 00:00:00 Tuesday 00 2002 %W %U %Y 2002-01-01 00:00:00 Thursday 53 1998 %W %u %Y 1998-12-31 00:00:00 +Sunday 01 2001 %W %v %x 2001-01-07 00:00:00 +Tuesday 52 2001 %W %V %X 2002-01-01 00:00:00 +060 2004 %j %Y 2004-02-29 00:00:00 +4 53 1998 %w %u %Y 1998-12-31 00:00:00 15-01-2001 %d-%m-%Y %H:%i:%S 2001-01-15 00:00:00 15-01-20 %d-%m-%y 2020-01-15 00:00:00 15-2001-1 %d-%Y-%c 2001-01-15 00:00:00 @@ -186,16 +214,23 @@ date format date2 2003-01-02 11:11:12Pm %Y-%m-%d %h:%i:%S%p 2003-01-02 10:20:10 %H:%i:%s 0000-00-00 10:20:10 %h:%i:%s.%f 0000-00-00 +10:20:10 %T 0000-00-00 10:20:10AM %h:%i:%s%p 0000-00-00 +10:20:10AM %r 0000-00-00 10:20:10.44AM %h:%i:%s.%f%p 0000-00-00 15-01-2001 12:59:58 %d-%m-%Y %H:%i:%S 2001-01-15 15 September 2001 %d %M %Y 2001-09-15 15 SEPTEMB 2001 %d %M %Y 2001-09-15 15 MAY 2001 %d %b %Y 2001-05-15 +15th May 2001 %D %b %Y 2001-05-15 Sunday 15 MAY 2001 %W %d %b %Y 2001-05-15 Sund 15 MAY 2001 %W %d %b %Y 2001-05-15 Tuesday 00 2002 %W %U %Y 2002-01-01 Thursday 53 1998 %W %u %Y 1998-12-31 +Sunday 01 2001 %W %v %x 2001-01-07 +Tuesday 52 2001 %W %V %X 2002-01-01 +060 2004 %j %Y 2004-02-29 +4 53 1998 %w %u %Y 1998-12-31 15-01-2001 %d-%m-%Y %H:%i:%S 2001-01-15 15-01-20 %d-%m-%y 2020-01-15 15-2001-1 %d-%Y-%c 2001-01-15 @@ -210,16 +245,23 @@ date format time 2003-01-02 11:11:12Pm %Y-%m-%d %h:%i:%S%p 23:11:12 10:20:10 %H:%i:%s 10:20:10 10:20:10 %h:%i:%s.%f 10:20:10 +10:20:10 %T 10:20:10 10:20:10AM %h:%i:%s%p 10:20:10 +10:20:10AM %r 10:20:10 10:20:10.44AM %h:%i:%s.%f%p 10:20:10.440000 15-01-2001 12:59:58 %d-%m-%Y %H:%i:%S 12:59:58 15 September 2001 %d %M %Y 00:00:00 15 SEPTEMB 2001 %d %M %Y 00:00:00 15 MAY 2001 %d %b %Y 00:00:00 +15th May 2001 %D %b %Y 00:00:00 Sunday 15 MAY 2001 %W %d %b %Y 00:00:00 Sund 15 MAY 2001 %W %d %b %Y 00:00:00 Tuesday 00 2002 %W %U %Y 00:00:00 Thursday 53 1998 %W %u %Y 00:00:00 +Sunday 01 2001 %W %v %x 00:00:00 +Tuesday 52 2001 %W %V %X 00:00:00 +060 2004 %j %Y 00:00:00 +4 53 1998 %w %u %Y 00:00:00 15-01-2001 %d-%m-%Y %H:%i:%S 00:00:00 15-01-20 %d-%m-%y 00:00:00 15-2001-1 %d-%Y-%c 00:00:00 @@ -234,16 +276,23 @@ date format time2 2003-01-02 11:11:12Pm %Y-%m-%d %h:%i:%S%p 23:11:12 10:20:10 %H:%i:%s 10:20:10 10:20:10 %h:%i:%s.%f 10:20:10 +10:20:10 %T 10:20:10 10:20:10AM %h:%i:%s%p 10:20:10 +10:20:10AM %r 10:20:10 10:20:10.44AM %h:%i:%s.%f%p 10:20:10.440000 15-01-2001 12:59:58 %d-%m-%Y %H:%i:%S 12:59:58 15 September 2001 %d %M %Y 00:00:00 15 SEPTEMB 2001 %d %M %Y 00:00:00 15 MAY 2001 %d %b %Y 00:00:00 +15th May 2001 %D %b %Y 00:00:00 Sunday 15 MAY 2001 %W %d %b %Y 00:00:00 Sund 15 MAY 2001 %W %d %b %Y 00:00:00 Tuesday 00 2002 %W %U %Y 00:00:00 Thursday 53 1998 %W %u %Y 00:00:00 +Sunday 01 2001 %W %v %x 00:00:00 +Tuesday 52 2001 %W %V %X 00:00:00 +060 2004 %j %Y 00:00:00 +4 53 1998 %w %u %Y 00:00:00 15-01-2001 %d-%m-%Y %H:%i:%S 00:00:00 15-01-20 %d-%m-%y 00:00:00 15-2001-1 %d-%Y-%c 00:00:00 @@ -258,10 +307,13 @@ insert into t1 values ('15 Septembei 2001', '%d %M %Y'), ('15 Ju 2001', '%d %M %Y'), ('Sund 15 MA', '%W %d %b %Y'), -('Sunday 01 2001', '%W %V %X'), ('Thursdai 12 1998', '%W %u %Y'), -(NULL, get_format(DATE,'USA')), -('Tuesday 52 2001', '%W %V %X'); +('Sunday 01 2001', '%W %v %X'), +('Tuesday 52 2001', '%W %V %x'), +('Tuesday 52 2001', '%W %V %Y'), +('Tuesday 52 2001', '%W %u %x'), +('7 53 1998', '%w %u %Y'), +(NULL, get_format(DATE,'USA')); select date,format,str_to_date(date, format) as str_to_date from t1; date format str_to_date 2003-01-02 10:11:12 PM %Y-%m-%d %H:%i:%S %p NULL @@ -273,10 +325,13 @@ date format str_to_date 15 Septembei 2001 %d %M %Y NULL 15 Ju 2001 %d %M %Y NULL Sund 15 MA %W %d %b %Y NULL -Sunday 01 2001 %W %V %X NULL Thursdai 12 1998 %W %u %Y NULL +Sunday 01 2001 %W %v %X NULL +Tuesday 52 2001 %W %V %x NULL +Tuesday 52 2001 %W %V %Y NULL +Tuesday 52 2001 %W %u %x NULL +7 53 1998 %w %u %Y NULL NULL %m.%d.%Y NULL -Tuesday 52 2001 %W %V %X NULL select date,format,concat(str_to_date(date, format),'') as con from t1; date format con 2003-01-02 10:11:12 PM %Y-%m-%d %H:%i:%S %p NULL @@ -288,10 +343,13 @@ date format con 15 Septembei 2001 %d %M %Y NULL 15 Ju 2001 %d %M %Y NULL Sund 15 MA %W %d %b %Y NULL -Sunday 01 2001 %W %V %X NULL Thursdai 12 1998 %W %u %Y NULL +Sunday 01 2001 %W %v %X NULL +Tuesday 52 2001 %W %V %x NULL +Tuesday 52 2001 %W %V %Y NULL +Tuesday 52 2001 %W %u %x NULL +7 53 1998 %w %u %Y NULL NULL %m.%d.%Y NULL -Tuesday 52 2001 %W %V %X NULL truncate table t1; insert into t1 values ('10:20:10AM', '%h:%i:%s'), diff --git a/mysql-test/t/date_formats.test b/mysql-test/t/date_formats.test index 1fc04cb907b..2e6e1fabd8d 100644 --- a/mysql-test/t/date_formats.test +++ b/mysql-test/t/date_formats.test @@ -132,16 +132,23 @@ insert into t1 values ('2003-01-02 11:11:12Pm', '%Y-%m-%d %h:%i:%S%p'), ('10:20:10', '%H:%i:%s'), ('10:20:10', '%h:%i:%s.%f'), +('10:20:10', '%T'), ('10:20:10AM', '%h:%i:%s%p'), +('10:20:10AM', '%r'), ('10:20:10.44AM', '%h:%i:%s.%f%p'), ('15-01-2001 12:59:58', '%d-%m-%Y %H:%i:%S'), ('15 September 2001', '%d %M %Y'), ('15 SEPTEMB 2001', '%d %M %Y'), ('15 MAY 2001', '%d %b %Y'), +('15th May 2001', '%D %b %Y'), ('Sunday 15 MAY 2001', '%W %d %b %Y'), ('Sund 15 MAY 2001', '%W %d %b %Y'), ('Tuesday 00 2002', '%W %U %Y'), ('Thursday 53 1998', '%W %u %Y'), +('Sunday 01 2001', '%W %v %x'), +('Tuesday 52 2001', '%W %V %X'), +('060 2004', '%j %Y'), +('4 53 1998', '%w %u %Y'), ('15-01-2001', '%d-%m-%Y %H:%i:%S'), ('15-01-20', '%d-%m-%y'), ('15-2001-1', '%d-%Y-%c'); @@ -156,7 +163,7 @@ select date,format,DATE(str_to_date(date, format)) as date2 from t1; select date,format,TIME(str_to_date(date, format)) as time from t1; select date,format,concat(TIME(str_to_date(date, format))) as time2 from t1; -# Test wrong dates +# Test wrong dates or converion specifiers truncate table t1; insert into t1 values @@ -169,10 +176,13 @@ insert into t1 values ('15 Septembei 2001', '%d %M %Y'), ('15 Ju 2001', '%d %M %Y'), ('Sund 15 MA', '%W %d %b %Y'), -('Sunday 01 2001', '%W %V %X'), ('Thursdai 12 1998', '%W %u %Y'), -(NULL, get_format(DATE,'USA')), -('Tuesday 52 2001', '%W %V %X'); +('Sunday 01 2001', '%W %v %X'), +('Tuesday 52 2001', '%W %V %x'), +('Tuesday 52 2001', '%W %V %Y'), +('Tuesday 52 2001', '%W %u %x'), +('7 53 1998', '%w %u %Y'), +(NULL, get_format(DATE,'USA')); select date,format,str_to_date(date, format) as str_to_date from t1; select date,format,concat(str_to_date(date, format),'') as con from t1; diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index 786bcf434ed..cc320addd47 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -113,6 +113,12 @@ static bool make_datetime(date_time_format_types format, TIME *ltime, } +/* Date formats corresponding to compound %r and %T conversion specifiers */ +static DATE_TIME_FORMAT time_ampm_format= {{}, '\0', 0, + {(char *)"%I:%i:%S %p", 11}}; +static DATE_TIME_FORMAT time_24hrs_format= {{}, '\0', 0, + {(char *)"%H:%i:%S", 8}}; + /* Extract datetime value to TIME struct from string value according to format string. @@ -126,6 +132,17 @@ static bool make_datetime(date_time_format_types format, TIME *ltime, cached_timestamp_type It uses to get an appropriate warning in the case when the value is truncated. + sub_pattern_end if non-zero then we are parsing string which + should correspond compound specifier (like %T or + %r) and this parameter is pointer to place where + pointer to end of string matching this specifier + should be stored. + NOTE + Possibility to parse strings matching to patterns equivalent to compound + specifiers is mainly intended for use from inside of this function in + order to understand %T and %r conversion specifiers, so number of + conversion specifiers that can be used in such sub-patterns is limited. + Also most of checks are skipped in this case. RETURN 0 ok @@ -134,14 +151,18 @@ static bool make_datetime(date_time_format_types format, TIME *ltime, static bool extract_date_time(DATE_TIME_FORMAT *format, const char *val, uint length, TIME *l_time, - timestamp_type cached_timestamp_type) + timestamp_type cached_timestamp_type, + const char **sub_pattern_end) { int weekday= 0, yearday= 0, daypart= 0; int week_number= -1; CHARSET_INFO *cs= &my_charset_bin; int error= 0; bool usa_time= 0; - bool sunday_first= 0; + bool sunday_first_n_first_week_non_iso; + bool strict_week_number; + int strict_week_number_year= -1; + bool strict_week_number_year_type; int frac_part; const char *val_begin= val; const char *val_end= val + length; @@ -149,7 +170,12 @@ static bool extract_date_time(DATE_TIME_FORMAT *format, const char *end= ptr + format->format.length; DBUG_ENTER("extract_date_time"); - bzero((char*) l_time, sizeof(*l_time)); + LINT_INIT(sunday_first_n_first_week_non_iso); + LINT_INIT(strict_week_number); + LINT_INIT(strict_week_number_year_type); + + if (!sub_pattern_end) + bzero((char*) l_time, sizeof(*l_time)); for (; ptr != end && val != val_end; ptr++) { @@ -160,7 +186,7 @@ static bool extract_date_time(DATE_TIME_FORMAT *format, char *tmp; /* Skip pre-space between each argument */ - while (my_isspace(cs, *val) && val != val_end) + while (val != val_end && my_isspace(cs, *val)) val++; val_len= (uint) (val_end - val); @@ -268,9 +294,12 @@ static bool extract_date_time(DATE_TIME_FORMAT *format, break; case 'w': tmp= (char*) val + 1; - if ((weekday= (int) my_strtoll10(val, &tmp, &error)) <= 0 || + if ((weekday= (int) my_strtoll10(val, &tmp, &error)) < 0 || weekday >= 7) goto err; + /* We should use the same 1 - 7 scale for %w as for %W */ + if (!weekday) + weekday= 7; val= tmp; break; case 'j': @@ -279,15 +308,45 @@ static bool extract_date_time(DATE_TIME_FORMAT *format, val= tmp; break; + /* Week numbers */ + case 'V': case 'U': - sunday_first= 1; - /* Fall through */ + case 'v': case 'u': + sunday_first_n_first_week_non_iso= (*ptr=='U' || *ptr== 'V'); + strict_week_number= (*ptr=='V' || *ptr=='v'); tmp= (char*) val + min(val_len, 2); - week_number= (int) my_strtoll10(val, &tmp, &error); + if ((week_number= (int) my_strtoll10(val, &tmp, &error)) < 0 || + strict_week_number && !week_number || + week_number > 53) + goto err; val= tmp; break; + /* Year used with 'strict' %V and %v week numbers */ + case 'X': + case 'x': + strict_week_number_year_type= (*ptr=='X'); + tmp= (char*) val + min(4, val_len); + strict_week_number_year= (int) my_strtoll10(val, &tmp, &error); + val= tmp; + break; + + /* Time in AM/PM notation */ + case 'r': + error= extract_date_time(&time_ampm_format, val, + (uint)(val_end - val), l_time, + cached_timestamp_type, &val); + break; + + /* Time in 24-hour notation */ + case 'T': + error= extract_date_time(&time_24hrs_format, val, + (uint)(val_end - val), l_time, + cached_timestamp_type, &val); + break; + + /* Conversion specifiers that match classes of characters */ case '.': while (my_ispunct(cs, *val) && val != val_end) val++; @@ -320,6 +379,16 @@ static bool extract_date_time(DATE_TIME_FORMAT *format, l_time->hour= l_time->hour%12+daypart; } + /* + If we are recursively called for parsing string matching compound + specifiers we are already done. + */ + if (sub_pattern_end) + { + *sub_pattern_end= val; + DBUG_RETURN(0); + } + if (yearday > 0) { uint days= calc_daynr(l_time->year,1,1) + yearday - 1; @@ -330,34 +399,45 @@ static bool extract_date_time(DATE_TIME_FORMAT *format, if (week_number >= 0 && weekday) { - int days= calc_daynr(l_time->year,1,1); + int days; uint weekday_b; - - if (weekday > 7 || weekday < 0) - goto err; - if (sunday_first) - weekday = weekday%7; - if (week_number == 53) + /* + %V,%v require %X,%x resprectively, + %U,%u should be used with %Y and not %X or %x + */ + if (strict_week_number && + (strict_week_number_year < 0 || + strict_week_number_year_type != sunday_first_n_first_week_non_iso) || + !strict_week_number && strict_week_number_year >= 0) + goto err; + + /* Number of days since year 0 till 1st Jan of this year */ + days= calc_daynr((strict_week_number ? strict_week_number_year : + l_time->year), + 1, 1); + /* Which day of week is 1st Jan of this year */ + weekday_b= calc_weekday(days, sunday_first_n_first_week_non_iso); + + /* + Below we are going to sum: + 1) number of days since year 0 till 1st day of 1st week of this year + 2) number of days between 1st week and our week + 3) and position of our day in the week + */ + if (sunday_first_n_first_week_non_iso) { - days+= (week_number - 1)*7; - weekday_b= calc_weekday(days, sunday_first); - weekday = weekday - weekday_b - !sunday_first; - days+= weekday; - } - else if (week_number == 0) - { - weekday_b= calc_weekday(days, sunday_first); - weekday = weekday - weekday_b - !sunday_first; - days+= weekday; + days+= ((weekday_b == 0) ? 0 : 7) - weekday_b + + (week_number - 1) * 7 + + weekday % 7; } else { - days+= (week_number - !sunday_first)*7; - weekday_b= calc_weekday(days, sunday_first); - weekday =weekday - weekday_b - !sunday_first; - days+= weekday; + days+= ((weekday_b <= 3) ? 0 : 7) - weekday_b + + (week_number - 1) * 7 + + (weekday - 1); } + if (days <= 0 || days >= MAX_DAY_NUMBER) goto err; get_date_from_daynr(days,&l_time->year,&l_time->month,&l_time->day); @@ -2599,7 +2679,7 @@ bool Item_func_str_to_date::get_date(TIME *ltime, uint fuzzy_date) date_time_format.format.str= (char*) format->ptr(); date_time_format.format.length= format->length(); if (extract_date_time(&date_time_format, val->ptr(), val->length(), - ltime, cached_timestamp_type)) + ltime, cached_timestamp_type, 0)) goto null_date; if (cached_timestamp_type == MYSQL_TIMESTAMP_TIME && ltime->day) {