DRILL-967: Age and shift functions.
Project: http://git-wip-us.apache.org/repos/asf/incubator-drill/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-drill/commit/d5dbe2c7 Tree: http://git-wip-us.apache.org/repos/asf/incubator-drill/tree/d5dbe2c7 Diff: http://git-wip-us.apache.org/repos/asf/incubator-drill/diff/d5dbe2c7 Branch: refs/heads/master Commit: d5dbe2c7ccc0f4376edc447385ee75bc714d50a5 Parents: 1e42087 Author: Sudheesh Katkam <[email protected]> Authored: Thu May 29 11:30:24 2014 -0700 Committer: Aditya Kishore <[email protected]> Committed: Wed Jul 2 23:09:37 2014 -0700 ---------------------------------------------------------------------- .../src/main/codegen/data/MathFunc.tdd | 24 +++++- .../exec/expr/fn/impl/DateTypeFunctions.java | 86 +++++++++++++++++++- .../drill/exec/fn/impl/TestDateFunctions.java | 9 ++ .../src/test/resources/functions/date/age.json | 36 ++++++++ 4 files changed, 153 insertions(+), 2 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/d5dbe2c7/exec/java-exec/src/main/codegen/data/MathFunc.tdd ---------------------------------------------------------------------- diff --git a/exec/java-exec/src/main/codegen/data/MathFunc.tdd b/exec/java-exec/src/main/codegen/data/MathFunc.tdd index 2720e82..b5b5543 100644 --- a/exec/java-exec/src/main/codegen/data/MathFunc.tdd +++ b/exec/java-exec/src/main/codegen/data/MathFunc.tdd @@ -133,7 +133,29 @@ unaryMathFunctions : [ {input: "UInt1", outputType: "UInt1", castType: "byte"}, {input: "UInt2", outputType: "UInt2", castType: "char"}, {input: "UInt4", outputType: "UInt4", castType: "int"}, - {input: "UInt8", outputType: "UInt8", castType: "long"} + {input: "UInt8", outputType: "UInt8", castType: "long"} + ] + }, + {className: "LeftShift", funcName: "lshift", javaFunc: " << ", types: [ + {input: "Int", outputType: "Int", castType: "int"}, + {input: "BigInt", outputType: "BigInt", castType: "long"}, + {input: "SmallInt", outputType: "SmallInt", castType: "short"}, + {input: "TinyInt", outputType: "TinyInt", castType: "byte"}, + {input: "UInt1", outputType: "UInt1", castType: "byte"}, + {input: "UInt2", outputType: "UInt2", castType: "char"}, + {input: "UInt4", outputType: "UInt4", castType: "int"}, + {input: "UInt8", outputType: "UInt8", castType: "long"} + ] + }, + {className: "RightShift", funcName: "rshift", javaFunc: " >> ", types: [ + {input: "Int", outputType: "Int", castType: "int"}, + {input: "BigInt", outputType: "BigInt", castType: "long"}, + {input: "SmallInt", outputType: "SmallInt", castType: "short"}, + {input: "TinyInt", outputType: "TinyInt", castType: "byte"}, + {input: "UInt1", outputType: "UInt1", castType: "byte"}, + {input: "UInt2", outputType: "UInt2", castType: "char"}, + {input: "UInt4", outputType: "UInt4", castType: "int"}, + {input: "UInt8", outputType: "UInt8", castType: "long"} ] } ], http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/d5dbe2c7/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/DateTypeFunctions.java ---------------------------------------------------------------------- diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/DateTypeFunctions.java b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/DateTypeFunctions.java index 821db11..2349ddf 100644 --- a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/DateTypeFunctions.java +++ b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/DateTypeFunctions.java @@ -227,7 +227,7 @@ public class DateTypeFunctions { } - @FunctionTemplate(names = {"current_timestamp", "now"}, scope = FunctionTemplate.FunctionScope.SIMPLE, nulls = NullHandling.NULL_IF_NULL) + @FunctionTemplate(names = {"current_timestamp", "now", "statement_timestamp", "transaction_timestamp"}, scope = FunctionTemplate.FunctionScope.SIMPLE, nulls = NullHandling.NULL_IF_NULL) public static class CurrentTimeStamp implements DrillSimpleFunc { @Workspace long queryStartDate; @Workspace int timezoneIndex; @@ -372,4 +372,88 @@ public class DateTypeFunctions { } } } + + @SuppressWarnings("unused") + @FunctionTemplate(name = "age", scope = FunctionTemplate.FunctionScope.SIMPLE, nulls = NullHandling.NULL_IF_NULL) + public static class AgeTimeStampFunction implements DrillSimpleFunc { + @Param TimeStampHolder left; + @Param TimeStampHolder right; + @Output IntervalHolder out; + + public void setup(RecordBatch incoming) { + } + + public void eval() { + long diff = left.value - right.value; + long days = diff / org.apache.drill.exec.expr.fn.impl.DateUtility.daysToStandardMillis; + out.months = (int) (days / org.apache.drill.exec.expr.fn.impl.DateUtility.monthToStandardDays); + out.days = (int) (days % org.apache.drill.exec.expr.fn.impl.DateUtility.monthToStandardDays); + out.milliSeconds = (int) (diff % org.apache.drill.exec.expr.fn.impl.DateUtility.daysToStandardMillis); + } + } + + @SuppressWarnings("unused") + @FunctionTemplate(name = "age", scope = FunctionTemplate.FunctionScope.SIMPLE, nulls = NullHandling.NULL_IF_NULL) + public static class AgeTimeStamp2Function implements DrillSimpleFunc { + @Param TimeStampHolder right; + @Workspace long queryStartDate; + @Output IntervalHolder out; + + public void setup(RecordBatch incoming) { + int timeZoneIndex = incoming.getContext().getRootFragmentTimeZone(); + org.joda.time.DateTimeZone timeZone = org.joda.time.DateTimeZone.forID(org.apache.drill.exec.expr.fn.impl.DateUtility.getTimeZone(timeZoneIndex)); + org.joda.time.DateTime now = new org.joda.time.DateTime(incoming.getContext().getQueryStartTime(), timeZone); + queryStartDate = (new org.joda.time.DateMidnight(now.getYear(), now.getMonthOfYear(), now.getDayOfMonth(), timeZone)).getMillis(); + } + + public void eval() { + long diff = queryStartDate - right.value; + long days = diff / org.apache.drill.exec.expr.fn.impl.DateUtility.daysToStandardMillis; + out.months = (int) (days / org.apache.drill.exec.expr.fn.impl.DateUtility.monthToStandardDays); + out.days = (int) (days % org.apache.drill.exec.expr.fn.impl.DateUtility.monthToStandardDays); + out.milliSeconds = (int) (diff % org.apache.drill.exec.expr.fn.impl.DateUtility.daysToStandardMillis); + } + } + + @SuppressWarnings("unused") + @FunctionTemplate(name = "age", scope = FunctionTemplate.FunctionScope.SIMPLE, nulls = NullHandling.NULL_IF_NULL) + public static class AgeDateFunction implements DrillSimpleFunc { + @Param DateHolder left; + @Param DateHolder right; + @Output IntervalHolder out; + + public void setup(RecordBatch incoming) { + } + + public void eval() { + long diff = left.value - right.value; + long days = diff / org.apache.drill.exec.expr.fn.impl.DateUtility.daysToStandardMillis; + out.months = (int) (days / org.apache.drill.exec.expr.fn.impl.DateUtility.monthToStandardDays); + out.days = (int) (days % org.apache.drill.exec.expr.fn.impl.DateUtility.monthToStandardDays); + out.milliSeconds = (int) (diff % org.apache.drill.exec.expr.fn.impl.DateUtility.daysToStandardMillis); + } + } + + @SuppressWarnings("unused") + @FunctionTemplate(name = "age", scope = FunctionTemplate.FunctionScope.SIMPLE, nulls = NullHandling.NULL_IF_NULL) + public static class AgeDate2Function implements DrillSimpleFunc { + @Param DateHolder right; + @Workspace long queryStartDate; + @Output IntervalHolder out; + + public void setup(RecordBatch incoming) { + int timeZoneIndex = incoming.getContext().getRootFragmentTimeZone(); + org.joda.time.DateTimeZone timeZone = org.joda.time.DateTimeZone.forID(org.apache.drill.exec.expr.fn.impl.DateUtility.getTimeZone(timeZoneIndex)); + org.joda.time.DateTime now = new org.joda.time.DateTime(incoming.getContext().getQueryStartTime(), timeZone); + queryStartDate = (new org.joda.time.DateMidnight(now.getYear(), now.getMonthOfYear(), now.getDayOfMonth(), timeZone)).getMillis(); + } + + public void eval() { + long diff = queryStartDate - right.value; + long days = diff / org.apache.drill.exec.expr.fn.impl.DateUtility.daysToStandardMillis; + out.months = (int) (days / org.apache.drill.exec.expr.fn.impl.DateUtility.monthToStandardDays); + out.days = (int) (days % org.apache.drill.exec.expr.fn.impl.DateUtility.monthToStandardDays); + out.milliSeconds = (int) (diff % org.apache.drill.exec.expr.fn.impl.DateUtility.daysToStandardMillis); + } + } } http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/d5dbe2c7/exec/java-exec/src/test/java/org/apache/drill/exec/fn/impl/TestDateFunctions.java ---------------------------------------------------------------------- diff --git a/exec/java-exec/src/test/java/org/apache/drill/exec/fn/impl/TestDateFunctions.java b/exec/java-exec/src/test/java/org/apache/drill/exec/fn/impl/TestDateFunctions.java index ff45bb5..6338e23 100644 --- a/exec/java-exec/src/test/java/org/apache/drill/exec/fn/impl/TestDateFunctions.java +++ b/exec/java-exec/src/test/java/org/apache/drill/exec/fn/impl/TestDateFunctions.java @@ -104,6 +104,15 @@ public class TestDateFunctions extends PopUnitTestBase { } @Test + public void testAge() throws Exception { + String[] expectedResults = { "P109M16DT82800S", + "P172M27D", + "P-172M-27D", + "P-39M-18DT-63573S"}; + testCommon(expectedResults, "/functions/date/age.json", "/test_simple_date.json"); + } + + @Test public void testIntervalArithmetic() throws Exception { String expectedResults[] = {"P2Y2M", http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/d5dbe2c7/exec/java-exec/src/test/resources/functions/date/age.json ---------------------------------------------------------------------- diff --git a/exec/java-exec/src/test/resources/functions/date/age.json b/exec/java-exec/src/test/resources/functions/date/age.json new file mode 100644 index 0000000..96dc981 --- /dev/null +++ b/exec/java-exec/src/test/resources/functions/date/age.json @@ -0,0 +1,36 @@ +{ + "head" : { + "version" : 1, + "generator" : { + "type" : "org.apache.drill.exec.planner.logical.DrillImplementor", + "info" : "" + }, + "type" : "APACHE_DRILL_PHYSICAL", + "resultMode" : "EXEC" + }, + graph:[ + { + @id:1, + pop:"fs-scan", + format: {type: "json"}, + storage:{type: "file", connection: "classpath:///"}, + files:["#{TEST_FILE}"] + }, + { + pop:"project", + @id:2, + child: 1, + exprs: [ + { ref: "TS1", expr: "age(cast('2010-01-01 10:10:10' as timestamp), cast('2001-01-01 11:10:10' as timestamp))"}, + { ref: "D1", expr: "age(cast('2005-07-11' as date), cast('1991-04-29' as date))"}, + { ref: "D2", expr: "age(cast('1991-04-29' as date), cast('2005-07-11' as date))"}, + { ref: "TS2", expr: "age(cast('1997-12-17 23:37:54' as timestamp), cast('2001-03-20 17:17:27' as timestamp))"} + ] + }, + { + @id: 3, + child: 2, + pop: "screen" + } + ] +}
