You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@doris.apache.org by zh...@apache.org on 2019/11/08 10:57:28 UTC
[incubator-doris] branch master updated: Support date_add function
to support partition prune (#2154)
This is an automated email from the ASF dual-hosted git repository.
zhaoc pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-doris.git
The following commit(s) were added to refs/heads/master by this push:
new 48d9318 Support date_add function to support partition prune (#2154)
48d9318 is described below
commit 48d9318d07488895261305bdb512985134d7db75
Author: HangyuanLiu <46...@qq.com>
AuthorDate: Fri Nov 8 18:57:21 2019 +0800
Support date_add function to support partition prune (#2154)
Currently in the date_add/date_sub functions (DATE_ADD(DATETIME date,INTERVAL expr type)), the expr parameter is the interval you want to add.
Doris will convert these functions to xxx_sub/xxx_add. However, there is only the days_add function in fe, which causes other date_add formats, such as select date_add('2010-11-30 23:59:59', INTERVAL 2 DAY), cannot be pruned.
So I've added other functions to support fe partition prune
---
.../org/apache/doris/analysis/DateLiteral.java | 49 +++++++++++++---
.../apache/doris/analysis/ExpressionFunctions.java | 3 +-
.../java/org/apache/doris/rewrite/FEFunctions.java | 68 ++++++++++++++++++++--
.../org/apache/doris/rewrite/FEFunctionsTest.java | 41 +++++++++++++
4 files changed, 147 insertions(+), 14 deletions(-)
diff --git a/fe/src/main/java/org/apache/doris/analysis/DateLiteral.java b/fe/src/main/java/org/apache/doris/analysis/DateLiteral.java
index 8bbedfe..7042ad8 100644
--- a/fe/src/main/java/org/apache/doris/analysis/DateLiteral.java
+++ b/fe/src/main/java/org/apache/doris/analysis/DateLiteral.java
@@ -161,6 +161,16 @@ public class DateLiteral extends LiteralExpr {
this.type = Type.DATETIME;
}
+ public DateLiteral(LocalDateTime dateTime, Type type) {
+ this.year = dateTime.getYear();
+ this.month = dateTime.getMonthOfYear();
+ this.day = dateTime.getDayOfMonth();
+ this.hour = dateTime.getHourOfDay();
+ this.minute = dateTime.getMinuteOfHour();
+ this.second = dateTime.getSecondOfMinute();
+ this.type = type;
+ }
+
public DateLiteral(DateLiteral other) {
super(other);
hour = other.hour;
@@ -542,17 +552,38 @@ public class DateLiteral extends LiteralExpr {
return builder;
}
- public DateLiteral plusDays(int day) throws AnalysisException {
- LocalDateTime dateTime;
+ public LocalDateTime getTimeFormatter() throws AnalysisException {
if (type == Type.DATE) {
- dateTime = DATE_FORMATTER.parseLocalDateTime(getStringValue()).plusDays(day);
+ return DATE_FORMATTER.parseLocalDateTime(getStringValue());
+ } else if (type == Type.DATETIME) {
+ return DATE_TIME_FORMATTER.parseLocalDateTime(getStringValue());
} else {
- dateTime = DATE_TIME_FORMATTER.parseLocalDateTime(getStringValue()).plusDays(day);
- }
- DateLiteral dateLiteral = new DateLiteral(dateTime.getYear(), dateTime.getMonthOfYear(), dateTime.getDayOfMonth(),
- dateTime.getHourOfDay(), dateTime.getMinuteOfHour(), dateTime.getSecondOfMinute());
- dateLiteral.setType(type);
- return dateLiteral;
+ throw new AnalysisException("Not support date literal type");
+ }
+ }
+
+ public DateLiteral plusYears(int year) throws AnalysisException {
+ return new DateLiteral(getTimeFormatter().plusYears(year), type);
+ }
+
+ public DateLiteral plusMonths(int month) throws AnalysisException {
+ return new DateLiteral(getTimeFormatter().plusMonths(month), type);
+ }
+
+ public DateLiteral plusDays(int day) throws AnalysisException {
+ return new DateLiteral(getTimeFormatter().plusDays(day), type);
+ }
+
+ public DateLiteral plusHours(int hour) throws AnalysisException {
+ return new DateLiteral(getTimeFormatter().plusHours(hour), type);
+ }
+
+ public DateLiteral plusMinutes(int minute) throws AnalysisException {
+ return new DateLiteral(getTimeFormatter().plusMinutes(minute), type);
+ }
+
+ public DateLiteral plusSeconds(int second) throws AnalysisException {
+ return new DateLiteral(getTimeFormatter().plusSeconds(second), type);
}
public long getYear() {
diff --git a/fe/src/main/java/org/apache/doris/analysis/ExpressionFunctions.java b/fe/src/main/java/org/apache/doris/analysis/ExpressionFunctions.java
index 2ceb86f..e81e75b 100644
--- a/fe/src/main/java/org/apache/doris/analysis/ExpressionFunctions.java
+++ b/fe/src/main/java/org/apache/doris/analysis/ExpressionFunctions.java
@@ -66,7 +66,8 @@ public enum ExpressionFunctions {
}
if (constExpr instanceof ArithmeticExpr
- || constExpr instanceof FunctionCallExpr) {
+ || constExpr instanceof FunctionCallExpr
+ || constExpr instanceof TimestampArithmeticExpr) {
Function fn = constExpr.getFn();
Preconditions.checkNotNull(fn, "Expr's fn can't be null.");
diff --git a/fe/src/main/java/org/apache/doris/rewrite/FEFunctions.java b/fe/src/main/java/org/apache/doris/rewrite/FEFunctions.java
index a8b7c57..6786f72 100644
--- a/fe/src/main/java/org/apache/doris/rewrite/FEFunctions.java
+++ b/fe/src/main/java/org/apache/doris/rewrite/FEFunctions.java
@@ -66,18 +66,48 @@ public class FEFunctions {
@FEFunction(name = "date_add", argTypes = { "DATETIME", "INT" }, returnType = "DATETIME")
public static DateLiteral dateAdd(LiteralExpr date, LiteralExpr day) throws AnalysisException {
- DateLiteral dateLiteral = (DateLiteral) date;
- return dateLiteral.plusDays((int) day.getLongValue());
+ return daysAdd(date, day);
}
@FEFunction(name = "adddate", argTypes = { "DATETIME", "INT" }, returnType = "DATETIME")
public static DateLiteral addDate(LiteralExpr date, LiteralExpr day) throws AnalysisException {
- return dateAdd(date, day);
+ return daysAdd(date, day);
+ }
+
+ @FEFunction(name = "years_add", argTypes = { "DATETIME", "INT" }, returnType = "DATETIME")
+ public static DateLiteral yearsAdd(LiteralExpr date, LiteralExpr year) throws AnalysisException {
+ DateLiteral dateLiteral = (DateLiteral) date;
+ return dateLiteral.plusYears((int) year.getLongValue());
+ }
+
+ @FEFunction(name = "months_add", argTypes = { "DATETIME", "INT" }, returnType = "DATETIME")
+ public static DateLiteral monthsAdd(LiteralExpr date, LiteralExpr month) throws AnalysisException {
+ DateLiteral dateLiteral = (DateLiteral) date;
+ return dateLiteral.plusMonths((int) month.getLongValue());
}
@FEFunction(name = "days_add", argTypes = { "DATETIME", "INT" }, returnType = "DATETIME")
public static DateLiteral daysAdd(LiteralExpr date, LiteralExpr day) throws AnalysisException {
- return dateAdd(date, day);
+ DateLiteral dateLiteral = (DateLiteral) date;
+ return dateLiteral.plusDays((int) day.getLongValue());
+ }
+
+ @FEFunction(name = "hours_add", argTypes = { "DATETIME", "INT" }, returnType = "DATETIME")
+ public static DateLiteral hoursAdd(LiteralExpr date, LiteralExpr hour) throws AnalysisException {
+ DateLiteral dateLiteral = (DateLiteral) date;
+ return dateLiteral.plusHours((int) hour.getLongValue());
+ }
+
+ @FEFunction(name = "minutes_add", argTypes = { "DATETIME", "INT" }, returnType = "DATETIME")
+ public static DateLiteral minutesAdd(LiteralExpr date, LiteralExpr minute) throws AnalysisException {
+ DateLiteral dateLiteral = (DateLiteral) date;
+ return dateLiteral.plusMinutes((int) minute.getLongValue());
+ }
+
+ @FEFunction(name = "seconds_add", argTypes = { "DATETIME", "INT" }, returnType = "DATETIME")
+ public static DateLiteral secondsAdd(LiteralExpr date, LiteralExpr second) throws AnalysisException {
+ DateLiteral dateLiteral = (DateLiteral) date;
+ return dateLiteral.plusSeconds((int) second.getLongValue());
}
@FEFunction(name = "date_format", argTypes = { "DATETIME", "VARCHAR" }, returnType = "VARCHAR")
@@ -96,6 +126,36 @@ public class FEFunctions {
return dateAdd(date, new IntLiteral(-(int) day.getLongValue()));
}
+ @FEFunction(name = "years_sub", argTypes = { "DATETIME", "INT" }, returnType = "DATETIME")
+ public static DateLiteral yearsSub(LiteralExpr date, LiteralExpr year) throws AnalysisException {
+ return yearsAdd(date, new IntLiteral(-(int) year.getLongValue()));
+ }
+
+ @FEFunction(name = "months_sub", argTypes = { "DATETIME", "INT" }, returnType = "DATETIME")
+ public static DateLiteral monthsSub(LiteralExpr date, LiteralExpr month) throws AnalysisException {
+ return monthsAdd(date, new IntLiteral(-(int) month.getLongValue()));
+ }
+
+ @FEFunction(name = "days_sub", argTypes = { "DATETIME", "INT" }, returnType = "DATETIME")
+ public static DateLiteral daysSub(LiteralExpr date, LiteralExpr day) throws AnalysisException {
+ return daysAdd(date, new IntLiteral(-(int) day.getLongValue()));
+ }
+
+ @FEFunction(name = "hours_sub", argTypes = { "DATETIME", "INT" }, returnType = "DATETIME")
+ public static DateLiteral hoursSub(LiteralExpr date, LiteralExpr hour) throws AnalysisException {
+ return hoursAdd(date, new IntLiteral(-(int) hour.getLongValue()));
+ }
+
+ @FEFunction(name = "minutes_sub", argTypes = { "DATETIME", "INT" }, returnType = "DATETIME")
+ public static DateLiteral minutesSub(LiteralExpr date, LiteralExpr minute) throws AnalysisException {
+ return minutesAdd(date, new IntLiteral(-(int) minute.getLongValue()));
+ }
+
+ @FEFunction(name = "seconds_sub", argTypes = { "DATETIME", "INT" }, returnType = "DATETIME")
+ public static DateLiteral secondsSub(LiteralExpr date, LiteralExpr second) throws AnalysisException {
+ return secondsAdd(date, new IntLiteral(-(int) second.getLongValue()));
+ }
+
@FEFunction(name = "year", argTypes = { "DATETIME" }, returnType = "INT")
public static IntLiteral year(LiteralExpr arg) throws AnalysisException {
return new IntLiteral(((DateLiteral) arg).getYear(), Type.INT);
diff --git a/fe/src/test/java/org/apache/doris/rewrite/FEFunctionsTest.java b/fe/src/test/java/org/apache/doris/rewrite/FEFunctionsTest.java
index b54a9f0..276952d 100644
--- a/fe/src/test/java/org/apache/doris/rewrite/FEFunctionsTest.java
+++ b/fe/src/test/java/org/apache/doris/rewrite/FEFunctionsTest.java
@@ -518,4 +518,45 @@ public class FEFunctionsTest {
Assert.assertEquals(31559414743L, FEFunctions.timeDiff(d3, d1).getLongValue());
Assert.assertEquals(2419200, FEFunctions.timeDiff(d3, d2).getLongValue());
}
+
+ @Test
+ public void datePlusAndSubTest() throws AnalysisException {
+ DateLiteral dateLiteral = new DateLiteral("2019-11-11 00:00:00", Type.DATETIME);
+
+ Assert.assertEquals(new DateLiteral("2020-11-11 00:00:00", Type.DATETIME),
+ FEFunctions.yearsAdd(dateLiteral, new IntLiteral(1)));
+
+ Assert.assertEquals(new DateLiteral("2018-11-11 00:00:00", Type.DATETIME),
+ FEFunctions.yearsSub(dateLiteral, new IntLiteral(1)));
+
+ Assert.assertEquals(new DateLiteral("2019-12-11 00:00:00", Type.DATETIME),
+ FEFunctions.monthsAdd(dateLiteral, new IntLiteral(1)));
+
+ Assert.assertEquals(new DateLiteral("2019-10-11 00:00:00", Type.DATETIME),
+ FEFunctions.monthsSub(dateLiteral, new IntLiteral(1)));
+
+ Assert.assertEquals(new DateLiteral("2019-11-12 00:00:00", Type.DATETIME),
+ FEFunctions.daysAdd(dateLiteral, new IntLiteral(1)));
+
+ Assert.assertEquals(new DateLiteral("2019-11-10 00:00:00", Type.DATETIME),
+ FEFunctions.daysSub(dateLiteral, new IntLiteral(1)));
+
+ Assert.assertEquals(new DateLiteral("2019-11-11 01:00:00", Type.DATETIME),
+ FEFunctions.hoursAdd(dateLiteral, new IntLiteral(1)));
+
+ Assert.assertEquals(new DateLiteral("2019-11-10 23:00:00", Type.DATETIME),
+ FEFunctions.hoursSub(dateLiteral, new IntLiteral(1)));
+
+ Assert.assertEquals(new DateLiteral("2019-11-11 00:01:00", Type.DATETIME),
+ FEFunctions.minutesAdd(dateLiteral, new IntLiteral(1)));
+
+ Assert.assertEquals(new DateLiteral("2019-11-10 23:59:00", Type.DATETIME),
+ FEFunctions.minutesSub(dateLiteral, new IntLiteral(1)));
+
+ Assert.assertEquals(new DateLiteral("2019-11-11 00:00:01", Type.DATETIME),
+ FEFunctions.secondsAdd(dateLiteral, new IntLiteral(1)));
+
+ Assert.assertEquals(new DateLiteral("2019-11-10 23:59:59", Type.DATETIME),
+ FEFunctions.secondsSub(dateLiteral, new IntLiteral(1)));
+ }
}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For additional commands, e-mail: commits-help@doris.apache.org