From 5a9f5bb493949a0d80473fa76b975a49fa50d879 Mon Sep 17 00:00:00 2001 From: Dirkjan Bussink Date: Tue, 26 Dec 2023 16:34:01 +0100 Subject: [PATCH] evalengine: Fix week overflow Some of the last days in the year can fall in the first week of the next year. If that happens, there are various modes when we should return 53 as the week number and not week 1 for the next year. This can always be 53. There are weeks which already contain 53 weeks, but it can never be 54 in those cases as in years with 53 weeks, there's never a last day of the year that falls in the first week of next year. It then always falls in week 53 already. Signed-off-by: Dirkjan Bussink --- go/mysql/datetime/datetime.go | 8 ++++++++ go/vt/vtgate/evalengine/compiler_test.go | 16 ++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/go/mysql/datetime/datetime.go b/go/mysql/datetime/datetime.go index bf73ac85c27..debc21cff6d 100644 --- a/go/mysql/datetime/datetime.go +++ b/go/mysql/datetime/datetime.go @@ -315,12 +315,16 @@ func (d Date) Week(mode int) int { year, week := d.SundayWeek() if year < d.Year() { return 0 + } else if year > d.Year() { + return 53 } return week case 1: year, week := d.ISOWeek() if year < d.Year() { return 0 + } else if year > d.Year() { + return 53 } return week case 2: @@ -333,12 +337,16 @@ func (d Date) Week(mode int) int { year, week := d.Sunday4DayWeek() if year < d.Year() { return 0 + } else if year > d.Year() { + return 53 } return week case 5: year, week := d.MondayWeek() if year < d.Year() { return 0 + } else if year > d.Year() { + return 53 } return week case 6: diff --git a/go/vt/vtgate/evalengine/compiler_test.go b/go/vt/vtgate/evalengine/compiler_test.go index a0c29e1510f..0e9219c648a 100644 --- a/go/vt/vtgate/evalengine/compiler_test.go +++ b/go/vt/vtgate/evalengine/compiler_test.go @@ -574,6 +574,22 @@ func TestCompilerSingle(t *testing.T) { expression: `DAYOFMONTH(0)`, result: `INT64(0)`, }, + { + expression: `week('2023-12-31', 4)`, + result: `INT64(53)`, + }, + { + expression: `week('2023-12-31', 2)`, + result: `INT64(53)`, + }, + { + expression: `week('2024-12-31', 1)`, + result: `INT64(53)`, + }, + { + expression: `week('2024-12-31', 5)`, + result: `INT64(53)`, + }, } tz, _ := time.LoadLocation("Europe/Madrid")