This is an automated email from the ASF dual-hosted git repository.

zhangstar333 pushed a commit to branch branch-2.1
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/branch-2.1 by this push:
     new 1a242b8ae09 [cherry-pick](branch2.1) fix week/yearweek function get 
wrong result (#36538)
1a242b8ae09 is described below

commit 1a242b8ae09cfd9ed02109729b0a94a00dd308a1
Author: zhangstar333 <87313068+zhangstar...@users.noreply.github.com>
AuthorDate: Thu Jun 20 15:48:19 2024 +0800

    [cherry-pick](branch2.1) fix week/yearweek function get wrong result 
(#36538)
    
    ## Proposed changes
    cherry-pick from master #36000 #36159
---
 .../executable/DateTimeExtractAndTransform.java    | 30 ++++++++++-
 .../functions/DateTimeExtractAndTransformTest.java | 59 ++++++++++++++++++++++
 .../suites/nereids_syntax_p0/explain.groovy        |  6 +++
 3 files changed, 93 insertions(+), 2 deletions(-)

diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/executable/DateTimeExtractAndTransform.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/executable/DateTimeExtractAndTransform.java
index e7a92354440..b6960d4384b 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/executable/DateTimeExtractAndTransform.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/executable/DateTimeExtractAndTransform.java
@@ -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()));
diff --git 
a/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/expressions/functions/DateTimeExtractAndTransformTest.java
 
b/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/expressions/functions/DateTimeExtractAndTransformTest.java
new file mode 100644
index 00000000000..10aa5939e31
--- /dev/null
+++ 
b/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/expressions/functions/DateTimeExtractAndTransformTest.java
@@ -0,0 +1,59 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.nereids.trees.expressions.functions;
+
+import 
org.apache.doris.nereids.trees.expressions.functions.executable.DateTimeExtractAndTransform;
+import org.apache.doris.nereids.trees.expressions.literal.IntegerLiteral;
+import org.apache.doris.nereids.trees.expressions.literal.TinyIntLiteral;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import java.time.LocalDateTime;
+
+class DateTimeExtractAndTransformTest {
+    @Test
+    void testWeekMode2Function() {
+        LocalDateTime localDateTime = LocalDateTime.of(0, 1, 1, 0, 0, 0, 0);
+        Assertions.assertEquals(new TinyIntLiteral((byte) 1), 
DateTimeExtractAndTransform.week(localDateTime, 2));
+        LocalDateTime localDateTime2 = localDateTime.plusDays(1);
+        Assertions.assertEquals(new TinyIntLiteral((byte) 1), 
DateTimeExtractAndTransform.week(localDateTime2, 2));
+        LocalDateTime localDateTime3 = LocalDateTime.of(0, 1, 9, 0, 0, 0, 0);
+        Assertions.assertEquals(new TinyIntLiteral((byte) 2), 
DateTimeExtractAndTransform.week(localDateTime3, 2));
+
+        LocalDateTime localDateTime4 = LocalDateTime.of(0, 12, 30, 0, 0, 0, 0);
+        Assertions.assertEquals(new TinyIntLiteral((byte) 52), 
DateTimeExtractAndTransform.week(localDateTime4, 2));
+        LocalDateTime localDateTime5 = localDateTime4.plusDays(1);
+        Assertions.assertEquals(new TinyIntLiteral((byte) 53), 
DateTimeExtractAndTransform.week(localDateTime5, 2));
+    }
+
+    @Test
+    void testYearWeekMode2Function() {
+        LocalDateTime localDateTime = LocalDateTime.of(0, 1, 1, 0, 0, 0, 0);
+        Assertions.assertEquals(new IntegerLiteral(1), 
DateTimeExtractAndTransform.yearWeek(localDateTime, 2));
+        LocalDateTime localDateTime2 = localDateTime.plusDays(1);
+        Assertions.assertEquals(new IntegerLiteral(1), 
DateTimeExtractAndTransform.yearWeek(localDateTime2, 2));
+        LocalDateTime localDateTime3 = LocalDateTime.of(0, 1, 9, 0, 0, 0, 0);
+        Assertions.assertEquals(new IntegerLiteral(2), 
DateTimeExtractAndTransform.yearWeek(localDateTime3, 2));
+
+        LocalDateTime localDateTime4 = LocalDateTime.of(0, 12, 30, 0, 0, 0, 0);
+        Assertions.assertEquals(new IntegerLiteral(52), 
DateTimeExtractAndTransform.yearWeek(localDateTime4, 2));
+        LocalDateTime localDateTime5 = localDateTime4.plusDays(1);
+        Assertions.assertEquals(new IntegerLiteral(53), 
DateTimeExtractAndTransform.yearWeek(localDateTime5, 2));
+    }
+}
diff --git a/regression-test/suites/nereids_syntax_p0/explain.groovy 
b/regression-test/suites/nereids_syntax_p0/explain.groovy
index f0554473ec3..0e599b1beaa 100644
--- a/regression-test/suites/nereids_syntax_p0/explain.groovy
+++ b/regression-test/suites/nereids_syntax_p0/explain.groovy
@@ -68,4 +68,10 @@ suite("nereids_explain") {
 
     def explainStr = sql("select sum(if(lo_tax=1,lo_tax,0)) from lineorder 
where false").toString()
     assertTrue(!explainStr.contains("projections"))
+
+    explain {
+        sql("select week(cast('0000-01-01' as DATEV2), cast(2 as INT));")
+        notContains "week"
+        contains "1"
+    }
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org
For additional commands, e-mail: commits-h...@doris.apache.org

Reply via email to