From 468dcb6092bce57a4c7529f40d10fcd7654f5ead Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 7 Dec 2003 15:10:21 +0400 Subject: WL#1175: more default_week_formats for iso compatibility New formats added for 'week()' function and 'default_week_format' option(4 - 7). Next formats is supported now: *Value* *Meaning* `0' Week starts on Sunday; First Sunday of the year starts week 1. Week() returns 0-53. `1' Week starts on Monday; Weeks numbered according to ISO 8601:1988. Week() returns 0-53. `2' Week starts on Sunday; First Sunday of the year starts week 1. Week() returns 1-53. `3' Week starts on Monday; Weeks numbered according to ISO 8601:1988. Week() returns 1-53. `4' Week starts on Sunday; Weeks numbered according to ISO 8601:1988. Week() returns 0-53. `5' Week starts on Monday; First Monday of the year starts week 1. Week() returns 0-53. `6' Week starts on Sunday; Weeks numbered according to ISO 8601:1988. Week() returns 1-53. `7' Week starts on Monday; First Monday of the year starts week 1. Week() returns 1-53. mysql-test/r/func_time.result: Test for 'default_week_format' option and 'week' function mysql-test/t/func_time.test: Test for 'default_week_format' option and 'week' function sql/item_timefunc.cc: WL#1175 more default_week_formats for iso compatibility sql/mysql_priv.h: WL#1175 more default_week_formats for iso compatibility sql/mysqld.cc: WL#1175 more default_week_formats for iso compatibility sql/time.cc: WL#1175 more default_week_formats for iso compatibility --- sql/time.cc | 68 ++++++++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 49 insertions(+), 19 deletions(-) (limited to 'sql/time.cc') diff --git a/sql/time.cc b/sql/time.cc index 321a8ba16e5..bf218fa58ab 100644 --- a/sql/time.cc +++ b/sql/time.cc @@ -175,42 +175,72 @@ uint calc_days_in_year(uint year) 366 : 365; } -/* Calculate week. If 'with_year' is not set, then return a week 0-53, where - 0 means that it's the last week of the previous year. - If 'with_year' is set then the week will always be in the range 1-53 and - the year out parameter will contain the year for the week */ -uint calc_week(TIME *l_time, bool with_year, bool sunday_first_day_of_week, - uint *year) +/* + The bits in week_format has the following meaning: + WEEK_MONDAY_FIRST (0) If not set Sunday is first day of week + If set Monday is first day of week + WEEK_YEAR (1) If not set Week is in range 0-53 + + Week 0 is returned for the the last week of the previous year (for + a date at start of january) In this case one can get 53 for the + first week of next year. This flag ensures that the week is + relevant for the given year. Note that this flag is only + releveant if WEEK_JANUARY is not set. + + If set Week is in range 1-53. + + In this case one may get week 53 for a date in January (when + the week is that last week of previous year) and week 1 for a + date in December. + + WEEK_FIRST_WEEKDAY (2) If not set Weeks are numbered according + to ISO 8601:1988 + If set The week that contains the first + 'first-day-of-week' is week 1. + + ISO 8601:1988 means that if the week containing January 1 has + four or more days in the new year, then it is week 1; + Otherwise it is the last week of the previous year, and the + next week is week 1. +*/ + +uint calc_week(TIME *l_time, uint week_behaviour, uint *year) { uint days; ulong daynr=calc_daynr(l_time->year,l_time->month,l_time->day); ulong first_daynr=calc_daynr(l_time->year,1,1); - uint weekday=calc_weekday(first_daynr,sunday_first_day_of_week); + bool monday_first= test(week_behaviour & WEEK_MONDAY_FIRST); + bool week_year= test(week_behaviour & WEEK_YEAR); + bool first_weekday= test(week_behaviour & WEEK_FIRST_WEEKDAY); + + uint weekday=calc_weekday(first_daynr, !monday_first); *year=l_time->year; - if (l_time->month == 1 && l_time->day <= 7-weekday && - ((!sunday_first_day_of_week && weekday >= 4) || - (sunday_first_day_of_week && weekday != 0))) + + if (l_time->month == 1 && l_time->day <= 7-weekday) { - /* Last week of the previous year */ - if (!with_year) + if (!week_year && + (first_weekday && weekday != 0 || + !first_weekday && weekday >= 4)) return 0; - with_year=0; // Don't check the week again + week_year= 1; (*year)--; first_daynr-= (days=calc_days_in_year(*year)); weekday= (weekday + 53*7- days) % 7; } - if ((sunday_first_day_of_week && weekday != 0) || - (!sunday_first_day_of_week && weekday >= 4)) + + if ((first_weekday && weekday != 0) || + (!first_weekday && weekday >= 4)) days= daynr - (first_daynr+ (7-weekday)); else days= daynr - (first_daynr - weekday); - if (with_year && days >= 52*7) + + if (week_year && days >= 52*7) { - /* Check if we are on the first week of the next year (or week 53) */ weekday= (weekday + calc_days_in_year(*year)) % 7; - if (weekday < 4) - { // We are at first week on next year + if (!first_weekday && weekday < 4 || + first_weekday && weekday == 0) + { (*year)++; return 1; } -- cgit v1.2.1 From 759ea82ee1335543da1d484d76468b6686057e90 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 12 Dec 2003 22:26:58 +0200 Subject: Fix autoincrement for signed columns (Bug #1366) Fixed problem with char > 128 in QUOTE() function. (Bug #1868) Disable creation of symlinks if my_disable_symlink is set Fixed searching of TEXT with end space. (Bug #1651) Fixed caching bug in multi-table-update where same table was used twice. (Bug #1711) Fixed problem with UNIX_TIMESTAMP() for timestamps close to 0. (Bug #1998) Fixed timestamp.test include/my_base.h: Add HA_END_SPACE_KEY to mark keys that has VARCHAR/TEXT fields. myisam/mi_check.c: Delete not used variable myisam/mi_key.c: Fix autoincrement for signed columns (Bug #1366). Patch by Holyfoot myisam/mi_open.c: Bug fix for future (doesn't affect current code) myisam/mi_search.c: Ignore end space for VARCHAR/TEXT columns mysql-test/r/auto_increment.result: Test auto_increment with signed numbers mysql-test/r/binary.result: Update results (old result was wrong) mysql-test/r/func_str.result: Added test of QUOTE() mysql-test/r/func_time.result: Add test of unix_timestamp() mysql-test/r/have_met_timezone.require: Fixed test mysql-test/r/innodb.result: Add test for InnoDB behaviour with TRUNCATE mysql-test/r/multi_update.result: Test of multi-update bug mysql-test/r/symlink.result: Test of ALTER TABLE and symlinks mysql-test/r/timezone.result: Test of from_unixtime() mysql-test/r/truncate.result: Test of truncate and auto_increment mysql-test/r/type_blob.result: Test of key search on TEXT/VARCHAR column with end space mysql-test/t/auto_increment.test: Test auto_increment with signed numbers mysql-test/t/func_str.test: Added test of QUOTE() mysql-test/t/func_time.test: Add test of unix_timestamp() mysql-test/t/innodb.test: Add test for InnoDB behaviour with TRUNCATE mysql-test/t/multi_update.test: Test of multi-update bug mysql-test/t/symlink.test: Test of ALTER TABLE and symlinks mysql-test/t/timezone.test: Test of from_unixtime() mysql-test/t/truncate.test: Test of truncate and auto_increment mysql-test/t/type_blob.test: Test of key search on TEXT/VARCHAR column with end space mysys/my_symlink2.c: Disable creation of symlinks if my_disable_symlink is set sql/field.h: Indentation cleanup sql/ha_innodb.cc: HA_PART_KEY -> HA_PART_KEY_SEG sql/item_strfunc.cc: Fixed problem with char > 128 in QUOTE() function. (Bug #1868) sql/mysql_priv.h: Make check_dup() external sql/opt_range.cc: Fixed searching of TEXT with end space. (Bug #1651) sql/records.cc: Fixed caching bug in multi-table-update where same table was used twice. (Bug #1711) sql/sql_acl.cc: Reset ip and ip_mask if hostname is NULL sql/sql_parse.cc: Make check_dup() global sql/sql_select.cc: Fixed searching of TEXT with end space. (Bug #1651) sql/sql_table.cc: Fixed searching of TEXT with end space. (Bug #1651) sql/sql_update.cc: Fixed caching bug in multi-table-update where same table was used twice. (Bug #1711) sql/table.cc: Fixed searching of TEXT with end space. (Bug #1651) sql/table.h: Fixed caching bug in multi-table-update where same table was used twice. (Bug #1711) sql/time.cc: Fixed problem with UNIX_TIMESTAMP() for timestamps close to 0. (Bug #1998) --- sql/time.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'sql/time.cc') diff --git a/sql/time.cc b/sql/time.cc index bf218fa58ab..5dc229b1d88 100644 --- a/sql/time.cc +++ b/sql/time.cc @@ -125,6 +125,8 @@ long my_gmt_sec(TIME *t, long *my_timezone) tmp-=t->minute*60 + t->second; // Move to previous hour } *my_timezone= current_timezone; + if (tmp < 0 && t->year <= 1900+YY_PART_YEAR) + tmp= 0; return (long) tmp; } /* my_gmt_sec */ @@ -445,7 +447,7 @@ time_t str_to_timestamp(const char *str,uint length) if (str_to_TIME(str,length,&l_time,0) == TIMESTAMP_NONE) return(0); - if (l_time.year >= TIMESTAMP_MAX_YEAR || l_time.year < 1900+YY_PART_YEAR) + if (l_time.year >= TIMESTAMP_MAX_YEAR || l_time.year < 1900+YY_PART_YEAR-1) { current_thd->cuted_fields++; return(0); -- cgit v1.2.1