This is an automated email from the ASF dual-hosted git repository. jakevin pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/master by this push: new 66eeafcd484 [refactor](Nereids): unify one DateLiteral init() (#27618) 66eeafcd484 is described below commit 66eeafcd484570c1cc80e64d45a435214969dca7 Author: jakevin <jakevin...@gmail.com> AuthorDate: Mon Nov 27 17:09:45 2023 +0800 [refactor](Nereids): unify one DateLiteral init() (#27618) `fromDateStr` will parse `date string` into `dateLiteral`, but `init()` already handle it, so we can use `init()` replace it. --- .../org/apache/doris/analysis/DateLiteral.java | 179 +++++---------------- .../doris/rewrite/RewriteDateLiteralRule.java | 3 +- 2 files changed, 39 insertions(+), 143 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 6253f91fb3c..879795f8737 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 @@ -64,6 +64,7 @@ import java.util.Set; import java.util.TimeZone; import java.util.regex.Pattern; import java.util.stream.Collectors; +import javax.annotation.Nullable; public class DateLiteral extends LiteralExpr { private static final Logger LOG = LogManager.getLogger(DateLiteral.class); @@ -107,9 +108,6 @@ public class DateLiteral extends LiteralExpr { private static Map<String, Integer> WEEK_DAY_NAME_DICT = Maps.newHashMap(); private static Set<Character> 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 int ALLOW_SPACE_MASK = 4 | 64; - private static final int MAX_DATE_PARTS = 8; - private static final int YY_PART_YEAR = 70; static { try { @@ -245,6 +243,12 @@ public class DateLiteral extends LiteralExpr { analysisDone(); } + public DateLiteral(String s) throws AnalysisException { + super(); + init(s, null); + analysisDone(); + } + public DateLiteral(long unixTimestamp, TimeZone timeZone, Type type) throws AnalysisException { Timestamp timestamp = new Timestamp(unixTimestamp); @@ -368,9 +372,11 @@ public class DateLiteral extends LiteralExpr { return new DateLiteral(type, false); } - private void init(String s, Type type) throws AnalysisException { + private void init(String s, @Nullable Type type) throws AnalysisException { try { - Preconditions.checkArgument(type.isDateType()); + if (type != null) { + Preconditions.checkArgument(type.isDateType()); + } TemporalAccessor dateTime = null; boolean parsed = false; int offset = 0; @@ -442,10 +448,11 @@ public class DateLiteral extends LiteralExpr { builder.appendLiteral(" "); } String[] timePart = s.contains(" ") ? s.split(" ")[1].split(":") : new String[] {}; - if (timePart.length > 0 && (type.equals(Type.DATE) || type.equals(Type.DATEV2))) { + if (timePart.length > 0 && type != null && (type.equals(Type.DATE) || type.equals(Type.DATEV2))) { throw new AnalysisException("Invalid date value: " + s); } - if (timePart.length == 0 && (type.equals(Type.DATETIME) || type.equals(Type.DATETIMEV2))) { + if (timePart.length == 0 && type != null && (type.equals(Type.DATETIME) || type.equals( + Type.DATETIMEV2))) { throw new AnalysisException("Invalid datetime value: " + s); } for (int i = 0; i < timePart.length; i++) { @@ -485,10 +492,30 @@ public class DateLiteral extends LiteralExpr { minute = getOrDefault(dateTime, ChronoField.MINUTE_OF_HOUR, 0); second = getOrDefault(dateTime, ChronoField.SECOND_OF_MINUTE, 0); microsecond = getOrDefault(dateTime, ChronoField.MICRO_OF_SECOND, 0); - if (microsecond != 0 && type.isDatetime()) { - int dotIndex = s.lastIndexOf("."); - int scale = s.length() - dotIndex - 1; - type = ScalarType.createDatetimeV2Type(scale); + + if (type != null) { + if (microsecond != 0 && type.isDatetime()) { + int dotIndex = s.lastIndexOf("."); + int scale = s.length() - dotIndex - 1; + type = ScalarType.createDatetimeV2Type(scale); + } + } else { + if (hour == 0 && minute == 0 && second == 0 && microsecond == 0) { + type = ScalarType.getDefaultDateType(Type.DATE); + } else { + type = ScalarType.getDefaultDateType(Type.DATETIME); + if (type.isDatetimeV2() && microsecond != 0) { + int scale = 6; + for (int i = 0; i < 6; i++) { + if (microsecond % Math.pow(10.0, i + 1) > 0) { + break; + } else { + scale -= 1; + } + } + type = ScalarType.createDatetimeV2Type(scale); + } + } } this.type = type; @@ -1677,136 +1704,6 @@ public class DateLiteral extends LiteralExpr { throw new InvalidFormatException("'" + value + "' is invalid"); } - // The interval format is that with no delimiters - // YYYY-MM-DD HH-MM-DD.FFFFFF AM in default format, and now doris will skip part 7 - // 0 1 2 3 4 5 6 7 - public void fromDateStr(String dateStr) throws AnalysisException { - dateStr = dateStr.trim(); - if (dateStr.isEmpty()) { - throw new AnalysisException("parse datetime value failed: " + dateStr); - } - int[] dateVal = new int[MAX_DATE_PARTS]; - int[] dateLen = new int[MAX_DATE_PARTS]; - - // Fix year length - int pre = 0; - int pos = 0; - while (pos < dateStr.length() && (Character.isDigit(dateStr.charAt(pos)) || dateStr.charAt(pos) == 'T')) { - pos++; - } - int yearLen = 4; - int digits = pos - pre; - boolean isIntervalFormat = false; - // For YYYYMMDD/YYYYMMDDHHMMSS is 4 digits years - if (pos == dateStr.length() || dateStr.charAt(pos) == '.') { - if (digits == 4 || digits == 8 || digits >= 14) { - yearLen = 4; - } else { - yearLen = 2; - } - isIntervalFormat = true; - } - - int fieldIdx = 0; - int fieldLen = yearLen; - while (pre < dateStr.length() && Character.isDigit(dateStr.charAt(pre)) && fieldIdx < MAX_DATE_PARTS - 1) { - int start = pre; - int tempVal = 0; - boolean scanToDelim = (!isIntervalFormat) && (fieldIdx != 6); - while (pre < dateStr.length() && Character.isDigit(dateStr.charAt(pre)) - && (scanToDelim || fieldLen-- != 0)) { - tempVal = tempVal * 10 + (dateStr.charAt(pre++) - '0'); - } - dateVal[fieldIdx] = tempVal; - dateLen[fieldIdx] = pre - start; - fieldLen = 2; - - if (pre == dateStr.length()) { - fieldIdx++; - break; - } - - if (fieldIdx == 2 && dateStr.charAt(pre) == 'T') { - // YYYYMMDDTHHMMDD, skip 'T' and continue - pre++; - fieldIdx++; - continue; - } - - // Second part - if (fieldIdx == 5) { - if (dateStr.charAt(pre) == '.') { - pre++; - fieldLen = 6; - } else if (Character.isDigit(dateStr.charAt(pre))) { - fieldIdx++; - break; - } - fieldIdx++; - continue; - } - // escape separator - while (pre < dateStr.length() && ((Character.toString(dateStr.charAt(pre)).matches("\\p{Punct}")) - || Character.isSpaceChar(dateStr.charAt(pre)))) { - if (Character.isSpaceChar(dateStr.charAt(pre))) { - if (((1 << fieldIdx) & ALLOW_SPACE_MASK) == 0) { - throw new AnalysisException("parse datetime value failed: " + dateStr); - } - } - pre++; - } - fieldIdx++; - } - int numField = fieldIdx; - if (!isIntervalFormat) { - yearLen = dateLen[0]; - } - for (; fieldIdx < MAX_DATE_PARTS; ++fieldIdx) { - dateLen[fieldIdx] = 0; - dateVal[fieldIdx] = 0; - } - if (yearLen == 2) { - if (dateVal[0] < YY_PART_YEAR) { - dateVal[0] += 2000; - } else { - dateVal[0] += 1900; - } - } - - if (numField < 3) { - throw new AnalysisException("parse datetime value failed: " + dateStr); - } - - year = dateVal[0]; - month = dateVal[1]; - day = dateVal[2]; - hour = dateVal[3]; - minute = dateVal[4]; - second = dateVal[5]; - microsecond = dateVal[6]; - - if (numField == 3) { - type = ScalarType.getDefaultDateType(Type.DATE); - } else { - type = ScalarType.getDefaultDateType(Type.DATETIME); - if (type.isDatetimeV2() && microsecond != 0) { - int scale = 6; - for (int i = 0; i < 6; i++) { - if (microsecond % Math.pow(10.0, i + 1) > 0) { - break; - } else { - scale -= 1; - } - } - type = ScalarType.createDatetimeV2Type(scale); - } - } - - if (checkRange() || checkDate()) { - throw new AnalysisException("Datetime value is out of range: " + dateStr); - } - } - public void setMinValue() { year = 0; month = 1; diff --git a/fe/fe-core/src/main/java/org/apache/doris/rewrite/RewriteDateLiteralRule.java b/fe/fe-core/src/main/java/org/apache/doris/rewrite/RewriteDateLiteralRule.java index a11999a0777..eeb65261f6e 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/rewrite/RewriteDateLiteralRule.java +++ b/fe/fe-core/src/main/java/org/apache/doris/rewrite/RewriteDateLiteralRule.java @@ -62,8 +62,7 @@ public class RewriteDateLiteralRule implements ExprRewriteRule { if (childExpr instanceof LiteralExpr) { try { String dateStr = childExpr.getStringValue(); - DateLiteral dateLiteral = new DateLiteral(); - dateLiteral.fromDateStr(dateStr); + DateLiteral dateLiteral = new DateLiteral(dateStr); expr.setChild(1, dateLiteral); } catch (AnalysisException e) { if (ConnectContext.get() != null) { --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org For additional commands, e-mail: commits-h...@doris.apache.org