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

morrysnow pushed a commit to branch branch-1.2-lts
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/branch-1.2-lts by this push:
     new 4fa805a670 [Enhancement](planner) support fold constant date_trunc() 
function. (#21995)
4fa805a670 is described below

commit 4fa805a670e43efe58bbeec1aa9420f1ccce70aa
Author: mch_ucchi <41606806+sohardforan...@users.noreply.github.com>
AuthorDate: Fri Jul 21 18:20:14 2023 +0800

    [Enhancement](planner) support fold constant date_trunc() function. (#21995)
---
 .../java/org/apache/doris/rewrite/FEFunctions.java | 77 ++++++++++++++++++++++
 .../datetime_functions/test_date_function.groovy   |  3 +
 2 files changed, 80 insertions(+)

diff --git a/fe/fe-core/src/main/java/org/apache/doris/rewrite/FEFunctions.java 
b/fe/fe-core/src/main/java/org/apache/doris/rewrite/FEFunctions.java
index 81cff97b1b..9449edc71b 100755
--- a/fe/fe-core/src/main/java/org/apache/doris/rewrite/FEFunctions.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/rewrite/FEFunctions.java
@@ -151,6 +151,83 @@ public class FEFunctions {
         return new StringLiteral(result);
     }
 
+    @FEFunction(name = "date_trunc", argTypes = {"DATETIME", "VARCHAR"}, 
returnType = "DATETIME")
+    public static DateLiteral dateTrunc(LiteralExpr date, LiteralExpr 
truncate) {
+        if (date.getType().isDateLike()) {
+            DateLiteral dateLiteral = ((DateLiteral) date);
+            LocalDateTime localDate = dateTruncHelper(LocalDateTime.of(
+                    (int) dateLiteral.getYear(), (int) dateLiteral.getMonth(), 
(int) dateLiteral.getDay(),
+                    (int) dateLiteral.getHour(), (int) 
dateLiteral.getMinute(), (int) dateLiteral.getSecond()),
+                    truncate.getStringValue());
+
+            return new DateLiteral(localDate.getYear(), 
localDate.getMonthValue(), localDate.getDayOfMonth(),
+                    localDate.getHour(), localDate.getMinute(), 
localDate.getSecond(), date.getType());
+        }
+        return null;
+    }
+
+    @FEFunction(name = "date_trunc", argTypes = {"DATETIMEV2", "VARCHAR"}, 
returnType = "DATETIMEV2")
+    public static DateLiteral dateTruncV2(LiteralExpr date, LiteralExpr 
truncate) {
+        if (date.getType().isDateLike()) {
+            DateLiteral dateLiteral = ((DateLiteral) date);
+            LocalDateTime localDate = dateTruncHelper(LocalDateTime.of(
+                            (int) dateLiteral.getYear(), (int) 
dateLiteral.getMonth(), (int) dateLiteral.getDay(),
+                            (int) dateLiteral.getHour(), (int) 
dateLiteral.getMinute(), (int) dateLiteral.getSecond()),
+                    truncate.getStringValue());
+
+            return new DateLiteral(localDate.getYear(), 
localDate.getMonthValue(), localDate.getDayOfMonth(),
+                    localDate.getHour(), localDate.getMinute(), 
localDate.getSecond(), date.getType());
+        }
+        return null;
+    }
+
+    private static LocalDateTime dateTruncHelper(LocalDateTime dateTime, 
String trunc) {
+        int year = dateTime.getYear();
+        int month = dateTime.getMonthValue();
+        int day = dateTime.getDayOfMonth();
+        int hour = dateTime.getHour();
+        int minute = dateTime.getMinute();
+        int second = dateTime.getSecond();
+        switch (trunc.toLowerCase()) {
+            case "year":
+                month = 0;
+            case "quarter": // CHECKSTYLE IGNORE THIS LINE
+                month = ((month - 1) / 3) * 3 + 1;
+            case "month": // CHECKSTYLE IGNORE THIS LINE
+                day = 1;
+                break;
+            case "week":
+                LocalDateTime firstDayOfWeek = firstDayOfWeek(dateTime);
+                year = firstDayOfWeek.getYear();
+                month = firstDayOfWeek.getMonthValue();
+                day = firstDayOfWeek.getDayOfMonth();
+            default: // CHECKSTYLE IGNORE THIS LINE
+                break;
+        }
+        switch (trunc.toLowerCase()) {
+            case "year":
+            case "quarter":
+            case "month":
+            case "week":
+            case "day": // CHECKSTYLE IGNORE THIS LINE
+                hour = 0;
+            case "hour": // CHECKSTYLE IGNORE THIS LINE
+                minute = 0;
+            case "minute": // CHECKSTYLE IGNORE THIS LINE
+                second = 0;
+            default: // CHECKSTYLE IGNORE THIS LINE
+        }
+        return LocalDateTime.of(year, month, day, hour, minute, second);
+    }
+
+    private static int distanceToFirstDayOfWeek(LocalDateTime dateTime) {
+        return dateTime.getDayOfWeek().getValue() - 1;
+    }
+
+    private static LocalDateTime firstDayOfWeek(LocalDateTime dateTime) {
+        return dateTime.plusDays(-distanceToFirstDayOfWeek(dateTime));
+    }
+
     @FEFunction(name = "str_to_date", argTypes = { "VARCHAR", "VARCHAR" }, 
returnType = "DATETIME")
     public static DateLiteral dateParse(StringLiteral date, StringLiteral 
fmtLiteral) throws AnalysisException {
         DateLiteral dateLiteral = new DateLiteral();
diff --git 
a/regression-test/suites/query_p0/sql_functions/datetime_functions/test_date_function.groovy
 
b/regression-test/suites/query_p0/sql_functions/datetime_functions/test_date_function.groovy
index 2454f76275..8359900214 100644
--- 
a/regression-test/suites/query_p0/sql_functions/datetime_functions/test_date_function.groovy
+++ 
b/regression-test/suites/query_p0/sql_functions/datetime_functions/test_date_function.groovy
@@ -631,6 +631,9 @@ suite("test_date_function") {
         sql("select * from ${tableName} where date(birth1) < timestamp(date 
'2022-01-01')")
         contains "`birth1` < '2022-01-01'"
     }
+    
+    def result = sql "explain select date_trunc('2021-01-01 00:00:12', 
'month')"
+    assertFalse(result[0][0].contains("date_trunc"))
 
     sql """
         insert into ${tableName} values 


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

Reply via email to