From e91d16854b6a6c61d61a354c2de6bad5578c94de Mon Sep 17 00:00:00 2001 From: lw112 <131352377+felixwluo@users.noreply.github.com> Date: Thu, 7 Mar 2024 12:04:48 +0800 Subject: [PATCH] [fix](function) fix date_format function execution error on fe (#31645) --- .../main/java/org/apache/doris/analysis/DateLiteral.java | 8 +++++++- .../java/org/apache/doris/nereids/util/DateUtils.java | 8 +++++++- .../doris/nereids/rules/expression/FoldConstantTest.java | 2 +- .../java/org/apache/doris/rewrite/FEFunctionsTest.java | 2 +- .../datetime_functions/test_date_function.out | 6 ++++++ .../datetime_functions/test_date_function.out | 6 ++++++ .../datetime_functions/test_date_function.groovy | 2 ++ .../datetime_functions/test_date_function.groovy | 2 ++ 8 files changed, 32 insertions(+), 4 deletions(-) diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/DateLiteral.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/DateLiteral.java index 37171b70fa..5c16814707 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/DateLiteral.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/DateLiteral.java @@ -45,6 +45,7 @@ import java.io.IOException; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.sql.Timestamp; +import java.time.DayOfWeek; import java.time.LocalDateTime; import java.time.Year; import java.time.ZoneId; @@ -53,10 +54,12 @@ import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatterBuilder; import java.time.format.DateTimeParseException; import java.time.format.ResolverStyle; +import java.time.format.SignStyle; import java.time.format.TextStyle; import java.time.temporal.ChronoField; import java.time.temporal.IsoFields; import java.time.temporal.TemporalAccessor; +import java.time.temporal.WeekFields; import java.util.Collections; import java.util.List; import java.util.Map; @@ -108,6 +111,7 @@ public class DateLiteral extends LiteralExpr { private static Map WEEK_DAY_NAME_DICT = Maps.newHashMap(); private static Set TIME_PART_SET = Sets.newHashSet(); private static final int[] DAYS_IN_MONTH = new int[] {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; + private static final WeekFields weekFields = WeekFields.of(DayOfWeek.SUNDAY, 7); static { try { @@ -1047,7 +1051,7 @@ public class DateLiteral extends LiteralExpr { builder.appendPattern("HH:mm:ss"); break; case 'V': // %V Week (01..53), where Sunday is the first day of the week; used with %X - builder.appendValue(ChronoField.ALIGNED_WEEK_OF_YEAR, 2); + builder.appendValue(weekFields.weekOfWeekBasedYear(), 2); break; case 'v': // %v Week (01..53), where Monday is the first day of the week; used with %x builder.appendValue(IsoFields.WEEK_OF_WEEK_BASED_YEAR, 2); @@ -1059,6 +1063,8 @@ public class DateLiteral extends LiteralExpr { builder.appendValue(IsoFields.WEEK_BASED_YEAR, 4); break; case 'X': + builder.appendValue(weekFields.weekBasedYear(), 4, 10, SignStyle.EXCEEDS_PAD); + break; case 'Y': // %Y Year, numeric, four digits // %X Year for the week, where Sunday is the first day of the week, // numeric, four digits; used with %v diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/util/DateUtils.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/util/DateUtils.java index bd09bfa342..70f25b25fc 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/util/DateUtils.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/util/DateUtils.java @@ -20,19 +20,23 @@ package org.apache.doris.nereids.util; import org.apache.doris.nereids.exceptions.AnalysisException; import org.apache.doris.qe.ConnectContext; +import java.time.DayOfWeek; import java.time.LocalDateTime; import java.time.ZoneId; import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatterBuilder; +import java.time.format.SignStyle; import java.time.format.TextStyle; import java.time.temporal.ChronoField; import java.time.temporal.IsoFields; import java.time.temporal.TemporalAccessor; +import java.time.temporal.WeekFields; /** * date util tools. */ public class DateUtils { + private static final WeekFields weekFields = WeekFields.of(DayOfWeek.SUNDAY, 7); /** * format builder. @@ -103,7 +107,7 @@ public class DateUtils { builder.appendPattern("HH:mm:ss"); break; case 'V': // %V Week (01..53), where Sunday is the first day of the week; used with %X - builder.appendValue(ChronoField.ALIGNED_WEEK_OF_YEAR, 2); + builder.appendValue(weekFields.weekOfWeekBasedYear(), 2); break; case 'v': // %v Week (01..53), where Monday is the first day of the week; used with %x builder.appendValue(IsoFields.WEEK_OF_WEEK_BASED_YEAR, 2); @@ -115,6 +119,8 @@ public class DateUtils { builder.appendValue(IsoFields.WEEK_BASED_YEAR, 4); break; case 'X': + builder.appendValue(weekFields.weekBasedYear(), 4, 10, SignStyle.EXCEEDS_PAD); + break; case 'Y': // %Y Year, numeric, four digits // %X Year for the week, where Sunday is the first day of the week, // numeric, four digits; used with %v diff --git a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/FoldConstantTest.java b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/FoldConstantTest.java index 5132fd27ff..3b8fbc8526 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/FoldConstantTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/FoldConstantTest.java @@ -491,7 +491,7 @@ class FoldConstantTest extends ExpressionRewriteTestHelper { Assertions.assertEquals(DateTimeExtractAndTransform.date(dateLiteral).toSql(), answer[answerIdx++]); Assertions.assertEquals(DateTimeExtractAndTransform.dateV2(dateLiteral).toSql(), answer[answerIdx]); - Assertions.assertEquals("'2021 52 2022 01'", DateTimeExtractAndTransform.dateFormat( + Assertions.assertEquals("'2021 52 2021 52'", DateTimeExtractAndTransform.dateFormat( new DateTimeLiteral("2022-01-01 00:12:42"), new VarcharLiteral("%x %v %X %V")).toSql()); Assertions.assertEquals("'2023 18 2023 19'", DateTimeExtractAndTransform.dateFormat( diff --git a/fe/fe-core/src/test/java/org/apache/doris/rewrite/FEFunctionsTest.java b/fe/fe-core/src/test/java/org/apache/doris/rewrite/FEFunctionsTest.java index 727a663562..b405d78721 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/rewrite/FEFunctionsTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/rewrite/FEFunctionsTest.java @@ -386,7 +386,7 @@ public class FEFunctionsTest { new StringLiteral("2013-05-17 08:07:05 PM"), new StringLiteral("%Y-%m-%d %r")).getStringValue()); Assert.assertEquals("2013-05-17 08:07:05", FEFunctions.dateParse(new StringLiteral("2013-05-17 08:07:05"), new StringLiteral("%Y-%m-%d %T")).getStringValue()); - Assert.assertEquals("2021 52 2022 01", FEFunctions.dateFormat(new DateLiteral("2022-01-01 00:12:42", Type.DATETIMEV2), + Assert.assertEquals("2021 52 2021 52", FEFunctions.dateFormat(new DateLiteral("2022-01-01 00:12:42", Type.DATETIMEV2), new StringLiteral("%x %v %X %V")).getStringValue()); Assert.assertEquals("2023 18 2023 19", FEFunctions.dateFormat(new DateLiteral("2023-05-07 02:41:42", Type.DATETIMEV2), new StringLiteral("%x %v %X %V")).getStringValue()); diff --git a/regression-test/data/nereids_p0/sql_functions/datetime_functions/test_date_function.out b/regression-test/data/nereids_p0/sql_functions/datetime_functions/test_date_function.out index 086faf0c85..46a6256615 100644 --- a/regression-test/data/nereids_p0/sql_functions/datetime_functions/test_date_function.out +++ b/regression-test/data/nereids_p0/sql_functions/datetime_functions/test_date_function.out @@ -479,6 +479,12 @@ true -- !sql -- true +-- !sql -- +1998 52 + +-- !sql -- +2024 52 + -- !sql -- 2022 31 4 diff --git a/regression-test/data/query_p0/sql_functions/datetime_functions/test_date_function.out b/regression-test/data/query_p0/sql_functions/datetime_functions/test_date_function.out index dc1d05c9d4..ffd8d5b8cd 100644 --- a/regression-test/data/query_p0/sql_functions/datetime_functions/test_date_function.out +++ b/regression-test/data/query_p0/sql_functions/datetime_functions/test_date_function.out @@ -496,6 +496,12 @@ true -- !sql -- true +-- !sql -- +1998 52 + +-- !sql -- +2024 52 + -- !sql -- 2022 31 4 diff --git a/regression-test/suites/nereids_p0/sql_functions/datetime_functions/test_date_function.groovy b/regression-test/suites/nereids_p0/sql_functions/datetime_functions/test_date_function.groovy index 633e884dad..58413e29ce 100644 --- a/regression-test/suites/nereids_p0/sql_functions/datetime_functions/test_date_function.groovy +++ b/regression-test/suites/nereids_p0/sql_functions/datetime_functions/test_date_function.groovy @@ -470,6 +470,8 @@ suite("test_date_function") { sql """ drop table ${tableName} """ + qt_sql """ select date_format('1999-01-01', '%X %V'); """ + qt_sql """ select date_format('2025-01-01', '%X %V'); """ qt_sql """ select date_format('2022-08-04', '%X %V %w'); """ qt_sql """ select STR_TO_DATE('Tue Jul 12 20:00:45 CST 2022', '%a %b %e %H:%i:%s %Y'); """ qt_sql """ select STR_TO_DATE('Tue Jul 12 20:00:45 CST 2022', '%a %b %e %T CST %Y'); """ 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 cbef7072b2..ba48c34f40 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 @@ -473,6 +473,8 @@ suite("test_date_function") { sql """ drop table ${tableName} """ + qt_sql """ select date_format('1999-01-01', '%X %V'); """ + qt_sql """ select date_format('2025-01-01', '%X %V'); """ qt_sql """ select date_format('2022-08-04', '%X %V %w'); """ qt_sql """ select STR_TO_DATE('Tue Jul 12 20:00:45 CST 2022', '%a %b %e %H:%i:%s %Y'); """ qt_sql """ select STR_TO_DATE('Tue Jul 12 20:00:45 CST 2022', '%a %b %e %T CST %Y'); """