branch-2.1: [fix](Nereids) fold str_to_date to wrong result when parameter out of range #49033 (#49150)

This commit is contained in:
LiBinfeng
2025-03-18 11:01:49 +08:00
committed by GitHub
parent 68f50b569b
commit bd5d0ca741
3 changed files with 27 additions and 15 deletions

View File

@ -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()));
}
}
}

View File

@ -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);
}
/**

View File

@ -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');")
}