[cherry-pick](branch2.1) fix week/yearweek function get wrong result (#36538)
## Proposed changes cherry-pick from master #36000 #36159
This commit is contained in:
@ -687,7 +687,10 @@ public class DateTimeExtractAndTransform {
|
||||
return week(date.toJavaDateType(), mode.getIntValue());
|
||||
}
|
||||
|
||||
private static Expression week(LocalDateTime localDateTime, int mode) {
|
||||
/**
|
||||
* the impl of function week(date/datetime, mode)
|
||||
*/
|
||||
public static Expression week(LocalDateTime localDateTime, int mode) {
|
||||
switch (mode) {
|
||||
case 0: {
|
||||
return new TinyIntLiteral(
|
||||
@ -697,6 +700,13 @@ public class DateTimeExtractAndTransform {
|
||||
return new TinyIntLiteral((byte) localDateTime.get(WeekFields.ISO.weekOfYear()));
|
||||
}
|
||||
case 2: {
|
||||
// https://dev.mysql.com/doc/refman/8.4/en/date-and-time-functions.html#function_week
|
||||
// mode 2 is start with a Sunday day as first week in this year.
|
||||
// and special case for 0000-01-01, as it's SATURDAY, calculate result of 52 is
|
||||
// last year, so it's meaningless.
|
||||
if (checkIsSpecificDate(localDateTime)) {
|
||||
return new TinyIntLiteral((byte) 1);
|
||||
}
|
||||
return new TinyIntLiteral(
|
||||
(byte) localDateTime.get(WeekFields.of(DayOfWeek.SUNDAY, 7).weekOfWeekBasedYear()));
|
||||
}
|
||||
@ -757,9 +767,15 @@ public class DateTimeExtractAndTransform {
|
||||
return yearWeek(dateTime.toJavaDateType(), 0);
|
||||
}
|
||||
|
||||
private static Expression yearWeek(LocalDateTime localDateTime, int mode) {
|
||||
/**
|
||||
* the impl of function yearWeek(date/datetime, mode)
|
||||
*/
|
||||
public static Expression yearWeek(LocalDateTime localDateTime, int mode) {
|
||||
switch (mode) {
|
||||
case 0: {
|
||||
if (checkIsSpecificDate(localDateTime)) {
|
||||
return new IntegerLiteral(1);
|
||||
}
|
||||
return new IntegerLiteral(
|
||||
localDateTime.get(WeekFields.of(DayOfWeek.SUNDAY, 7).weekBasedYear()) * 100
|
||||
+ localDateTime.get(
|
||||
@ -770,6 +786,9 @@ public class DateTimeExtractAndTransform {
|
||||
+ localDateTime.get(WeekFields.ISO.weekOfWeekBasedYear()));
|
||||
}
|
||||
case 2: {
|
||||
if (checkIsSpecificDate(localDateTime)) {
|
||||
return new IntegerLiteral(1);
|
||||
}
|
||||
return new IntegerLiteral(
|
||||
localDateTime.get(WeekFields.of(DayOfWeek.SUNDAY, 7).weekBasedYear()) * 100
|
||||
+ localDateTime.get(
|
||||
@ -810,6 +829,13 @@ public class DateTimeExtractAndTransform {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 0000-01-01 is specific date, sometime need handle it alone.
|
||||
*/
|
||||
private static boolean checkIsSpecificDate(LocalDateTime localDateTime) {
|
||||
return localDateTime.getYear() == 0 && localDateTime.getMonthValue() == 1 && localDateTime.getDayOfMonth() == 1;
|
||||
}
|
||||
|
||||
@ExecFunction(name = "weekofyear", argTypes = {"DATETIMEV2"}, returnType = "TINYINT")
|
||||
public static Expression weekOfYear(DateTimeV2Literal dateTime) {
|
||||
return new TinyIntLiteral((byte) dateTime.toJavaDateType().get(WeekFields.ISO.weekOfWeekBasedYear()));
|
||||
|
||||
Reference in New Issue
Block a user