From 5de76b28a1596ecd675c8f8ef73a48e33b27bb81 Mon Sep 17 00:00:00 2001 From: Mehant Baid Date: Tue, 22 Apr 2014 16:42:06 -0700 Subject: [PATCH] DRILL-556: Implement the following aggregate functions. stddev() stddev_samp() stddev_pop() variance() var_samp() var_pop() Date, Interval aggregate functions --- exec/java-exec/src/main/codegen/config.fmpp | 1 + .../src/main/codegen/data/AggrTypes1.tdd | 128 +++++++---- .../src/main/codegen/data/AggrTypes2.tdd | 22 +- .../src/main/codegen/data/AggrTypes3.tdd | 115 ++++++++++ .../codegen/templates/AggrTypeFunctions1.java | 3 +- .../codegen/templates/AggrTypeFunctions2.java | 3 +- .../codegen/templates/AggrTypeFunctions3.java | 126 +++++++++++ .../templates/DateIntervalAggrFunctions1.java | 204 ++++++++++++++++++ .../templates/IntervalAggrFunctions2.java | 127 +++++++++++ .../drill/exec/expr/fn/impl/DateUtility.java | 6 +- .../exec/fn/impl/TestAggregateFunction.java | 110 ++++++++++ .../functions/test_stddev_variance.json | 56 +++++ .../simple_stddev_variance_input.json | 8 + .../jdbc/test/TestDateAggregateFunction.java | 62 ++++++ 14 files changed, 920 insertions(+), 51 deletions(-) create mode 100644 exec/java-exec/src/main/codegen/data/AggrTypes3.tdd create mode 100644 exec/java-exec/src/main/codegen/templates/AggrTypeFunctions3.java create mode 100644 exec/java-exec/src/main/codegen/templates/DateIntervalAggrFunctions1.java create mode 100644 exec/java-exec/src/main/codegen/templates/IntervalAggrFunctions2.java create mode 100644 exec/java-exec/src/test/java/org/apache/drill/exec/fn/impl/TestAggregateFunction.java create mode 100644 exec/java-exec/src/test/resources/functions/test_stddev_variance.json create mode 100644 exec/java-exec/src/test/resources/simple_stddev_variance_input.json create mode 100644 sqlparser/src/test/java/org/apache/drill/jdbc/test/TestDateAggregateFunction.java diff --git a/exec/java-exec/src/main/codegen/config.fmpp b/exec/java-exec/src/main/codegen/config.fmpp index 49e0614a16f..e434f2b70e1 100644 --- a/exec/java-exec/src/main/codegen/config.fmpp +++ b/exec/java-exec/src/main/codegen/config.fmpp @@ -23,6 +23,7 @@ data: { drillOI:tdd(../data/HiveTypes.tdd), aggrtypes1: tdd(../data/AggrTypes1.tdd), aggrtypes2: tdd(../data/AggrTypes2.tdd), + aggrtypes3: tdd(../data/AggrTypes3.tdd), date: tdd(../data/DateTypes.tdd), extract: tdd(../data/ExtractTypes.tdd), parser: tdd(../data/Parser.tdd), diff --git a/exec/java-exec/src/main/codegen/data/AggrTypes1.tdd b/exec/java-exec/src/main/codegen/data/AggrTypes1.tdd index 25dcd962638..defd69d5b30 100644 --- a/exec/java-exec/src/main/codegen/data/AggrTypes1.tdd +++ b/exec/java-exec/src/main/codegen/data/AggrTypes1.tdd @@ -17,55 +17,103 @@ { aggrtypes: [ {className: "Min", funcName: "min", types: [ - {inputType: "Bit", outputType: "Bit", runningType: "Bit"}, - {inputType: "Int", outputType: "Int", runningType: "Int"}, - {inputType: "BigInt", outputType: "BigInt", runningType: "BigInt"}, - {inputType: "NullableBit", outputType: "Bit", runningType: "Bit"}, - {inputType: "NullableInt", outputType: "Int", runningType: "Int"}, - {inputType: "NullableBigInt", outputType: "BigInt", runningType: "BigInt"}, - {inputType: "Float4", outputType: "Float4", runningType: "Float4"}, - {inputType: "Float8", outputType: "Float8", runningType: "Float8"}, - {inputType: "NullableFloat4", outputType: "Float4", runningType: "Float4"}, - {inputType: "NullableFloat8", outputType: "Float8", runningType: "Float8"} + {inputType: "Bit", outputType: "Bit", runningType: "Bit", major: "Numeric"}, + {inputType: "Int", outputType: "Int", runningType: "Int", major: "Numeric"}, + {inputType: "BigInt", outputType: "BigInt", runningType: "BigInt", major: "Numeric"}, + {inputType: "NullableBit", outputType: "Bit", runningType: "Bit", major: "Numeric"}, + {inputType: "NullableInt", outputType: "Int", runningType: "Int", major: "Numeric"}, + {inputType: "NullableBigInt", outputType: "BigInt", runningType: "BigInt", major: "Numeric"}, + {inputType: "Float4", outputType: "Float4", runningType: "Float4", major: "Numeric"}, + {inputType: "Float8", outputType: "Float8", runningType: "Float8", major: "Numeric"}, + {inputType: "NullableFloat4", outputType: "Float4", runningType: "Float4", major: "Numeric"}, + {inputType: "NullableFloat8", outputType: "Float8", runningType: "Float8", major: "Numeric"}, + {inputType: "Date", outputType: "Date", runningType: "Date", major: "Date", initialValue: "Long.MAX_VALUE"}, + {inputType: "NullableDate", outputType: "Date", runningType: "Date", major: "Date", initialValue: "Long.MAX_VALUE"}, + {inputType: "TimeStamp", outputType: "TimeStamp", runningType: "TimeStamp", major: "Date", initialValue: "Long.MAX_VALUE"}, + {inputType: "NullableTimeStamp", outputType: "TimeStamp", runningType: "TimeStamp", major: "Date", initialValue: "Long.MAX_VALUE"}, + {inputType: "TimeStampTZ", outputType: "TimeStampTZ", runningType: "TimeStampTZ", major: "Date", initialValue: "Long.MAX_VALUE"}, + {inputType: "NullableTimeStampTZ", outputType: "TimeStampTZ", runningType: "TimeStampTZ", major: "Date", initialValue: "Long.MAX_VALUE"}, + {inputType: "Time", outputType: "Time", runningType: "Time", major: "Date", initialValue: "Integer.MAX_VALUE"}, + {inputType: "NullableTime", outputType: "Time", runningType: "Time", major: "Date", initialValue: "Integer.MAX_VALUE"}, + {inputType: "IntervalDay", outputType: "IntervalDay", runningType: "IntervalDay", major: "Date", initialValue: "Integer.MAX_VALUE"}, + {inputType: "NullableIntervalDay", outputType: "IntervalDay", runningType: "IntervalDay", major: "Date", initialValue: "Integer.MAX_VALUE"}, + {inputType: "IntervalYear", outputType: "IntervalYear", runningType: "IntervalYear", major: "Date", initialValue: "Integer.MAX_VALUE"}, + {inputType: "NullableIntervalYear", outputType: "IntervalYear", runningType: "IntervalYear", major: "Date", initialValue: "Integer.MAX_VALUE"}, + {inputType: "Interval", outputType: "Interval", runningType: "Interval", major: "Date", initialValue: "Integer.MAX_VALUE"}, + {inputType: "NullableInterval", outputType: "Interval", runningType: "Interval", major: "Date", initialValue: "Integer.MAX_VALUE"} ] }, {className: "Max", funcName: "max", types: [ - {inputType: "Bit", outputType: "Bit", runningType: "Bit"}, - {inputType: "Int", outputType: "Int", runningType: "Int"}, - {inputType: "BigInt", outputType: "BigInt", runningType: "BigInt"}, - {inputType: "NullableBit", outputType: "Bit", runningType: "Bit"}, - {inputType: "NullableInt", outputType: "Int", runningType: "Int"}, - {inputType: "NullableBigInt", outputType: "BigInt", runningType: "BigInt"}, - {inputType: "Float4", outputType: "Float4", runningType: "Float4"}, - {inputType: "Float8", outputType: "Float8", runningType: "Float8"}, - {inputType: "NullableFloat4", outputType: "Float4", runningType: "Float4"}, - {inputType: "NullableFloat8", outputType: "Float8", runningType: "Float8"} + {inputType: "Bit", outputType: "Bit", runningType: "Bit", major: "Numeric"}, + {inputType: "Int", outputType: "Int", runningType: "Int", major: "Numeric"}, + {inputType: "BigInt", outputType: "BigInt", runningType: "BigInt", major: "Numeric"}, + {inputType: "NullableBit", outputType: "Bit", runningType: "Bit", major: "Numeric"}, + {inputType: "NullableInt", outputType: "Int", runningType: "Int", major: "Numeric"}, + {inputType: "NullableBigInt", outputType: "BigInt", runningType: "BigInt", major: "Numeric"}, + {inputType: "Float4", outputType: "Float4", runningType: "Float4", major: "Numeric"}, + {inputType: "Float8", outputType: "Float8", runningType: "Float8", major: "Numeric"}, + {inputType: "NullableFloat4", outputType: "Float4", runningType: "Float4", major: "Numeric"}, + {inputType: "NullableFloat8", outputType: "Float8", runningType: "Float8", major: "Numeric"}, + {inputType: "Date", outputType: "Date", runningType: "Date", major: "Date", initialValue: "Long.MIN_VALUE"}, + {inputType: "NullableDate", outputType: "Date", runningType: "Date", major: "Date", initialValue: "Long.MIN_VALUE"}, + {inputType: "TimeStamp", outputType: "TimeStamp", runningType: "TimeStamp", major: "Date", initialValue: "Long.MIN_VALUE"}, + {inputType: "NullableTimeStamp", outputType: "TimeStamp", runningType: "TimeStamp", major: "Date", initialValue: "Long.MIN_VALUE"}, + {inputType: "TimeStampTZ", outputType: "TimeStampTZ", runningType: "TimeStampTZ", major: "Date", initialValue: "Long.MIN_VALUE"}, + {inputType: "NullableTimeStampTZ", outputType: "TimeStampTZ", runningType: "TimeStampTZ", major: "Date", initialValue: "Long.MIN_VALUE"}, + {inputType: "Time", outputType: "Time", runningType: "Time", major: "Date", initialValue: "Integer.MIN_VALUE"}, + {inputType: "NullableTime", outputType: "Time", runningType: "Time", major: "Date", initialValue: "Integer.MIN_VALUE"}, + {inputType: "IntervalDay", outputType: "IntervalDay", runningType: "IntervalDay", major: "Date", initialValue: "Integer.MIN_VALUE"}, + {inputType: "NullableIntervalDay", outputType: "IntervalDay", runningType: "IntervalDay", major: "Date", initialValue: "Integer.MIN_VALUE"}, + {inputType: "IntervalYear", outputType: "IntervalYear", runningType: "IntervalYear", major: "Date", initialValue: "Integer.MIN_VALUE"}, + {inputType: "NullableIntervalYear", outputType: "IntervalYear", runningType: "IntervalYear", major: "Date", initialValue: "Integer.MIN_VALUE"}, + {inputType: "Interval", outputType: "Interval", runningType: "Interval", major: "Date", initialValue: "Integer.MIN_VALUE"}, + {inputType: "NullableInterval", outputType: "Interval", runningType: "Interval", major: "Date", initialValue: "Integer.MIN_VALUE"} ] }, {className: "Sum", funcName: "sum", types: [ - {inputType: "Bit", outputType: "Bit", runningType: "Bit"}, - {inputType: "Int", outputType: "BigInt", runningType: "BigInt"}, - {inputType: "BigInt", outputType: "BigInt", runningType: "BigInt"}, - {inputType: "NullableBit", outputType: "Bit", runningType: "Bit"}, - {inputType: "NullableInt", outputType: "BigInt", runningType: "BigInt"}, - {inputType: "NullableBigInt", outputType: "BigInt", runningType: "BigInt"}, - {inputType: "Float4", outputType: "Float8", runningType: "Float8"}, - {inputType: "Float8", outputType: "Float8", runningType: "Float8"}, - {inputType: "NullableFloat4", outputType: "Float8", runningType: "Float8"}, - {inputType: "NullableFloat8", outputType: "Float8", runningType: "Float8"} + {inputType: "Bit", outputType: "Bit", runningType: "Bit", major: "Numeric"}, + {inputType: "Int", outputType: "BigInt", runningType: "BigInt", major: "Numeric"}, + {inputType: "BigInt", outputType: "BigInt", runningType: "BigInt", major: "Numeric"}, + {inputType: "NullableBit", outputType: "Bit", runningType: "Bit", major: "Numeric"}, + {inputType: "NullableInt", outputType: "BigInt", runningType: "BigInt", major: "Numeric"}, + {inputType: "NullableBigInt", outputType: "BigInt", runningType: "BigInt", major: "Numeric"}, + {inputType: "Float4", outputType: "Float8", runningType: "Float8", major: "Numeric"}, + {inputType: "Float8", outputType: "Float8", runningType: "Float8", major: "Numeric"}, + {inputType: "NullableFloat4", outputType: "Float8", runningType: "Float8", major: "Numeric"}, + {inputType: "NullableFloat8", outputType: "Float8", runningType: "Float8", major: "Numeric"}, + {inputType: "IntervalDay", outputType: "IntervalDay", runningType: "IntervalDay", major: "Date", initialValue: "0"}, + {inputType: "NullableIntervalDay", outputType: "IntervalDay", runningType: "IntervalDay", major: "Date", initialValue: "0"}, + {inputType: "IntervalYear", outputType: "IntervalYear", runningType: "IntervalYear", major: "Date", initialValue: "0"}, + {inputType: "NullableIntervalYear", outputType: "IntervalYear", runningType: "IntervalYear", major: "Date", initialValue: "0"}, + {inputType: "Interval", outputType: "Interval", runningType: "Interval", major: "Date", initialValue: "0"}, + {inputType: "NullableInterval", outputType: "Interval", runningType: "Interval", major: "Date", initialValue: "0"} ] }, {className: "Count", funcName: "count", types: [ - {inputType: "Bit", outputType: "Bit", runningType: "Bit"}, - {inputType: "Int", outputType: "BigInt", runningType: "BigInt"}, - {inputType: "BigInt", outputType: "BigInt", runningType: "BigInt"}, - {inputType: "NullableBit", outputType: "Bit", runningType: "Bit"}, - {inputType: "NullableInt", outputType: "BigInt", runningType: "BigInt"}, - {inputType: "NullableBigInt", outputType: "BigInt", runningType: "BigInt"}, - {inputType: "Float4", outputType: "BigInt", runningType: "BigInt"}, - {inputType: "Float8", outputType: "BigInt", runningType: "BigInt"}, - {inputType: "NullableFloat4", outputType: "BigInt", runningType: "BigInt"}, - {inputType: "NullableFloat8", outputType: "BigInt", runningType: "BigInt"} + {inputType: "Bit", outputType: "Bit", runningType: "Bit", major: "Numeric"}, + {inputType: "Int", outputType: "BigInt", runningType: "BigInt", major: "Numeric"}, + {inputType: "BigInt", outputType: "BigInt", runningType: "BigInt", major: "Numeric"}, + {inputType: "NullableBit", outputType: "Bit", runningType: "Bit", major: "Numeric"}, + {inputType: "NullableInt", outputType: "BigInt", runningType: "BigInt", major: "Numeric"}, + {inputType: "NullableBigInt", outputType: "BigInt", runningType: "BigInt", major: "Numeric"}, + {inputType: "Float4", outputType: "BigInt", runningType: "BigInt", major: "Numeric"}, + {inputType: "Float8", outputType: "BigInt", runningType: "BigInt", major: "Numeric"}, + {inputType: "NullableFloat4", outputType: "BigInt", runningType: "BigInt", major: "Numeric"}, + {inputType: "NullableFloat8", outputType: "BigInt", runningType: "BigInt", major: "Numeric"}, + {inputType: "Date", outputType: "BigInt", runningType: "BigInt", major: "Date", initialValue: "0"}, + {inputType: "NullableDate", outputType: "BigInt", runningType: "BigInt", major: "Date", initialValue: "0"}, + {inputType: "TimeStamp", outputType: "BigInt", runningType: "BigInt", major: "Date", initialValue: "0"}, + {inputType: "NullableTimeStamp", outputType: "BigInt", runningType: "BigInt", major: "Date", initialValue: "0"}, + {inputType: "TimeStampTZ", outputType: "BigInt", runningType: "BigInt", major: "Date", initialValue: "0"}, + {inputType: "NullableTimeStampTZ", outputType: "BigInt", runningType: "BigInt", major: "Date", initialValue: "0"}, + {inputType: "Time", outputType: "BigInt", runningType: "BigInt", major: "Date", initialValue: "0"}, + {inputType: "NullableTime", outputType: "BigInt", runningType: "BigInt", major: "Date", initialValue: "0"}, + {inputType: "IntervalDay", outputType: "BigInt", runningType: "BigInt", major: "Date", initialValue: "0"}, + {inputType: "NullableIntervalDay", outputType: "BigInt", runningType: "BigInt", major: "Date", initialValue: "0"}, + {inputType: "IntervalYear", outputType: "BigInt", runningType: "BigInt", major: "Date", initialValue: "0"}, + {inputType: "NullableIntervalYear", outputType: "BigInt", runningType: "BigInt", major: "Date", initialValue: "0"}, + {inputType: "Interval", outputType: "BigInt", runningType: "BigInt", major: "Date", initialValue: "0"}, + {inputType: "NullableInterval", outputType: "BigInt", runningType: "BigInt", major: "Date", initialValue: "0"} ] } ] diff --git a/exec/java-exec/src/main/codegen/data/AggrTypes2.tdd b/exec/java-exec/src/main/codegen/data/AggrTypes2.tdd index a05d0748948..7c2643a0432 100644 --- a/exec/java-exec/src/main/codegen/data/AggrTypes2.tdd +++ b/exec/java-exec/src/main/codegen/data/AggrTypes2.tdd @@ -17,14 +17,20 @@ { aggrtypes: [ {className: "Avg", funcName: "avg", types: [ - {inputType: "Int", outputType: "Float8", sumRunningType: "BigInt", countRunningType: "BigInt"}, - {inputType: "BigInt", outputType: "Float8", sumRunningType: "BigInt", countRunningType: "BigInt"}, - {inputType: "NullableInt", outputType: "Float8", sumRunningType: "BigInt", countRunningType: "BigInt"}, - {inputType: "NullableBigInt", outputType: "Float8", sumRunningType: "BigInt", countRunningType: "BigInt"}, - {inputType: "Float4", outputType: "Float8", sumRunningType: "BigInt", countRunningType: "BigInt"}, - {inputType: "Float8", outputType: "Float8", sumRunningType: "BigInt", countRunningType: "BigInt"}, - {inputType: "NullableFloat4", outputType: "Float8", sumRunningType: "BigInt", countRunningType: "BigInt"}, - {inputType: "NullableFloat8", outputType: "Float8", sumRunningType: "BigInt", countRunningType: "BigInt"} + {inputType: "Int", outputType: "Float8", sumRunningType: "BigInt", countRunningType: "BigInt", major: "Numeric"}, + {inputType: "BigInt", outputType: "Float8", sumRunningType: "BigInt", countRunningType: "BigInt", major: "Numeric"}, + {inputType: "NullableInt", outputType: "Float8", sumRunningType: "BigInt", countRunningType: "BigInt", major: "Numeric"}, + {inputType: "NullableBigInt", outputType: "Float8", sumRunningType: "BigInt", countRunningType: "BigInt", major: "Numeric"}, + {inputType: "Float4", outputType: "Float8", sumRunningType: "BigInt", countRunningType: "BigInt", major: "Numeric"}, + {inputType: "Float8", outputType: "Float8", sumRunningType: "BigInt", countRunningType: "BigInt", major: "Numeric"}, + {inputType: "NullableFloat4", outputType: "Float8", sumRunningType: "BigInt", countRunningType: "BigInt", major: "Numeric"}, + {inputType: "NullableFloat8", outputType: "Float8", sumRunningType: "BigInt", countRunningType: "BigInt", major: "Numeric"}, + {inputType: "IntervalDay", outputType: "Interval", sumRunningType: "BigInt", countRunningType: "BigInt", major: "Date"}, + {inputType: "NullableIntervalDay", outputType: "Interval", sumRunningType: "BigInt", countRunningType: "BigInt", major: "Date"}, + {inputType: "IntervalYear", outputType: "Interval", sumRunningType: "BigInt", countRunningType: "BigInt", major: "Date"}, + {inputType: "NullableIntervalYear", outputType: "Interval", sumRunningType: "BigInt", countRunningType: "BigInt", major: "Date"}, + {inputType: "Interval", outputType: "Interval", sumRunningType: "BigInt", countRunningType: "BigInt", major: "Date"}, + {inputType: "NullableInterval", outputType: "Interval", sumRunningType: "BigInt", countRunningType: "BigInt", major: "Date"} ] } ] diff --git a/exec/java-exec/src/main/codegen/data/AggrTypes3.tdd b/exec/java-exec/src/main/codegen/data/AggrTypes3.tdd new file mode 100644 index 00000000000..05acc032725 --- /dev/null +++ b/exec/java-exec/src/main/codegen/data/AggrTypes3.tdd @@ -0,0 +1,115 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http:# www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +{ + aggrtypes: [ + {className: "StdDevPop", funcName: "stddev_pop", aliasName: "", types: [ + {inputType: "BigInt", outputType: "Float8", movingAverageType: "Float8", movingDeviationType: "Float8", countRunningType: "BigInt"}, + {inputType: "NullableBigInt", outputType: "Float8", movingAverageType: "Float8", movingDeviationType: "Float8", countRunningType: "BigInt"}, + {inputType: "Int", outputType: "Float8", movingAverageType: "Float8", movingDeviationType: "Float8", countRunningType: "BigInt"}, + {inputType: "NullableInt", outputType: "Float8", movingAverageType: "Float8", movingDeviationType: "Float8", countRunningType: "BigInt"}, + {inputType: "SmallInt", outputType: "Float8", movingAverageType: "Float8", movingDeviationType: "Float8", countRunningType: "BigInt"}, + {inputType: "NullableSmallInt", outputType: "Float8", movingAverageType: "Float8", movingDeviationType: "Float8", countRunningType: "BigInt"}, + {inputType: "TinyInt", outputType: "Float8", movingAverageType: "Float8", movingDeviationType: "Float8", countRunningType: "BigInt"}, + {inputType: "NullableTinyInt", outputType: "Float8", movingAverageType: "Float8", movingDeviationType: "Float8", countRunningType: "BigInt"}, + {inputType: "UInt1", outputType: "Float8", movingAverageType: "Float8", movingDeviationType: "Float8", countRunningType: "BigInt"}, + {inputType: "NullableUInt1", outputType: "Float8", movingAverageType: "Float8", movingDeviationType: "Float8", countRunningType: "BigInt"}, + {inputType: "UInt2", outputType: "Float8", movingAverageType: "Float8", movingDeviationType: "Float8", countRunningType: "BigInt"}, + {inputType: "NullableUInt2", outputType: "Float8", movingAverageType: "Float8", movingDeviationType: "Float8", countRunningType: "BigInt"}, + {inputType: "UInt4", outputType: "Float8", movingAverageType: "Float8", movingDeviationType: "Float8", countRunningType: "BigInt"}, + {inputType: "NullableUInt4", outputType: "Float8", movingAverageType: "Float8", movingDeviationType: "Float8", countRunningType: "BigInt"}, + {inputType: "UInt8", outputType: "Float8", movingAverageType: "Float8", movingDeviationType: "Float8", countRunningType: "BigInt"}, + {inputType: "NullableUInt8", outputType: "Float8", movingAverageType: "Float8", movingDeviationType: "Float8", countRunningType: "BigInt"}, + {inputType: "Float4", outputType: "Float8", movingAverageType: "Float8", movingDeviationType: "Float8", countRunningType: "BigInt"}, + {inputType: "NullableFloat4", outputType: "Float8", movingAverageType: "Float8", movingDeviationType: "Float8", countRunningType: "BigInt"}, + {inputType: "Float8", outputType: "Float8", movingAverageType: "Float8", movingDeviationType: "Float8", countRunningType: "BigInt"}, + {inputType: "NullableFloat8", outputType: "Float8", movingAverageType: "Float8", movingDeviationType: "Float8", countRunningType: "BigInt"} + ] + }, + + {className: "VariancePop", funcName: "var_pop", aliasName: "", types: [ + {inputType: "BigInt", outputType: "Float8", movingAverageType: "Float8", movingDeviationType: "Float8", countRunningType: "BigInt"}, + {inputType: "NullableBigInt", outputType: "Float8", movingAverageType: "Float8", movingDeviationType: "Float8", countRunningType: "BigInt"}, + {inputType: "Int", outputType: "Float8", movingAverageType: "Float8", movingDeviationType: "Float8", countRunningType: "BigInt"}, + {inputType: "NullableInt", outputType: "Float8", movingAverageType: "Float8", movingDeviationType: "Float8", countRunningType: "BigInt"}, + {inputType: "SmallInt", outputType: "Float8", movingAverageType: "Float8", movingDeviationType: "Float8", countRunningType: "BigInt"}, + {inputType: "NullableSmallInt", outputType: "Float8", movingAverageType: "Float8", movingDeviationType: "Float8", countRunningType: "BigInt"}, + {inputType: "TinyInt", outputType: "Float8", movingAverageType: "Float8", movingDeviationType: "Float8", countRunningType: "BigInt"}, + {inputType: "NullableTinyInt", outputType: "Float8", movingAverageType: "Float8", movingDeviationType: "Float8", countRunningType: "BigInt"}, + {inputType: "UInt1", outputType: "Float8", movingAverageType: "Float8", movingDeviationType: "Float8", countRunningType: "BigInt"}, + {inputType: "NullableUInt1", outputType: "Float8", movingAverageType: "Float8", movingDeviationType: "Float8", countRunningType: "BigInt"}, + {inputType: "UInt2", outputType: "Float8", movingAverageType: "Float8", movingDeviationType: "Float8", countRunningType: "BigInt"}, + {inputType: "NullableUInt2", outputType: "Float8", movingAverageType: "Float8", movingDeviationType: "Float8", countRunningType: "BigInt"}, + {inputType: "UInt4", outputType: "Float8", movingAverageType: "Float8", movingDeviationType: "Float8", countRunningType: "BigInt"}, + {inputType: "NullableUInt4", outputType: "Float8", movingAverageType: "Float8", movingDeviationType: "Float8", countRunningType: "BigInt"}, + {inputType: "UInt8", outputType: "Float8", movingAverageType: "Float8", movingDeviationType: "Float8", countRunningType: "BigInt"}, + {inputType: "NullableUInt8", outputType: "Float8", movingAverageType: "Float8", movingDeviationType: "Float8", countRunningType: "BigInt"}, + {inputType: "Float4", outputType: "Float8", movingAverageType: "Float8", movingDeviationType: "Float8", countRunningType: "BigInt"}, + {inputType: "NullableFloat4", outputType: "Float8", movingAverageType: "Float8", movingDeviationType: "Float8", countRunningType: "BigInt"}, + {inputType: "Float8", outputType: "Float8", movingAverageType: "Float8", movingDeviationType: "Float8", countRunningType: "BigInt"}, + {inputType: "NullableFloat8", outputType: "Float8", movingAverageType: "Float8", movingDeviationType: "Float8", countRunningType: "BigInt"} + ] + }, + + {className: "StdDevSample", funcName: "stddev_samp", aliasName: "stddev", types: [ + {inputType: "BigInt", outputType: "Float8", movingAverageType: "Float8", movingDeviationType: "Float8", countRunningType: "BigInt"}, + {inputType: "NullableBigInt", outputType: "Float8", movingAverageType: "Float8", movingDeviationType: "Float8", countRunningType: "BigInt"}, + {inputType: "Int", outputType: "Float8", movingAverageType: "Float8", movingDeviationType: "Float8", countRunningType: "BigInt"}, + {inputType: "NullableInt", outputType: "Float8", movingAverageType: "Float8", movingDeviationType: "Float8", countRunningType: "BigInt"}, + {inputType: "SmallInt", outputType: "Float8", movingAverageType: "Float8", movingDeviationType: "Float8", countRunningType: "BigInt"}, + {inputType: "NullableSmallInt", outputType: "Float8", movingAverageType: "Float8", movingDeviationType: "Float8", countRunningType: "BigInt"}, + {inputType: "TinyInt", outputType: "Float8", movingAverageType: "Float8", movingDeviationType: "Float8", countRunningType: "BigInt"}, + {inputType: "NullableTinyInt", outputType: "Float8", movingAverageType: "Float8", movingDeviationType: "Float8", countRunningType: "BigInt"}, + {inputType: "UInt1", outputType: "Float8", movingAverageType: "Float8", movingDeviationType: "Float8", countRunningType: "BigInt"}, + {inputType: "NullableUInt1", outputType: "Float8", movingAverageType: "Float8", movingDeviationType: "Float8", countRunningType: "BigInt"}, + {inputType: "UInt2", outputType: "Float8", movingAverageType: "Float8", movingDeviationType: "Float8", countRunningType: "BigInt"}, + {inputType: "NullableUInt2", outputType: "Float8", movingAverageType: "Float8", movingDeviationType: "Float8", countRunningType: "BigInt"}, + {inputType: "UInt4", outputType: "Float8", movingAverageType: "Float8", movingDeviationType: "Float8", countRunningType: "BigInt"}, + {inputType: "NullableUInt4", outputType: "Float8", movingAverageType: "Float8", movingDeviationType: "Float8", countRunningType: "BigInt"}, + {inputType: "UInt8", outputType: "Float8", movingAverageType: "Float8", movingDeviationType: "Float8", countRunningType: "BigInt"}, + {inputType: "NullableUInt8", outputType: "Float8", movingAverageType: "Float8", movingDeviationType: "Float8", countRunningType: "BigInt"}, + {inputType: "Float4", outputType: "Float8", movingAverageType: "Float8", movingDeviationType: "Float8", countRunningType: "BigInt"}, + {inputType: "NullableFloat4", outputType: "Float8", movingAverageType: "Float8", movingDeviationType: "Float8", countRunningType: "BigInt"}, + {inputType: "Float8", outputType: "Float8", movingAverageType: "Float8", movingDeviationType: "Float8", countRunningType: "BigInt"}, + {inputType: "NullableFloat8", outputType: "Float8", movingAverageType: "Float8", movingDeviationType: "Float8", countRunningType: "BigInt"} + ] + }, + + {className: "VarianceSample", funcName: "var_samp", aliasName: "variance", types: [ + {inputType: "BigInt", outputType: "Float8", movingAverageType: "Float8", movingDeviationType: "Float8", countRunningType: "BigInt"}, + {inputType: "NullableBigInt", outputType: "Float8", movingAverageType: "Float8", movingDeviationType: "Float8", countRunningType: "BigInt"}, + {inputType: "Int", outputType: "Float8", movingAverageType: "Float8", movingDeviationType: "Float8", countRunningType: "BigInt"}, + {inputType: "NullableInt", outputType: "Float8", movingAverageType: "Float8", movingDeviationType: "Float8", countRunningType: "BigInt"}, + {inputType: "SmallInt", outputType: "Float8", movingAverageType: "Float8", movingDeviationType: "Float8", countRunningType: "BigInt"}, + {inputType: "NullableSmallInt", outputType: "Float8", movingAverageType: "Float8", movingDeviationType: "Float8", countRunningType: "BigInt"}, + {inputType: "TinyInt", outputType: "Float8", movingAverageType: "Float8", movingDeviationType: "Float8", countRunningType: "BigInt"}, + {inputType: "NullableTinyInt", outputType: "Float8", movingAverageType: "Float8", movingDeviationType: "Float8", countRunningType: "BigInt"}, + {inputType: "UInt1", outputType: "Float8", movingAverageType: "Float8", movingDeviationType: "Float8", countRunningType: "BigInt"}, + {inputType: "NullableUInt1", outputType: "Float8", movingAverageType: "Float8", movingDeviationType: "Float8", countRunningType: "BigInt"}, + {inputType: "UInt2", outputType: "Float8", movingAverageType: "Float8", movingDeviationType: "Float8", countRunningType: "BigInt"}, + {inputType: "NullableUInt2", outputType: "Float8", movingAverageType: "Float8", movingDeviationType: "Float8", countRunningType: "BigInt"}, + {inputType: "UInt4", outputType: "Float8", movingAverageType: "Float8", movingDeviationType: "Float8", countRunningType: "BigInt"}, + {inputType: "NullableUInt4", outputType: "Float8", movingAverageType: "Float8", movingDeviationType: "Float8", countRunningType: "BigInt"}, + {inputType: "UInt8", outputType: "Float8", movingAverageType: "Float8", movingDeviationType: "Float8", countRunningType: "BigInt"}, + {inputType: "NullableUInt8", outputType: "Float8", movingAverageType: "Float8", movingDeviationType: "Float8", countRunningType: "BigInt"}, + {inputType: "Float4", outputType: "Float8", movingAverageType: "Float8", movingDeviationType: "Float8", countRunningType: "BigInt"}, + {inputType: "NullableFloat4", outputType: "Float8", movingAverageType: "Float8", movingDeviationType: "Float8", countRunningType: "BigInt"}, + {inputType: "Float8", outputType: "Float8", movingAverageType: "Float8", movingDeviationType: "Float8", countRunningType: "BigInt"}, + {inputType: "NullableFloat8", outputType: "Float8", movingAverageType: "Float8", movingDeviationType: "Float8", countRunningType: "BigInt"} + ] + } + ] +} diff --git a/exec/java-exec/src/main/codegen/templates/AggrTypeFunctions1.java b/exec/java-exec/src/main/codegen/templates/AggrTypeFunctions1.java index 14ca1ce6805..aa9aeab7af7 100644 --- a/exec/java-exec/src/main/codegen/templates/AggrTypeFunctions1.java +++ b/exec/java-exec/src/main/codegen/templates/AggrTypeFunctions1.java @@ -48,6 +48,7 @@ public class ${aggrtype.className}Functions { static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(${aggrtype.className}Functions.class); <#list aggrtype.types as type> +<#if type.major == "Numeric"> @FunctionTemplate(name = "${aggrtype.funcName}", scope = FunctionTemplate.FunctionScope.POINT_AGGREGATE) public static class ${type.inputType}${aggrtype.className} implements DrillAggFunc{ @@ -149,7 +150,7 @@ public void reset() { } - + } diff --git a/exec/java-exec/src/main/codegen/templates/AggrTypeFunctions2.java b/exec/java-exec/src/main/codegen/templates/AggrTypeFunctions2.java index f2ebbe8fcf9..8606dd1f2ca 100644 --- a/exec/java-exec/src/main/codegen/templates/AggrTypeFunctions2.java +++ b/exec/java-exec/src/main/codegen/templates/AggrTypeFunctions2.java @@ -49,6 +49,7 @@ public class ${aggrtype.className}Functions { static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(${aggrtype.className}Functions.class); <#list aggrtype.types as type> +<#if type.major == "Numeric"> @FunctionTemplate(name = "${aggrtype.funcName}", scope = FunctionTemplate.FunctionScope.POINT_AGGREGATE) @@ -99,7 +100,7 @@ public void reset() { } - + } diff --git a/exec/java-exec/src/main/codegen/templates/AggrTypeFunctions3.java b/exec/java-exec/src/main/codegen/templates/AggrTypeFunctions3.java new file mode 100644 index 00000000000..1b276e7c81e --- /dev/null +++ b/exec/java-exec/src/main/codegen/templates/AggrTypeFunctions3.java @@ -0,0 +1,126 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +<@pp.dropOutputFile /> + + + +<#list aggrtypes3.aggrtypes as aggrtype> +<@pp.changeOutputFile name="/org/apache/drill/exec/expr/fn/impl/gaggr/${aggrtype.className}Functions.java" /> + +<#include "/@includes/license.ftl" /> + +<#-- A utility class that is used to generate java code for aggr functions such as stddev, variance --> + +/* + * This class is automatically generated from AggrTypeFunctions2.tdd using FreeMarker. + */ + +package org.apache.drill.exec.expr.fn.impl.gaggr; + +import org.apache.drill.exec.expr.DrillAggFunc; +import org.apache.drill.exec.expr.annotations.FunctionTemplate; +import org.apache.drill.exec.expr.annotations.FunctionTemplate.NullHandling; +import org.apache.drill.exec.expr.annotations.FunctionTemplate.FunctionScope; +import org.apache.drill.exec.expr.annotations.Output; +import org.apache.drill.exec.expr.annotations.Param; +import org.apache.drill.exec.expr.annotations.Workspace; +import org.apache.drill.exec.expr.holders.*; +import org.apache.drill.exec.record.RecordBatch; + +@SuppressWarnings("unused") + +public class ${aggrtype.className}Functions { + static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(${aggrtype.className}Functions.class); + +<#list aggrtype.types as type> + +<#if aggrtype.aliasName == ""> +@FunctionTemplate(name = "${aggrtype.funcName}", scope = FunctionTemplate.FunctionScope.POINT_AGGREGATE) +<#else> +@FunctionTemplate(names = {"${aggrtype.funcName}", "${aggrtype.aliasName}"}, scope = FunctionTemplate.FunctionScope.POINT_AGGREGATE) + + +public static class ${type.inputType}${aggrtype.className} implements DrillAggFunc{ + + @Param ${type.inputType}Holder in; + @Workspace ${type.movingAverageType}Holder avg; + @Workspace ${type.movingDeviationType}Holder dev; + @Workspace ${type.countRunningType}Holder count; + @Output ${type.outputType}Holder out; + + public void setup(RecordBatch b) { + avg = new ${type.movingAverageType}Holder(); + dev = new ${type.movingDeviationType}Holder(); + count = new ${type.countRunningType}Holder(); + + // Initialize the workspace variables + avg.value = 0; + dev.value = 0; + count.value = 1; + } + + @Override + public void add() { + <#if type.inputType?starts_with("Nullable")> + sout: { + if (in.isSet == 0) { + // processing nullable input and the value is null, so don't do anything... + break sout; + } + + + // Welford's approach to compute standard deviation + double temp = avg.value; + avg.value += ((in.value - temp) / count.value); + dev.value += (in.value - temp) * (in.value - avg.value); + count.value++; + + <#if type.inputType?starts_with("Nullable")> + } // end of sout block + + } + + @Override + public void output() { + <#if aggrtype.funcName == "stddev_pop"> + if (count.value > 1) + out.value = Math.sqrt((dev.value / (count.value - 1))); + <#elseif aggrtype.funcName == "var_pop"> + if (count.value > 1) + out.value = (dev.value / (count.value - 1)); + <#elseif aggrtype.funcName == "stddev_samp"> + if (count.value > 2) + out.value = Math.sqrt((dev.value / (count.value - 2))); + <#elseif aggrtype.funcName == "var_samp"> + if (count.value > 2) + out.value = (dev.value / (count.value - 2)); + + } + + @Override + public void reset() { + avg.value = 0; + dev.value = 0; + count.value = 1; + } +} + + + +} + diff --git a/exec/java-exec/src/main/codegen/templates/DateIntervalAggrFunctions1.java b/exec/java-exec/src/main/codegen/templates/DateIntervalAggrFunctions1.java new file mode 100644 index 00000000000..f451105d14d --- /dev/null +++ b/exec/java-exec/src/main/codegen/templates/DateIntervalAggrFunctions1.java @@ -0,0 +1,204 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +<@pp.dropOutputFile /> + + + +<#list aggrtypes1.aggrtypes as aggrtype> +<@pp.changeOutputFile name="/org/apache/drill/exec/expr/fn/impl/gaggr/${aggrtype.className}DateTypeFunctions.java" /> + +<#include "/@includes/license.ftl" /> + +<#-- A utility class that is used to generate java code for aggr functions for Date, Time, Interval types --> +<#-- that maintain a single running counter to hold the result. This includes: MIN, MAX, SUM, COUNT. --> + +/* + * This class is automatically generated from AggrTypeFunctions1.tdd using FreeMarker. + */ + +package org.apache.drill.exec.expr.fn.impl.gaggr; + +import org.apache.drill.exec.expr.DrillAggFunc; +import org.apache.drill.exec.expr.annotations.FunctionTemplate; +import org.apache.drill.exec.expr.annotations.FunctionTemplate.FunctionScope; +import org.apache.drill.exec.expr.annotations.Output; +import org.apache.drill.exec.expr.annotations.Param; +import org.apache.drill.exec.expr.annotations.Workspace; +import org.apache.drill.exec.expr.holders.*; +import org.apache.drill.exec.record.RecordBatch; + +@SuppressWarnings("unused") + +public class ${aggrtype.className}DateTypeFunctions { + static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(${aggrtype.className}Functions.class); + +<#list aggrtype.types as type> +<#if type.major == "Date"> +@FunctionTemplate(name = "${aggrtype.funcName}", scope = FunctionTemplate.FunctionScope.POINT_AGGREGATE) +public static class ${type.inputType}${aggrtype.className} implements DrillAggFunc{ + + @Param ${type.inputType}Holder in; + @Workspace ${type.runningType}Holder value; + @Output ${type.outputType}Holder out; + + public void setup(RecordBatch b) { + value = new ${type.runningType}Holder(); + <#if type.runningType == "Interval"> + value.months = ${type.initialValue}; + value.days= ${type.initialValue}; + value.milliSeconds = ${type.initialValue}; + <#elseif type.outputType == "IntervalDay"> + value.days= ${type.initialValue}; + value.milliSeconds = ${type.initialValue}; + <#else> + value.value = ${type.initialValue}; + + } + + @Override + public void add() { + <#if type.inputType?starts_with("Nullable")> + sout: { + if (in.isSet == 0) { + // processing nullable input and the value is null, so don't do anything... + break sout; + } + + + <#if aggrtype.funcName == "min"> + + <#if type.outputType == "TimeStampTZ"> + if (in.value < value.value) { + value.value = in.value; + value.index = in.index; + } + <#elseif type.outputType == "Interval"> + long valueMS = (long) value.months * org.apache.drill.exec.expr.fn.impl.DateUtility.monthToStandardDays + + value.days * (org.apache.drill.exec.expr.fn.impl.DateUtility.daysToStandardMillis) + + value.milliSeconds; + long inMS = (long) in.months * org.apache.drill.exec.expr.fn.impl.DateUtility.monthToStandardDays + + in.days * (org.apache.drill.exec.expr.fn.impl.DateUtility.daysToStandardMillis) + + in.milliSeconds; + + if (valueMS < inMS) { + value.days = in.days; + value.months = in.months; + value.milliSeconds = in.milliSeconds; + } + <#elseif type.outputType == "IntervalDay"> + long valueMS = (long) value.days * (org.apache.drill.exec.expr.fn.impl.DateUtility.daysToStandardMillis) + + value.milliSeconds; + long inMS = (long) in.days * (org.apache.drill.exec.expr.fn.impl.DateUtility.daysToStandardMillis) + + in.milliSeconds; + + if (valueMS < inMS) { + value.days = in.days; + value.milliSeconds = in.milliSeconds; + } + <#else> + value.value = Math.min(value.value, in.value); + + <#elseif aggrtype.funcName == "max"> + <#if type.outputType == "TimeStampTZ"> + if (in.value < value.value) { + value.value = in.value; + value.index = in.index; + } + <#elseif type.outputType == "Interval"> + long valueMS = (long) value.months * org.apache.drill.exec.expr.fn.impl.DateUtility.monthToStandardDays + + value.days * (org.apache.drill.exec.expr.fn.impl.DateUtility.daysToStandardMillis) + + value.milliSeconds; + long inMS = (long) in.months * org.apache.drill.exec.expr.fn.impl.DateUtility.monthToStandardDays + + in.days * (org.apache.drill.exec.expr.fn.impl.DateUtility.daysToStandardMillis) + + in.milliSeconds; + + if (valueMS > inMS) { + value.days = in.days; + value.months = in.months; + value.milliSeconds = in.milliSeconds; + } + <#elseif type.outputType == "IntervalDay"> + long valueMS = (long) value.days * (org.apache.drill.exec.expr.fn.impl.DateUtility.daysToStandardMillis) + + value.milliSeconds; + long inMS = (long) in.days * (org.apache.drill.exec.expr.fn.impl.DateUtility.daysToStandardMillis) + + in.milliSeconds; + + if (valueMS > inMS) { + value.days = in.days; + value.milliSeconds = in.milliSeconds; + } + <#else> + value.value = Math.max(value.value, in.value); + + + <#elseif aggrtype.funcName == "sum"> + <#if type.outputType == "Interval"> + value.days += in.days; + value.months += in.months; + value.milliSeconds += in.milliSeconds; + <#elseif type.outputType == "IntervalDay"> + value.days += in.days; + value.milliSeconds += in.milliSeconds; + <#else> + value.value += in.value; + + <#elseif aggrtype.funcName == "count"> + value.value++; + <#else> + // TODO: throw an error ? + + <#if type.inputType?starts_with("Nullable")> + } // end of sout block + + } + + @Override + public void output() { + <#if type.runningType == "Interval"> + out.months = value.months; + out.days = value.days; + out.milliSeconds = value.milliSeconds; + <#elseif type.outputType == "IntervalDay"> + out.days = value.days; + out.milliSeconds = value.milliSeconds; + <#else> + out.value = value.value; + + } + + @Override + public void reset() { + <#if type.runningType == "Interval"> + value.months = ${type.initialValue}; + value.days= ${type.initialValue}; + value.milliSeconds = ${type.initialValue}; + <#elseif type.outputType == "IntervalDay"> + value.days= ${type.initialValue}; + value.milliSeconds = ${type.initialValue}; + <#else> + value.value = ${type.initialValue}; + + } + + } + + + +} + + diff --git a/exec/java-exec/src/main/codegen/templates/IntervalAggrFunctions2.java b/exec/java-exec/src/main/codegen/templates/IntervalAggrFunctions2.java new file mode 100644 index 00000000000..ba572103fee --- /dev/null +++ b/exec/java-exec/src/main/codegen/templates/IntervalAggrFunctions2.java @@ -0,0 +1,127 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +<@pp.dropOutputFile /> + + + +<#list aggrtypes2.aggrtypes as aggrtype> +<@pp.changeOutputFile name="/org/apache/drill/exec/expr/fn/impl/gaggr/${aggrtype.className}IntervalTypeFunctions.java" /> + +<#include "/@includes/license.ftl" /> + +<#-- A utility class that is used to generate java code for aggr functions for the interval data types. It maintains a running sum --> +<#-- and a running count. For now, this includes: AVG. --> + +/* + * This class is automatically generated from AggrTypeFunctions2.tdd using FreeMarker. + */ + + +package org.apache.drill.exec.expr.fn.impl.gaggr; + +import org.apache.drill.exec.expr.DrillAggFunc; +import org.apache.drill.exec.expr.annotations.FunctionTemplate; +import org.apache.drill.exec.expr.annotations.FunctionTemplate.FunctionScope; +import org.apache.drill.exec.expr.annotations.Output; +import org.apache.drill.exec.expr.annotations.Param; +import org.apache.drill.exec.expr.annotations.Workspace; +import org.apache.drill.exec.expr.holders.*; +import org.apache.drill.exec.record.RecordBatch; + +@SuppressWarnings("unused") + +public class ${aggrtype.className}IntervalTypeFunctions { + static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(${aggrtype.className}Functions.class); + +<#list aggrtype.types as type> +<#if type.major == "Date"> + +@FunctionTemplate(name = "${aggrtype.funcName}", scope = FunctionTemplate.FunctionScope.POINT_AGGREGATE) + +public static class ${type.inputType}${aggrtype.className} implements DrillAggFunc{ + + @Param ${type.inputType}Holder in; + @Workspace ${type.sumRunningType}Holder sum; + @Workspace ${type.countRunningType}Holder count; + @Output ${type.outputType}Holder out; + + public void setup(RecordBatch b) { + sum = new ${type.sumRunningType}Holder(); + count = new ${type.countRunningType}Holder(); + sum.value = 0; + count.value = 0; + } + + @Override + public void add() { + <#if type.inputType?starts_with("Nullable")> + sout: { + if (in.isSet == 0) { + // processing nullable input and the value is null, so don't do anything... + break sout; + } + + <#if aggrtype.funcName == "avg"> + <#if type.inputType.endsWith("Interval")> + sum.value += (long) in.months * org.apache.drill.exec.expr.fn.impl.DateUtility.monthToStandardDays + + in.days * (org.apache.drill.exec.expr.fn.impl.DateUtility.daysToStandardMillis) + + in.milliSeconds; + <#elseif type.inputType.endsWith("IntervalDay")> + sum.value += (long) in.days * (org.apache.drill.exec.expr.fn.impl.DateUtility.daysToStandardMillis) + + in.milliSeconds; + <#else> + sum.value += in.value; + + count.value++; + + <#else> + // TODO: throw an error ? + + <#if type.inputType?starts_with("Nullable")> + } // end of sout block + + } + + @Override + public void output() { + double millis = sum.value / ((double) count.value); + <#if type.inputType.endsWith("Interval") || type.inputType.endsWith("IntervalYear")> + out.months = (int) (millis / org.apache.drill.exec.expr.fn.impl.DateUtility.monthsToMillis); + millis = millis % org.apache.drill.exec.expr.fn.impl.DateUtility.monthsToMillis; + out.days =(int) (millis / org.apache.drill.exec.expr.fn.impl.DateUtility.daysToStandardMillis); + out.milliSeconds = (int) (millis % org.apache.drill.exec.expr.fn.impl.DateUtility.daysToStandardMillis); + <#elseif type.inputType.endsWith("IntervalDay")> + out.months = 0; + out.days = (int) (millis / org.apache.drill.exec.expr.fn.impl.DateUtility.daysToStandardMillis); + out.milliSeconds = (int) (millis % org.apache.drill.exec.expr.fn.impl.DateUtility.daysToStandardMillis); + + } + + @Override + public void reset() { + sum.value = 0; + count.value = 0; + } + + } + + + +} + + diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/DateUtility.java b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/DateUtility.java index c9e66a1a41e..390b0331746 100644 --- a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/DateUtility.java +++ b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/DateUtility.java @@ -1199,8 +1199,12 @@ public class DateUtility { public static final int hoursToMillis = 60 * 60 * 1000; public static final int minutesToMillis = 60 * 1000; public static final int secondsToMillis = 1000; + public static final int monthToStandardDays = 30; + public static final int monthsToMillis = 30 * 24 * 60 * 60 * 1000; + public static final int daysToStandardMillis = 24 * 60 * 60 * 1000; - public static int getIndex(String timezone) { + + public static int getIndex(String timezone) { return timezoneMap.get(timezone); } diff --git a/exec/java-exec/src/test/java/org/apache/drill/exec/fn/impl/TestAggregateFunction.java b/exec/java-exec/src/test/java/org/apache/drill/exec/fn/impl/TestAggregateFunction.java new file mode 100644 index 00000000000..8d8b0eb62fc --- /dev/null +++ b/exec/java-exec/src/test/java/org/apache/drill/exec/fn/impl/TestAggregateFunction.java @@ -0,0 +1,110 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.drill.exec.fn.impl; + +import org.apache.drill.exec.pop.PopUnitTestBase; +import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; + +import mockit.Injectable; +import mockit.NonStrictExpectations; + +import org.apache.drill.common.config.DrillConfig; +import org.apache.drill.common.expression.ExpressionPosition; +import org.apache.drill.common.expression.SchemaPath; +import org.apache.drill.common.util.FileUtils; +import org.apache.drill.exec.client.DrillClient; +import org.apache.drill.exec.expr.fn.FunctionImplementationRegistry; +import org.apache.drill.exec.memory.BufferAllocator; +import org.apache.drill.exec.memory.TopLevelAllocator; +import org.apache.drill.exec.ops.FragmentContext; +import org.apache.drill.exec.physical.PhysicalPlan; +import org.apache.drill.exec.physical.base.FragmentRoot; +import org.apache.drill.exec.physical.impl.OperatorCreatorRegistry; +import org.apache.drill.exec.physical.impl.ImplCreator; +import org.apache.drill.exec.physical.impl.SimpleRootExec; +import org.apache.drill.exec.planner.PhysicalPlanReader; +import org.apache.drill.exec.pop.PopUnitTestBase; +import org.apache.drill.exec.proto.BitControl; +import org.apache.drill.exec.proto.CoordinationProtos; +import org.apache.drill.exec.proto.ExecProtos.FragmentHandle; +import org.apache.drill.exec.proto.UserProtos; +import org.apache.drill.exec.record.RecordBatchLoader; +import org.apache.drill.exec.record.VectorWrapper; +import org.apache.drill.exec.rpc.user.QueryResultBatch; +import org.apache.drill.exec.rpc.user.UserServer.UserClientConnection; +import org.apache.drill.exec.server.Drillbit; +import org.apache.drill.exec.server.DrillbitContext; +import org.apache.drill.exec.server.RemoteServiceSet; +import org.apache.drill.exec.vector.BigIntVector; +import org.apache.drill.exec.vector.Float8Vector; + +import org.apache.drill.exec.vector.ValueVector; +import org.junit.Ignore; +import org.junit.Test; + +import com.google.common.base.Charsets; +import com.google.common.io.Files; +import com.codahale.metrics.MetricRegistry; + +import java.util.Iterator; +import java.util.List; + +public class TestAggregateFunction extends PopUnitTestBase { + @Test + public void testSortDate() throws Exception { + try (RemoteServiceSet serviceSet = RemoteServiceSet.getLocalServiceSet(); + Drillbit bit = new Drillbit(CONFIG, serviceSet); + DrillClient client = new DrillClient(CONFIG, serviceSet.getCoordinator())) { + + // run query. + bit.run(); + client.connect(); + List results = client.runQuery(UserProtos.QueryType.PHYSICAL, + Files.toString(FileUtils.getResourceAsFile("/functions/test_stddev_variance.json"), Charsets.UTF_8) + .replace("#{TEST_FILE}", "/simple_stddev_variance_input.json")); + + RecordBatchLoader batchLoader = new RecordBatchLoader(bit.getContext().getAllocator()); + + QueryResultBatch batch = results.get(0); + assertTrue(batchLoader.load(batch.getHeader().getDef(), batch.getData())); + + Double values[] = {2.0d, + 2.138089935299395d, + 2.138089935299395d, + 4.0d, + 4.571428571428571d, + 4.571428571428571d}; + + batchLoader.getValueAccessorById(0, BigIntVector.class); + + int i = 0; + for (VectorWrapper v : batchLoader) { + + ValueVector.Accessor accessor = v.getValueVector().getAccessor(); + System.out.println(accessor.getObject(0)); + assertEquals((accessor.getObject(0)), values[i++]); + } + + batchLoader.clear(); + for(QueryResultBatch b : results){ + b.release(); + } + } + } +} diff --git a/exec/java-exec/src/test/resources/functions/test_stddev_variance.json b/exec/java-exec/src/test/resources/functions/test_stddev_variance.json new file mode 100644 index 00000000000..5ba8d3edeea --- /dev/null +++ b/exec/java-exec/src/test/resources/functions/test_stddev_variance.json @@ -0,0 +1,56 @@ +{ + "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, + "exprs" : [ { + "ref" : "`A`", + "expr" : "`A`" + } ], + "child" : 1 + }, { + "pop" : "streaming-aggregate", + "@id" : 3, + "child" : 2, + "keys" : [ ], + "exprs" : [ { + "ref" : "`EXPR$0`", + "expr" : "stddev_pop(`A`) " + }, { + "ref" : "`EXPR$1`", + "expr" : "stddev(`A`) " + }, { + "ref" : "`EXPR$2`", + "expr" : "stddev_samp(`A`) " + }, { + "ref" : "`EXPR$3`", + "expr" : "var_pop(`A`) " + }, { + "ref" : "`EXPR$4`", + "expr" : "variance(`A`) " + }, { + "ref" : "`EXPR$5`", + "expr" : "var_samp(`A`) " + } ] + }, { + "pop" : "screen", + "@id" : 4, + "child" : 3 + } ] +} diff --git a/exec/java-exec/src/test/resources/simple_stddev_variance_input.json b/exec/java-exec/src/test/resources/simple_stddev_variance_input.json new file mode 100644 index 00000000000..7e128185ca5 --- /dev/null +++ b/exec/java-exec/src/test/resources/simple_stddev_variance_input.json @@ -0,0 +1,8 @@ +{"A" : 2.0} +{"A" : 4.0} +{"A" : 4.0} +{"A" : 4.0} +{"A" : 5.0} +{"A" : 5.0} +{"A" : 7.0} +{"A" : 9.0} \ No newline at end of file diff --git a/sqlparser/src/test/java/org/apache/drill/jdbc/test/TestDateAggregateFunction.java b/sqlparser/src/test/java/org/apache/drill/jdbc/test/TestDateAggregateFunction.java new file mode 100644 index 00000000000..9d3366674dc --- /dev/null +++ b/sqlparser/src/test/java/org/apache/drill/jdbc/test/TestDateAggregateFunction.java @@ -0,0 +1,62 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.drill.jdbc.test; + +import java.nio.file.Paths; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.ResultSet; +import java.sql.ResultSetMetaData; +import java.sql.Statement; +import java.util.concurrent.TimeUnit; + +import org.apache.drill.common.util.TestTools; +import org.apache.drill.exec.store.hive.HiveTestDataGenerator; +import org.apache.drill.jdbc.Driver; +import org.apache.drill.jdbc.JdbcTest; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Ignore; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestRule; + +import com.google.common.base.Function; +import com.google.common.base.Stopwatch; + +public class TestDateAggregateFunction { + + public static final String WORKING_PATH; + static{ + Driver.load(); + WORKING_PATH = Paths.get("").toAbsolutePath().toString(); + + } + @Test + public void testAbsDecimalFunction() throws Exception{ + String query = new String("SELECT max(cast(HIRE_DATE as date)) as MAX_DATE, min(cast(HIRE_DATE as date)) as MIN_DATE" + + " FROM `employee.json`"); + + JdbcAssert.withFull("cp") + .sql(query) + .returns( + "MAX_DATE=1998-01-01; " + + "MIN_DATE=1993-05-01\n" + ); + } +}