Skip to content

Commit 98539fb

Browse files
committed
1
1 parent 76fa580 commit 98539fb

File tree

2 files changed

+60
-48
lines changed

2 files changed

+60
-48
lines changed

fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/executable/DateTimeExtractAndTransform.java

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -687,10 +687,27 @@ public static Expression week(DateV2Literal date, IntegerLiteral mode) {
687687
return week(date.toJavaDateType(), mode.getIntValue());
688688
}
689689

690+
/**
691+
* 0000-01-01/02 are specific dates, sometime need handle them alone.
692+
*/
693+
private static boolean isSpecificDate(LocalDateTime localDateTime) {
694+
return localDateTime.getYear() == 0 && localDateTime.getMonthValue() == 1
695+
&& (localDateTime.getDayOfMonth() == 1 || localDateTime.getDayOfMonth() == 2);
696+
}
697+
690698
/**
691699
* the impl of function week(date/datetime, mode)
692700
*/
693701
public static Expression week(LocalDateTime localDateTime, int mode) {
702+
final byte[] resultOfFirstDayBC1 = new byte[] { 1, 0, 1, 52, 1, 0, 1, 52 };
703+
if (isSpecificDate(localDateTime) && mode >= 0 && mode <= 7) { // 0000-01-01/02
704+
if (localDateTime.getDayOfMonth() == 1) {
705+
return new TinyIntLiteral(resultOfFirstDayBC1[mode]);
706+
} else { // 0001-01-02
707+
return new TinyIntLiteral((byte) 1);
708+
}
709+
}
710+
694711
switch (mode) {
695712
case 0: {
696713
return new TinyIntLiteral(
@@ -700,13 +717,6 @@ public static Expression week(LocalDateTime localDateTime, int mode) {
700717
return new TinyIntLiteral((byte) localDateTime.get(WeekFields.ISO.weekOfYear()));
701718
}
702719
case 2: {
703-
// https://dev.mysql.com/doc/refman/8.4/en/date-and-time-functions.html#function_week
704-
// mode 2 is start with a Sunday day as first week in this year.
705-
// and special case for 0000-01-01, as it's SATURDAY, calculate result of 52 is
706-
// last year, so it's meaningless.
707-
if (checkIsSpecificDate(localDateTime)) {
708-
return new TinyIntLiteral((byte) 1);
709-
}
710720
return new TinyIntLiteral(
711721
(byte) localDateTime.get(WeekFields.of(DayOfWeek.SUNDAY, 7).weekOfWeekBasedYear()));
712722
}
@@ -771,11 +781,12 @@ public static Expression yearWeek(DateTimeLiteral dateTime) {
771781
* the impl of function yearWeek(date/datetime, mode)
772782
*/
773783
public static Expression yearWeek(LocalDateTime localDateTime, int mode) {
784+
if (localDateTime.getYear() == 0) {
785+
return week(localDateTime, mode);
786+
}
787+
774788
switch (mode) {
775789
case 0: {
776-
if (checkIsSpecificDate(localDateTime)) {
777-
return new IntegerLiteral(1);
778-
}
779790
return new IntegerLiteral(
780791
localDateTime.get(WeekFields.of(DayOfWeek.SUNDAY, 7).weekBasedYear()) * 100
781792
+ localDateTime.get(
@@ -786,9 +797,6 @@ public static Expression yearWeek(LocalDateTime localDateTime, int mode) {
786797
+ localDateTime.get(WeekFields.ISO.weekOfWeekBasedYear()));
787798
}
788799
case 2: {
789-
if (checkIsSpecificDate(localDateTime)) {
790-
return new IntegerLiteral(1);
791-
}
792800
return new IntegerLiteral(
793801
localDateTime.get(WeekFields.of(DayOfWeek.SUNDAY, 7).weekBasedYear()) * 100
794802
+ localDateTime.get(
@@ -824,18 +832,11 @@ public static Expression yearWeek(LocalDateTime localDateTime, int mode) {
824832
}
825833
default: {
826834
throw new AnalysisException(
827-
String.format("unknown mode %d in week function", mode));
835+
String.format("unknown mode %d in yearweek function", mode));
828836
}
829837
}
830838
}
831839

832-
/**
833-
* 0000-01-01 is specific date, sometime need handle it alone.
834-
*/
835-
private static boolean checkIsSpecificDate(LocalDateTime localDateTime) {
836-
return localDateTime.getYear() == 0 && localDateTime.getMonthValue() == 1 && localDateTime.getDayOfMonth() == 1;
837-
}
838-
839840
@ExecFunction(name = "weekofyear", argTypes = {"DATETIMEV2"}, returnType = "TINYINT")
840841
public static Expression weekOfYear(DateTimeV2Literal dateTime) {
841842
return new TinyIntLiteral((byte) dateTime.toJavaDateType().get(WeekFields.ISO.weekOfWeekBasedYear()));

fe/fe-core/src/test/java/org/apache/doris/nereids/trees/expressions/functions/DateTimeExtractAndTransformTest.java

Lines changed: 38 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
package org.apache.doris.nereids.trees.expressions.functions;
1919

2020
import org.apache.doris.nereids.trees.expressions.functions.executable.DateTimeExtractAndTransform;
21-
import org.apache.doris.nereids.trees.expressions.literal.IntegerLiteral;
2221
import org.apache.doris.nereids.trees.expressions.literal.TinyIntLiteral;
2322

2423
import org.junit.jupiter.api.Assertions;
@@ -28,32 +27,44 @@
2827

2928
class DateTimeExtractAndTransformTest {
3029
@Test
31-
void testWeekMode2Function() {
32-
LocalDateTime localDateTime = LocalDateTime.of(0, 1, 1, 0, 0, 0, 0);
33-
Assertions.assertEquals(new TinyIntLiteral((byte) 1), DateTimeExtractAndTransform.week(localDateTime, 2));
34-
LocalDateTime localDateTime2 = localDateTime.plusDays(1);
35-
Assertions.assertEquals(new TinyIntLiteral((byte) 1), DateTimeExtractAndTransform.week(localDateTime2, 2));
36-
LocalDateTime localDateTime3 = LocalDateTime.of(0, 1, 9, 0, 0, 0, 0);
37-
Assertions.assertEquals(new TinyIntLiteral((byte) 2), DateTimeExtractAndTransform.week(localDateTime3, 2));
38-
39-
LocalDateTime localDateTime4 = LocalDateTime.of(0, 12, 30, 0, 0, 0, 0);
40-
Assertions.assertEquals(new TinyIntLiteral((byte) 52), DateTimeExtractAndTransform.week(localDateTime4, 2));
41-
LocalDateTime localDateTime5 = localDateTime4.plusDays(1);
42-
Assertions.assertEquals(new TinyIntLiteral((byte) 53), DateTimeExtractAndTransform.week(localDateTime5, 2));
43-
}
30+
void testSpecialDateWeeks() {
31+
// test week/yearweek for 0000-01-01/02
32+
LocalDateTime time1 = LocalDateTime.of(0, 1, 1, 0, 0, 0, 0);
33+
Assertions.assertEquals(new TinyIntLiteral((byte) 1), DateTimeExtractAndTransform.week(time1, 0));
34+
Assertions.assertEquals(new TinyIntLiteral((byte) 0), DateTimeExtractAndTransform.week(time1, 1));
35+
Assertions.assertEquals(new TinyIntLiteral((byte) 1), DateTimeExtractAndTransform.week(time1, 2));
36+
Assertions.assertEquals(new TinyIntLiteral((byte) 52), DateTimeExtractAndTransform.week(time1, 3));
37+
Assertions.assertEquals(new TinyIntLiteral((byte) 1), DateTimeExtractAndTransform.week(time1, 4));
38+
Assertions.assertEquals(new TinyIntLiteral((byte) 0), DateTimeExtractAndTransform.week(time1, 5));
39+
Assertions.assertEquals(new TinyIntLiteral((byte) 1), DateTimeExtractAndTransform.week(time1, 6));
40+
Assertions.assertEquals(new TinyIntLiteral((byte) 52), DateTimeExtractAndTransform.week(time1, 7));
4441

45-
@Test
46-
void testYearWeekMode2Function() {
47-
LocalDateTime localDateTime = LocalDateTime.of(0, 1, 1, 0, 0, 0, 0);
48-
Assertions.assertEquals(new IntegerLiteral(1), DateTimeExtractAndTransform.yearWeek(localDateTime, 2));
49-
LocalDateTime localDateTime2 = localDateTime.plusDays(1);
50-
Assertions.assertEquals(new IntegerLiteral(1), DateTimeExtractAndTransform.yearWeek(localDateTime2, 2));
51-
LocalDateTime localDateTime3 = LocalDateTime.of(0, 1, 9, 0, 0, 0, 0);
52-
Assertions.assertEquals(new IntegerLiteral(2), DateTimeExtractAndTransform.yearWeek(localDateTime3, 2));
53-
54-
LocalDateTime localDateTime4 = LocalDateTime.of(0, 12, 30, 0, 0, 0, 0);
55-
Assertions.assertEquals(new IntegerLiteral(52), DateTimeExtractAndTransform.yearWeek(localDateTime4, 2));
56-
LocalDateTime localDateTime5 = localDateTime4.plusDays(1);
57-
Assertions.assertEquals(new IntegerLiteral(53), DateTimeExtractAndTransform.yearWeek(localDateTime5, 2));
42+
Assertions.assertEquals(new TinyIntLiteral((byte) 1), DateTimeExtractAndTransform.yearWeek(time1, 0));
43+
Assertions.assertEquals(new TinyIntLiteral((byte) 0), DateTimeExtractAndTransform.yearWeek(time1, 1));
44+
Assertions.assertEquals(new TinyIntLiteral((byte) 1), DateTimeExtractAndTransform.yearWeek(time1, 2));
45+
Assertions.assertEquals(new TinyIntLiteral((byte) 52), DateTimeExtractAndTransform.yearWeek(time1, 3));
46+
Assertions.assertEquals(new TinyIntLiteral((byte) 1), DateTimeExtractAndTransform.yearWeek(time1, 4));
47+
Assertions.assertEquals(new TinyIntLiteral((byte) 0), DateTimeExtractAndTransform.yearWeek(time1, 5));
48+
Assertions.assertEquals(new TinyIntLiteral((byte) 1), DateTimeExtractAndTransform.yearWeek(time1, 6));
49+
Assertions.assertEquals(new TinyIntLiteral((byte) 52), DateTimeExtractAndTransform.yearWeek(time1, 7));
50+
51+
LocalDateTime time2 = LocalDateTime.of(0, 1, 2, 0, 0, 0, 0);
52+
Assertions.assertEquals(new TinyIntLiteral((byte) 1), DateTimeExtractAndTransform.week(time2, 0));
53+
Assertions.assertEquals(new TinyIntLiteral((byte) 1), DateTimeExtractAndTransform.week(time2, 1));
54+
Assertions.assertEquals(new TinyIntLiteral((byte) 1), DateTimeExtractAndTransform.week(time2, 2));
55+
Assertions.assertEquals(new TinyIntLiteral((byte) 1), DateTimeExtractAndTransform.week(time2, 3));
56+
Assertions.assertEquals(new TinyIntLiteral((byte) 1), DateTimeExtractAndTransform.week(time2, 4));
57+
Assertions.assertEquals(new TinyIntLiteral((byte) 1), DateTimeExtractAndTransform.week(time2, 5));
58+
Assertions.assertEquals(new TinyIntLiteral((byte) 1), DateTimeExtractAndTransform.week(time2, 6));
59+
Assertions.assertEquals(new TinyIntLiteral((byte) 1), DateTimeExtractAndTransform.week(time2, 7));
60+
61+
Assertions.assertEquals(new TinyIntLiteral((byte) 1), DateTimeExtractAndTransform.yearWeek(time2, 0));
62+
Assertions.assertEquals(new TinyIntLiteral((byte) 1), DateTimeExtractAndTransform.yearWeek(time2, 1));
63+
Assertions.assertEquals(new TinyIntLiteral((byte) 1), DateTimeExtractAndTransform.yearWeek(time2, 2));
64+
Assertions.assertEquals(new TinyIntLiteral((byte) 1), DateTimeExtractAndTransform.yearWeek(time2, 3));
65+
Assertions.assertEquals(new TinyIntLiteral((byte) 1), DateTimeExtractAndTransform.yearWeek(time2, 4));
66+
Assertions.assertEquals(new TinyIntLiteral((byte) 1), DateTimeExtractAndTransform.yearWeek(time2, 5));
67+
Assertions.assertEquals(new TinyIntLiteral((byte) 1), DateTimeExtractAndTransform.yearWeek(time2, 6));
68+
Assertions.assertEquals(new TinyIntLiteral((byte) 1), DateTimeExtractAndTransform.yearWeek(time2, 7));
5869
}
5970
}

0 commit comments

Comments
 (0)