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

dataroaring pushed a commit to branch branch-3.0
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/branch-3.0 by this push:
     new b5232d2bc95 branch-3.0: [fix](Nereids) fold str_to_date to wrong 
result when parameter out range #49033 (#49151)
b5232d2bc95 is described below

commit b5232d2bc95802f6054fd87212ca71d0f3928d59
Author: LiBinfeng <libinf...@selectdb.com>
AuthorDate: Thu Mar 27 17:40:01 2025 +0800

    branch-3.0: [fix](Nereids) fold str_to_date to wrong result when parameter 
out range #49033 (#49151)
    
    pick: #49033
    
    Related PR: #18209
    
    Problem Summary:
    
    SELECT STR_TO_DATE('2025-04-31', '%Y-%m-%d') AS result; would be changed
    to result 2025-04-30 in smart mode by mistake
---
 .../executable/DateTimeExtractAndTransform.java    | 26 +++++++++++-----------
 .../org/apache/doris/nereids/util/DateUtils.java   |  6 +++--
 .../fold_constant_date_arithmatic.groovy           | 10 +++++++++
 3 files changed, 27 insertions(+), 15 deletions(-)

diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/executable/DateTimeExtractAndTransform.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/executable/DateTimeExtractAndTransform.java
index 763cc492ef6..0cf8e38fcbc 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/executable/DateTimeExtractAndTransform.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/executable/DateTimeExtractAndTransform.java
@@ -295,14 +295,14 @@ public class DateTimeExtractAndTransform {
     @ExecFunction(name = "date_format")
     public static Expression dateFormat(DateLiteral date, StringLikeLiteral 
format) {
         format = (StringLikeLiteral) 
SupportJavaDateFormatter.translateJavaFormatter(format);
-        return new 
VarcharLiteral(DateUtils.formatBuilder(format.getValue()).toFormatter(Locale.US).format(
+        return new 
VarcharLiteral(DateUtils.dateTimeFormatter(format.getValue()).format(
                 java.time.LocalDate.of(((int) date.getYear()), ((int) 
date.getMonth()), ((int) date.getDay()))));
     }
 
     @ExecFunction(name = "date_format")
     public static Expression dateFormat(DateTimeLiteral date, 
StringLikeLiteral format) {
         format = (StringLikeLiteral) 
SupportJavaDateFormatter.translateJavaFormatter(format);
-        return new 
VarcharLiteral(DateUtils.formatBuilder(format.getValue()).toFormatter(Locale.US).format(
+        return new 
VarcharLiteral(DateUtils.dateTimeFormatter(format.getValue()).format(
                 java.time.LocalDateTime.of(((int) date.getYear()), ((int) 
date.getMonth()), ((int) date.getDay()),
                         ((int) date.getHour()), ((int) date.getMinute()), 
((int) date.getSecond()))));
     }
@@ -310,14 +310,14 @@ public class DateTimeExtractAndTransform {
     @ExecFunction(name = "date_format")
     public static Expression dateFormat(DateV2Literal date, StringLikeLiteral 
format) {
         format = (StringLikeLiteral) 
SupportJavaDateFormatter.translateJavaFormatter(format);
-        return new 
VarcharLiteral(DateUtils.formatBuilder(format.getValue()).toFormatter(Locale.US).format(
+        return new 
VarcharLiteral(DateUtils.dateTimeFormatter(format.getValue()).format(
                 java.time.LocalDate.of(((int) date.getYear()), ((int) 
date.getMonth()), ((int) date.getDay()))));
     }
 
     @ExecFunction(name = "date_format")
     public static Expression dateFormat(DateTimeV2Literal date, 
StringLikeLiteral format) {
         format = (StringLikeLiteral) 
SupportJavaDateFormatter.translateJavaFormatter(format);
-        return new 
VarcharLiteral(DateUtils.formatBuilder(format.getValue()).toFormatter(Locale.US).format(
+        return new 
VarcharLiteral(DateUtils.dateTimeFormatter(format.getValue()).format(
                 java.time.LocalDateTime.of(((int) date.getYear()), ((int) 
date.getMonth()), ((int) date.getDay()),
                         ((int) date.getHour()), ((int) date.getMinute()), 
((int) date.getSecond()))));
     }
@@ -539,7 +539,7 @@ public class DateTimeExtractAndTransform {
     @ExecFunction(name = "unix_timestamp")
     public static Expression unixTimestamp(StringLikeLiteral date, 
StringLikeLiteral format) {
         format = (StringLikeLiteral) 
SupportJavaDateFormatter.translateJavaFormatter(format);
-        DateTimeFormatter formatter = 
DateUtils.formatBuilder(format.getValue()).toFormatter();
+        DateTimeFormatter formatter = 
DateUtils.dateTimeFormatter(format.getValue());
         LocalDateTime dateObj;
         try {
             dateObj = LocalDateTime.parse(date.getValue(), formatter);
@@ -628,20 +628,20 @@ public class DateTimeExtractAndTransform {
         if 
(org.apache.doris.analysis.DateLiteral.hasTimePart(format.getStringValue())) {
             DataType returnType = 
DataType.fromCatalogType(ScalarType.getDefaultDateType(Type.DATETIME));
             if (returnType instanceof DateTimeV2Type) {
-                return 
DateTimeV2Literal.fromJavaDateType(DateUtils.getTime(DateUtils.formatBuilder(format.getValue())
-                        .toFormatter(), str.getValue()));
+                return 
DateTimeV2Literal.fromJavaDateType(DateUtils.getTime(DateUtils
+                        .dateTimeFormatter(format.getValue()), 
str.getValue()));
             } else {
-                return 
DateTimeLiteral.fromJavaDateType(DateUtils.getTime(DateUtils.formatBuilder(format.getValue())
-                        .toFormatter(), str.getValue()));
+                return 
DateTimeLiteral.fromJavaDateType(DateUtils.getTime(DateUtils
+                        .dateTimeFormatter(format.getValue()), 
str.getValue()));
             }
         } else {
             DataType returnType = 
DataType.fromCatalogType(ScalarType.getDefaultDateType(Type.DATE));
             if (returnType instanceof DateV2Type) {
-                return 
DateV2Literal.fromJavaDateType(DateUtils.getTime(DateUtils.formatBuilder(format.getValue())
-                        .toFormatter(), str.getValue()));
+                return 
DateV2Literal.fromJavaDateType(DateUtils.getTime(DateUtils.dateTimeFormatter(format.getValue()),
+                        str.getValue()));
             } else {
-                return 
DateLiteral.fromJavaDateType(DateUtils.getTime(DateUtils.formatBuilder(format.getValue())
-                        .toFormatter(), str.getValue()));
+                return 
DateLiteral.fromJavaDateType(DateUtils.getTime(DateUtils.dateTimeFormatter(format.getValue()),
+                        str.getValue()));
             }
         }
     }
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 c0563de5d10..e26c792a9bd 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
@@ -25,12 +25,14 @@ import java.time.LocalDateTime;
 import java.time.ZoneId;
 import java.time.format.DateTimeFormatter;
 import java.time.format.DateTimeFormatterBuilder;
+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.Locale;
 
 /**
  * date util tools.
@@ -41,7 +43,7 @@ public class DateUtils {
     /**
      * format builder.
      */
-    public static DateTimeFormatterBuilder formatBuilder(String pattern) 
throws AnalysisException {
+    public static DateTimeFormatter dateTimeFormatter(String pattern) throws 
AnalysisException {
         DateTimeFormatterBuilder builder = new DateTimeFormatterBuilder();
         boolean escaped = false;
         for (int i = 0; i < pattern.length(); i++) {
@@ -153,7 +155,7 @@ public class DateUtils {
                 builder.appendLiteral(character);
             }
         }
-        return builder;
+        return 
builder.toFormatter(Locale.US).withResolverStyle(ResolverStyle.STRICT);
     }
 
     /**
diff --git 
a/regression-test/suites/nereids_p0/expression/fold_constant/fold_constant_date_arithmatic.groovy
 
b/regression-test/suites/nereids_p0/expression/fold_constant/fold_constant_date_arithmatic.groovy
index e19a01b2a38..ccd3547deef 100644
--- 
a/regression-test/suites/nereids_p0/expression/fold_constant/fold_constant_date_arithmatic.groovy
+++ 
b/regression-test/suites/nereids_p0/expression/fold_constant/fold_constant_date_arithmatic.groovy
@@ -38,4 +38,14 @@ suite("fold_constant_date_arithmatic") {
     testFoldConst("SELECT date_format('2020-12-01 12:00:30.01', '%I');")
     testFoldConst("SELECT date_format('2020-12-01 12:00:30.01', '%l');")
     testFoldConst("SELECT date_format('2020-12-01 12:00:30.01', '%r');")
+    
+    testFoldConst("select str_to_date('2023-02-29', '%Y-%m-%d') AS result;")
+    testFoldConst("select str_to_date('1900-02-29', '%Y-%m-%d') AS result;")
+    testFoldConst("select str_to_date('2025-04-31', '%Y-%m-%d') AS result;")
+    testFoldConst("select str_to_date('31-12-2020 23:59:59', '%d-%m-%Y 
%H:%i:%s');")
+    testFoldConst("select str_to_date('2020-12-31T23:59:59', 
'%Y-%m-%dT%H:%i:%s');")
+    testFoldConst("select str_to_date('20201231235959', '%Y%m%d%H%i%s');")
+    testFoldConst("select str_to_date('31/12/2020 23:59', '%d/%m/%Y %H:%i');")
+    testFoldConst("select str_to_date('31/12/2020 11:59 PM', '%d/%m/%Y %h:%i 
%p');")
+    testFoldConst("select str_to_date('20201231T235959', '%Y%m%dT%H%i%s');")
 }


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

Reply via email to