imay commented on a change in pull request #1644: Refactor DateLiteral class in
FE
URL: https://github.com/apache/incubator-doris/pull/1644#discussion_r317677438
##########
File path: fe/src/main/java/org/apache/doris/rewrite/FEFunctions.java
##########
@@ -92,415 +89,67 @@ public static DateLiteral daysAdd(LiteralExpr date,
LiteralExpr day) throws Anal
@FEFunction(name = "date_format", argTypes = { "DATETIME", "VARCHAR" },
returnType = "VARCHAR")
public static StringLiteral dateFormat(LiteralExpr date, StringLiteral
fmtLiteral) throws AnalysisException {
- String result = dateFormat(new Date(getTime(date)),
fmtLiteral.getStringValue());
+ String result = ((DateLiteral)
date).dateFormat(fmtLiteral.getStringValue());
return new StringLiteral(result);
}
@FEFunction(name = "str_to_date", argTypes = { "VARCHAR", "VARCHAR" },
returnType = "DATETIME")
public static DateLiteral dateParse(StringLiteral date, StringLiteral
fmtLiteral) throws AnalysisException {
- boolean hasTimePart = false;
- DateTimeFormatterBuilder builder = new DateTimeFormatterBuilder();
-
- String formatString = fmtLiteral.getStringValue();
- boolean escaped = false;
- for (int i = 0; i < formatString.length(); i++) {
- char character = formatString.charAt(i);
-
- if (escaped) {
- switch (character) {
- case 'a': // %a Abbreviated weekday name (Sun..Sat)
- builder.appendDayOfWeekShortText();
- break;
- case 'b': // %b Abbreviated month name (Jan..Dec)
- builder.appendMonthOfYearShortText();
- break;
- case 'c': // %c Month, numeric (0..12)
- builder.appendMonthOfYear(1);
- break;
- case 'd': // %d Day of the month, numeric (00..31)
- builder.appendDayOfMonth(2);
- break;
- case 'e': // %e Day of the month, numeric (0..31)
- builder.appendDayOfMonth(1);
- break;
- case 'H': // %H Hour (00..23)
- builder.appendHourOfDay(2);
- hasTimePart = true;
- break;
- case 'h': // %h Hour (01..12)
- case 'I': // %I Hour (01..12)
- builder.appendClockhourOfHalfday(2);
- hasTimePart = true;
- break;
- case 'i': // %i Minutes, numeric (00..59)
- builder.appendMinuteOfHour(2);
- hasTimePart = true;
- break;
- case 'j': // %j Day of year (001..366)
- builder.appendDayOfYear(3);
- break;
- case 'k': // %k Hour (0..23)
- builder.appendHourOfDay(1);
- hasTimePart = true;
- break;
- case 'l': // %l Hour (1..12)
- builder.appendClockhourOfHalfday(1);
- hasTimePart = true;
- break;
- case 'M': // %M Month name (January..December)
- builder.appendMonthOfYearText();
- break;
- case 'm': // %m Month, numeric (00..12)
- builder.appendMonthOfYear(2);
- break;
- case 'p': // %p AM or PM
- builder.appendHalfdayOfDayText();
- break;
- case 'r': // %r Time, 12-hour (hh:mm:ss followed by AM or
PM)
- builder.appendClockhourOfHalfday(2)
- .appendLiteral(':')
- .appendMinuteOfHour(2)
- .appendLiteral(':')
- .appendSecondOfMinute(2)
- .appendLiteral(' ')
- .appendHalfdayOfDayText();
- hasTimePart = true;
- break;
- case 'S': // %S Seconds (00..59)
- case 's': // %s Seconds (00..59)
- builder.appendSecondOfMinute(2);
- hasTimePart = true;
- break;
- case 'T': // %T Time, 24-hour (hh:mm:ss)
- builder.appendHourOfDay(2)
- .appendLiteral(':')
- .appendMinuteOfHour(2)
- .appendLiteral(':')
- .appendSecondOfMinute(2);
- hasTimePart = true;
- break;
- case 'v': // %v Week (01..53), where Monday is the first
day of the week; used with %x
- builder.appendWeekOfWeekyear(2);
- break;
- case 'x': // %x Year for the week, where Monday is the
first day of the week, numeric, four digits; used with %v
- builder.appendWeekyear(4, 4);
- break;
- case 'W': // %W Weekday name (Sunday..Saturday)
- builder.appendDayOfWeekText();
- break;
- case 'Y': // %Y Year, numeric, four digits
- builder.appendYear(4, 4);
- break;
- case 'y': // %y Year, numeric (two digits)
- builder.appendTwoDigitYear(2020);
- break;
- case 'f': // %f Microseconds (000000..999999)
- case 'w': // %w Day of the week (0=Sunday..6=Saturday)
- case 'U': // %U Week (00..53), where Sunday is the first
day of the week
- case 'u': // %u Week (00..53), where Monday is the first
day of the week
- case 'V': // %V Week (01..53), where Sunday is the first
day of the week; used with %X
- case 'X': // %X Year for the week where Sunday is the
first day of the week, numeric, four digits; used with %V
- case 'D': // %D Day of the month with English suffix (0th,
1st, 2nd, 3rd, …)
- throw new AnalysisException(String.format("%%%s not
supported in date format string", character));
- case '%': // %% A literal "%" character
- builder.appendLiteral('%');
- break;
- default: // %<x> The literal character represented by <x>
- builder.appendLiteral(character);
- break;
- }
- escaped = false;
- } else if (character == '%') {
- escaped = true;
- } else {
- builder.appendLiteral(character);
- }
- }
-
- Date retDate = new
Date(builder.toFormatter().withLocale(Locale.ENGLISH).parseMillis(date.getStringValue()));
- if (hasTimePart) {
- return new DateLiteral(DateFormatUtils.format(retDate, "yyyy-MM-dd
HH:mm:ss"), Type.DATETIME);
- } else {
- return new DateLiteral(DateFormatUtils.format(retDate,
"yyyy-MM-dd"), Type.DATE);
- }
+ return DateLiteral.dateParser(date.getStringValue(),
fmtLiteral.getStringValue());
}
@FEFunction(name = "date_sub", argTypes = { "DATETIME", "INT" },
returnType = "DATETIME")
public static DateLiteral dateSub(LiteralExpr date, LiteralExpr day)
throws AnalysisException {
- Date d = new Date(getTime(date));
- d = DateUtils.addDays(d, -(int) day.getLongValue());
- return new DateLiteral(DateFormatUtils.format(d, "yyyy-MM-dd
HH:mm:ss"), Type.DATETIME);
+ return dateAdd(date, new IntLiteral(-(int) day.getLongValue()));
}
@FEFunction(name = "year", argTypes = { "DATETIME" }, returnType = "INT")
public static IntLiteral year(LiteralExpr arg) throws AnalysisException {
- long timestamp = getTime(arg);
- Calendar instance = Calendar.getInstance();
- instance.setTimeInMillis(timestamp);
- return new IntLiteral(instance.get(Calendar.YEAR), Type.INT);
+ return new IntLiteral(((DateLiteral) arg).getYear(), Type.INT);
}
@FEFunction(name = "month", argTypes = { "DATETIME" }, returnType = "INT")
public static IntLiteral month(LiteralExpr arg) throws AnalysisException {
- long timestamp = getTime(arg);
- Calendar instance = Calendar.getInstance();
- instance.setTimeInMillis(timestamp);
- return new IntLiteral(instance.get(Calendar.MONTH) + 1, Type.INT);
+ return new IntLiteral(((DateLiteral) arg).getMonth(), Type.INT);
}
@FEFunction(name = "day", argTypes = { "DATETIME" }, returnType = "INT")
public static IntLiteral day(LiteralExpr arg) throws AnalysisException {
- long timestamp = getTime(arg);
- Calendar instance = Calendar.getInstance();
- instance.setTimeInMillis(timestamp);
- return new IntLiteral(instance.get(Calendar.DAY_OF_MONTH), Type.INT);
+ return new IntLiteral(((DateLiteral) arg).getDay(), Type.INT);
}
@FEFunction(name = "unix_timestamp", argTypes = { "DATETIME" }, returnType
= "INT")
public static IntLiteral unix_timestamp(LiteralExpr arg) throws
AnalysisException {
- long timestamp = getTime(arg);
- return new IntLiteral(timestamp / 1000, Type.INT);
+ try {
+ return new IntLiteral(((DateLiteral)
arg).unixTime(TimeUtils.getTimeZone()) / 1000, Type.INT);
+ } catch (ParseException e) {
+ throw new AnalysisException(e.getLocalizedMessage());
+ }
}
@FEFunction(name = "from_unixtime", argTypes = { "INT" }, returnType =
"VARCHAR")
public static StringLiteral fromUnixTime(LiteralExpr unixTime) throws
AnalysisException {
- long ts = unixTime.getLongValue();
- // if unixTime < 0 or larger than 9999-12-31 23:59:59, we should
return null, throw a exception and let BE process
- if (ts < 0 || ts > 253402271999L) {
+ //if unixTime < 0, we should return null, throw a exception and let BE
process
+ if (unixTime.getLongValue() < 0) {
throw new AnalysisException("unixtime should larger than zero");
}
- Date date = new Date(unixTime.getLongValue() * 1000);
- return new StringLiteral(dateFormat(date, "%Y-%m-%d %H:%i:%S"));
+ SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd
HH:mm:ss");
Review comment:
I think we can create a constructor of DateLiteral with unix timestamp and
timezone.
Then this logic can be included in DateLiteral
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
[email protected]
With regards,
Apache Git Services
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]