[Enhancement](planner)support fold constant for date_trunc() (#22122)
This commit is contained in:
@ -350,6 +350,83 @@ public class FEFunctions {
|
||||
return null;
|
||||
}
|
||||
|
||||
@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));
|
||||
}
|
||||
|
||||
private static LocalDateTime toMonday(LocalDateTime dateTime) {
|
||||
LocalDateTime specialUpperBound = LocalDateTime.of(1970, 1, 4, 0, 0, 0);
|
||||
LocalDateTime specialLowerBound = LocalDateTime.of(1970, 1, 1, 0, 0, 0);
|
||||
|
||||
Reference in New Issue
Block a user