From ffe3eaa1a77f56f2bfb3cb44977fd9cd3d9eccb8 Mon Sep 17 00:00:00 2001 From: kangkaisen Date: Mon, 13 May 2019 16:59:52 +0800 Subject: [PATCH] Implement adddate, days_add and from_unixtime function in FE (#1149) --- .../org/apache/doris/rewrite/FEFunctions.java | 31 +++++++++++++++ .../apache/doris/rewrite/FEFunctionsTest.java | 38 +++++++++++++++++++ 2 files changed, 69 insertions(+) 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 32b879ffe6..6b572cc8df 100644 --- a/fe/src/main/java/org/apache/doris/rewrite/FEFunctions.java +++ b/fe/src/main/java/org/apache/doris/rewrite/FEFunctions.java @@ -67,6 +67,16 @@ public class FEFunctions { return new DateLiteral(DateFormatUtils.format(d, "yyyy-MM-dd HH:mm:ss"), Type.DATETIME); } + @FEFunction(name = "adddate", argTypes = { "DATETIME", "INT" }, returnType = "DATETIME") + public static DateLiteral addDate(LiteralExpr date, LiteralExpr day) throws AnalysisException { + return dateAdd(date, day); + } + + @FEFunction(name = "days_add", argTypes = { "DATETIME", "INT" }, returnType = "DATETIME") + public static DateLiteral daysAdd(LiteralExpr date, LiteralExpr day) throws AnalysisException { + return dateAdd(date, day); + } + @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()); @@ -239,6 +249,27 @@ public class FEFunctions { return new IntLiteral(timestamp / 1000, Type.INT); } + @FEFunction(name = "from_unixtime", argTypes = { "INT" }, returnType = "VARCHAR") + public static StringLiteral fromUnixTime(LiteralExpr unixTime) throws AnalysisException { + //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")); + } + + @FEFunction(name = "from_unixtime", argTypes = { "INT", "VARCHAR" }, returnType = "VARCHAR") + public static StringLiteral fromUnixTime(LiteralExpr unixTime, StringLiteral fmtLiteral) throws AnalysisException { + //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); + //currently, doris BE only support "yyyy-MM-dd HH:mm:ss" and "yyyy-MM-dd" format + return new StringLiteral(DateFormatUtils.format(date, fmtLiteral.getStringValue())); + } + private static long getTime(LiteralExpr expr) throws AnalysisException { try { String[] parsePatterns = { "yyyyMMdd", "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss" }; 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 fc645af190..c2602077bd 100644 --- a/fe/src/test/java/org/apache/doris/rewrite/FEFunctionsTest.java +++ b/fe/src/test/java/org/apache/doris/rewrite/FEFunctionsTest.java @@ -24,7 +24,9 @@ import org.apache.doris.catalog.Type; import org.apache.doris.common.AnalysisException; import org.junit.Assert; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.ExpectedException; import java.util.TimeZone; @@ -37,6 +39,9 @@ import static org.junit.Assert.fail; public class FEFunctionsTest { + @Rule + public ExpectedException expectedEx = ExpectedException.none(); + @Test public void unixtimestampTest() { try { @@ -47,6 +52,39 @@ public class FEFunctionsTest { } } + @Test + public void dateAddTest() throws AnalysisException { + DateLiteral actualResult = FEFunctions.dateAdd(new StringLiteral("2018-08-08"), new IntLiteral(1)); + DateLiteral expectedResult = new DateLiteral("2018-08-09", Type.DATE); + Assert.assertEquals(expectedResult, actualResult); + + actualResult = FEFunctions.dateAdd(new StringLiteral("2018-08-08"), new IntLiteral(-1)); + expectedResult = new DateLiteral("2018-08-07", Type.DATE); + Assert.assertEquals(expectedResult, actualResult); + } + + @Test + public void fromUnixTimeTest() throws AnalysisException { + StringLiteral actualResult = FEFunctions.fromUnixTime(new IntLiteral(100000)); + StringLiteral expectedResult = new StringLiteral("1970-01-02 11:46:40"); + Assert.assertEquals(expectedResult, actualResult); + + actualResult = FEFunctions.fromUnixTime(new IntLiteral(100000), new StringLiteral("yyyy-MM-dd")); + expectedResult = new StringLiteral("1970-01-02"); + Assert.assertEquals(expectedResult, actualResult); + + actualResult = FEFunctions.fromUnixTime(new IntLiteral(0)); + expectedResult = new StringLiteral("1970-01-01 08:00:00"); + Assert.assertEquals(expectedResult, actualResult); + } + + @Test + public void fromUnixTimeTestException() throws AnalysisException { + expectedEx.expect(AnalysisException.class); + expectedEx.expectMessage("unixtime should larger than zero"); + FEFunctions.fromUnixTime(new IntLiteral(-100)); + } + @Test public void dateFormatUtilTest() { try {