diff --git a/mysql-test/r/date_formats.result b/mysql-test/r/date_formats.result index dfd8244ef77..99ae6d85fee 100644 --- a/mysql-test/r/date_formats.result +++ b/mysql-test/r/date_formats.result @@ -590,3 +590,13 @@ select str_to_date('04/30/2004 ', '%m/%d/%Y '); str_to_date('04/30/2004 ', '%m/%d/%Y ') 2004-04-30 "End of 4.1 tests" +SELECT DATE_FORMAT("0000-01-01",'%W %d %M %Y') as valid_date; +valid_date +Sunday 01 January 0000 +SELECT DATE_FORMAT("0000-02-28",'%W %d %M %Y') as valid_date; +valid_date +Tuesday 28 February 0000 +SELECT DATE_FORMAT("2009-01-01",'%W %d %M %Y') as valid_date; +valid_date +Thursday 01 January 2009 +"End of 5.0 tests" diff --git a/mysql-test/t/date_formats.test b/mysql-test/t/date_formats.test index abf09942d1c..e474fac8a2a 100644 --- a/mysql-test/t/date_formats.test +++ b/mysql-test/t/date_formats.test @@ -340,3 +340,15 @@ select str_to_date('04/30 /2004', '%m /%d /%Y'); select str_to_date('04/30/2004 ', '%m/%d/%Y '); --echo "End of 4.1 tests" + +# +# Bug #41470: DATE_FORMAT() crashes the complete server with a valid date +# + +# show that these two do not crash the server: +SELECT DATE_FORMAT("0000-01-01",'%W %d %M %Y') as valid_date; +SELECT DATE_FORMAT("0000-02-28",'%W %d %M %Y') as valid_date; +# show that date within the Gregorian range render correct results: (THU) +SELECT DATE_FORMAT("2009-01-01",'%W %d %M %Y') as valid_date; + +--echo "End of 5.0 tests" diff --git a/sql-common/my_time.c b/sql-common/my_time.c index 23532027883..155e0237e3c 100644 --- a/sql-common/my_time.c +++ b/sql-common/my_time.c @@ -762,19 +762,20 @@ long calc_daynr(uint year,uint month,uint day) { long delsum; int temp; + int y= year; /* may be < 0 temporarily */ DBUG_ENTER("calc_daynr"); - if (year == 0 && month == 0 && day == 0) + if (y == 0 && month == 0 && day == 0) DBUG_RETURN(0); /* Skip errors */ - delsum= (long) (365L * year+ 31*(month-1) +day); + delsum= (long) (365L * y+ 31*(month-1) +day); if (month <= 2) - year--; + y--; else delsum-= (long) (month*4+23)/10; - temp=(int) ((year/100+1)*3)/4; + temp=(int) ((y/100+1)*3)/4; DBUG_PRINT("exit",("year: %d month: %d day: %d -> daynr: %ld", - year+(month <= 2),month,day,delsum+year/4-temp)); - DBUG_RETURN(delsum+(int) year/4-temp); + y+(month <= 2),month,day,delsum+y/4-temp)); + DBUG_RETURN(delsum+(int) y/4-temp); } /* calc_daynr */