From bf80585c2c4718f8a18a71e4a633ce9afc4283e5 Mon Sep 17 00:00:00 2001 From: linrrarity Date: Fri, 23 Oct 2026 14:43:20 +0800 Subject: [PATCH] [fix](nereids) Fold UTC_DATE and UTC_TIME in FE (#69393) ### What problem does this PR solve? Issue Number: close #69368 Related PR: #57347 Problem Summary: `UTC_DATE()` and `UTC_TIME()` lack FE constant folding support, preventing partition pruning for predicates such as `ts >= UTC_DATE()`. ### Release note Add FE constant folding for `UTC_DATE()` and both overloads of `UTC_TIME()`, using the statement start time in UTC. --- .../functions/executable/DateTimeAcquire.java | 15 ++++ .../nereids_p0/datatype/test_date_acquire.out | 60 +++++++++++++++- .../datatype/test_date_acquire.groovy | 71 +++++++++++++++++++ 3 files changed, 143 insertions(+), 3 deletions(-) diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/executable/DateTimeAcquire.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/executable/DateTimeAcquire.java index 3596d5950e2297..60d142af16b73d 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/executable/DateTimeAcquire.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/executable/DateTimeAcquire.java @@ -162,4 +162,19 @@ public static Expression utcTimestamp() { public static Expression utcTimestamp(IntegerLiteral precision) { return currentTimestamp(precision.getValue(), ZoneId.of("UTC+0")); } + + @ExecFunction(name = "utc_date") + public static Expression utcDate() { + return DateV2Literal.fromJavaDateType(currentDateTime(ZoneId.of("UTC+0"))); + } + + @ExecFunction(name = "utc_time") + public static Expression utcTime() { + return TimeV2Literal.fromJavaDateType(currentDateTime(ZoneId.of("UTC+0"))); + } + + @ExecFunction(name = "utc_time") + public static Expression utcTime(IntegerLiteral precision) { + return TimeV2Literal.fromJavaDateType(currentDateTime(ZoneId.of("UTC+0")), precision.getValue()); + } } diff --git a/regression-test/data/nereids_p0/datatype/test_date_acquire.out b/regression-test/data/nereids_p0/datatype/test_date_acquire.out index aa7b1098a7fec9..2e1e611d491380 100644 --- a/regression-test/data/nereids_p0/datatype/test_date_acquire.out +++ b/regression-test/data/nereids_p0/datatype/test_date_acquire.out @@ -1,10 +1,64 @@ -- This file is automatically generated. You should know what you did if you want to edit this -- !sql -- -2019-03-21 15:10:55 1196389819 +2019-03-21 15:10:55 1196389819.000000 -- !sql -- -2019-03-21 07:10:55 1196418619 +2019-03-21 07:10:55 1196418619.000000 -- !sql -- -2019-03-21 11:10:55 1196404219 +2019-03-21 11:10:55 1196404219.000000 + +-- !utc_today -- +3 + +-- !utc_yesterday -- +3 + +-- !utc_values -- +true true true true true true true true true + +-- !utc_today -- +3 + +-- !utc_yesterday -- +3 + +-- !utc_values -- +true true true true true true true true true + +-- !utc_today -- +3 + +-- !utc_yesterday -- +3 + +-- !utc_values -- +true true true true true true true true true + +-- !utc_today -- +3 + +-- !utc_yesterday -- +3 + +-- !utc_values -- +true true true true true true true true true + +-- !utc_today -- +3 + +-- !utc_yesterday -- +3 + +-- !utc_values -- +true true true true true true true true true + +-- !utc_today -- +3 + +-- !utc_yesterday -- +3 + +-- !utc_values -- +true true true true true true true true true diff --git a/regression-test/suites/nereids_p0/datatype/test_date_acquire.groovy b/regression-test/suites/nereids_p0/datatype/test_date_acquire.groovy index 4a4579d579dd2b..2e3a7afc6a738f 100644 --- a/regression-test/suites/nereids_p0/datatype/test_date_acquire.groovy +++ b/regression-test/suites/nereids_p0/datatype/test_date_acquire.groovy @@ -34,4 +34,75 @@ suite("test_date_acquire") { sql "set time_zone='+04:00'" qt_sql "select from_unixtime(1553152255), unix_timestamp('2007-11-30 10:30%3A19', '%Y-%m-%d %H:%i%%3A%s')" + + sql "DROP TABLE IF EXISTS utc_function_folding" + sql """ + CREATE TABLE utc_function_folding ( + ts DATETIME NOT NULL, + v INT + ) + DUPLICATE KEY(ts) + PARTITION BY RANGE(ts) ( + PARTITION p_before_1970 VALUES LESS THAN ('1970-01-01'), + PARTITION p_before_2000 VALUES LESS THAN ('2000-01-01'), + PARTITION p_current VALUES LESS THAN MAXVALUE + ) + DISTRIBUTED BY HASH(v) BUCKETS 1 + PROPERTIES ("replication_num" = "1") + """ + sql """INSERT INTO utc_function_folding VALUES + ('1960-01-01', 1), ('1990-01-01', 2), ('9999-01-01', 3) + """ + + def utcValues = """ + SELECT UTC_DATE() = CAST(UTC_TIMESTAMP() AS DATE), + UTC_TIME() = CAST(UTC_TIMESTAMP() AS TIME), + UTC_TIME(0) = CAST(UTC_TIMESTAMP(0) AS TIME(0)), + UTC_TIME(1) = CAST(UTC_TIMESTAMP(1) AS TIME(1)), + UTC_TIME(2) = CAST(UTC_TIMESTAMP(2) AS TIME(2)), + UTC_TIME(3) = CAST(UTC_TIMESTAMP(3) AS TIME(3)), + UTC_TIME(4) = CAST(UTC_TIMESTAMP(4) AS TIME(4)), + UTC_TIME(5) = CAST(UTC_TIMESTAMP(5) AS TIME(5)), + UTC_TIME(6) = CAST(UTC_TIMESTAMP(6) AS TIME(6)) + """ + def today = "SELECT v FROM utc_function_folding WHERE ts >= UTC_DATE() ORDER BY v" + def yesterday = """SELECT v FROM utc_function_folding + WHERE ts >= UTC_DATE() - INTERVAL 1 DAY ORDER BY v""" + def previous = sql "SELECT @@time_zone, @@enable_fold_constant_by_be, @@debug_skip_fold_constant" + try { + for (def foldByBe : [false, true]) { + sql "SET enable_fold_constant_by_be=${foldByBe}" + for (def timeZone : ["+00:00", "+08:00", "-08:00"]) { + sql "SET time_zone='${timeZone}'" + sql "SET debug_skip_fold_constant=false" + explain { + sql today + contains "partitions=1/3 (p_current)" + notContains "utc_date()" + } + explain { + sql yesterday + contains "partitions=1/3 (p_current)" + notContains "utc_date()" + } + explain { + sql "SELECT UTC_DATE(), UTC_TIME(), UTC_TIME(0), UTC_TIME(1), UTC_TIME(2), " + + "UTC_TIME(3), UTC_TIME(4), UTC_TIME(5), UTC_TIME(6)" + notContains "utc_date(" + notContains "utc_time(" + } + qt_utc_today today + qt_utc_yesterday yesterday + qt_utc_values utcValues + testFoldConst(today) + testFoldConst(yesterday) + testFoldConst(utcValues) + } + } + } finally { + sql "SET time_zone='${previous[0][0]}'" + sql "SET enable_fold_constant_by_be=${previous[0][1]}" + sql "SET debug_skip_fold_constant=${previous[0][2]}" + sql "DROP TABLE IF EXISTS utc_function_folding" + } }