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