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 <[email protected]>
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: [email protected]
For additional commands, e-mail: [email protected]