You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@drill.apache.org by ja...@apache.org on 2014/07/08 03:01:14 UTC

[2/8] git commit: DRILL-861: Implement sum, avg for decimal data type.

DRILL-861: Implement sum, avg for decimal data type.


Project: http://git-wip-us.apache.org/repos/asf/incubator-drill/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-drill/commit/e987e06c
Tree: http://git-wip-us.apache.org/repos/asf/incubator-drill/tree/e987e06c
Diff: http://git-wip-us.apache.org/repos/asf/incubator-drill/diff/e987e06c

Branch: refs/heads/master
Commit: e987e06c7e9de907a689e658768d38b4f2dc5bd7
Parents: cd4f726
Author: Mehant Baid <me...@gmail.com>
Authored: Thu Jul 3 14:35:13 2014 -0700
Committer: Jacques Nadeau <ja...@apache.org>
Committed: Mon Jul 7 14:50:31 2014 -0700

----------------------------------------------------------------------
 .../drill/common/util/DecimalUtility.java       |  10 +
 exec/java-exec/src/main/codegen/config.fmpp     |   1 +
 .../src/main/codegen/data/DecimalAggrTypes1.tdd |  13 +-
 .../src/main/codegen/data/DecimalAggrTypes2.tdd |  31 +++
 .../Decimal/DecimalAggrTypeFunctions1.java      | 240 +++++++++++++++++++
 .../Decimal/DecimalAggrTypeFunctions2.java      | 123 ++++++++++
 .../templates/DecimalAggrTypeFunctions1.java    | 204 ----------------
 .../exec/expr/annotations/FunctionTemplate.java |   1 +
 .../expr/fn/DrillDecimalSumAggFuncHolder.java   |  46 ++++
 .../drill/exec/expr/fn/FunctionConverter.java   |   3 +
 10 files changed, 467 insertions(+), 205 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/e987e06c/common/src/main/java/org/apache/drill/common/util/DecimalUtility.java
----------------------------------------------------------------------
diff --git a/common/src/main/java/org/apache/drill/common/util/DecimalUtility.java b/common/src/main/java/org/apache/drill/common/util/DecimalUtility.java
index 4f9f096..465cf82 100644
--- a/common/src/main/java/org/apache/drill/common/util/DecimalUtility.java
+++ b/common/src/main/java/org/apache/drill/common/util/DecimalUtility.java
@@ -23,6 +23,7 @@ import org.apache.drill.common.types.TypeProtos;
 
 import java.math.BigDecimal;
 import java.math.BigInteger;
+import java.math.RoundingMode;
 import java.util.Arrays;
 
 public class DecimalUtility {
@@ -341,6 +342,15 @@ public class DecimalUtility {
         return (input.unscaledValue().longValue());
     }
 
+    public static BigDecimal getBigDecimalFromPrimitiveTypes(int input, int scale, int precision) {
+      return BigDecimal.valueOf(input, scale);
+    }
+
+    public static BigDecimal getBigDecimalFromPrimitiveTypes(long input, int scale, int precision) {
+      return BigDecimal.valueOf(input, scale);
+    }
+
+
     public static int compareDenseBytes(ByteBuf left, int leftStart, boolean leftSign, ByteBuf right, int rightStart, boolean rightSign, int width) {
 
       int invert = 1;

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/e987e06c/exec/java-exec/src/main/codegen/config.fmpp
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/codegen/config.fmpp b/exec/java-exec/src/main/codegen/config.fmpp
index 83a0b70..72520f6 100644
--- a/exec/java-exec/src/main/codegen/config.fmpp
+++ b/exec/java-exec/src/main/codegen/config.fmpp
@@ -22,6 +22,7 @@ data: {
     mathFunc:tdd(../data/MathFunc.tdd),
     aggrtypes1: tdd(../data/AggrTypes1.tdd),
     decimalaggrtypes1: tdd(../data/DecimalAggrTypes1.tdd),
+    decimalaggrtypes2: tdd(../data/DecimalAggrTypes2.tdd),
     aggrtypes2: tdd(../data/AggrTypes2.tdd),
     aggrtypes3: tdd(../data/AggrTypes3.tdd),
     covarTypes: tdd(../data/CovarTypes.tdd),

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/e987e06c/exec/java-exec/src/main/codegen/data/DecimalAggrTypes1.tdd
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/codegen/data/DecimalAggrTypes1.tdd b/exec/java-exec/src/main/codegen/data/DecimalAggrTypes1.tdd
index 558f95b..d8a2c73 100644
--- a/exec/java-exec/src/main/codegen/data/DecimalAggrTypes1.tdd
+++ b/exec/java-exec/src/main/codegen/data/DecimalAggrTypes1.tdd
@@ -60,6 +60,17 @@
          {inputType: "Decimal38Dense", outputType: "BigInt", runningType: "BigInt", major: "Numeric"},
          {inputType: "NullableDecimal38Dense", outputType: "BigInt", runningType: "BigInt", major: "Numeric"}
         ]
+      },
+      {className: "Sum", funcName: "sum", types: [
+        {inputType: "Decimal9", outputType: "Decimal38Sparse", major: "Numeric"},
+        {inputType: "NullableDecimal9", outputType: "Decimal38Sparse", major: "Numeric"},
+        {inputType: "Decimal18", outputType: "Decimal38Sparse", major: "Numeric"},
+        {inputType: "NullableDecimal18", outputType: "Decimal38Sparse", major: "Numeric"},
+        {inputType: "Decimal28Sparse", outputType: "Decimal38Sparse", major: "Numeric"},
+        {inputType: "NullableDecimal28Sparse", outputType: "Decimal38Sparse", major: "Numeric"},
+        {inputType: "Decimal38Sparse", outputType: "Decimal38Sparse", major: "Numeric"},
+        {inputType: "NullableDecimal38Sparse", outputType: "Decimal38Sparse", major: "Numeric"}
+        ]
       }
-  ]
+   ]
 }

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/e987e06c/exec/java-exec/src/main/codegen/data/DecimalAggrTypes2.tdd
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/codegen/data/DecimalAggrTypes2.tdd b/exec/java-exec/src/main/codegen/data/DecimalAggrTypes2.tdd
new file mode 100644
index 0000000..ed8d133
--- /dev/null
+++ b/exec/java-exec/src/main/codegen/data/DecimalAggrTypes2.tdd
@@ -0,0 +1,31 @@
+# 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: "Avg", funcName: "avg", types: [
+        {inputType: "Decimal9", outputType: "Decimal38Sparse", countRunningType: "BigInt",  major: "Numeric"},
+        {inputType: "NullableDecimal9", outputType: "Decimal38Sparse", countRunningType: "BigInt", major: "Numeric"},
+        {inputType: "Decimal18", outputType: "Decimal38Sparse", countRunningType: "BigInt", major: "Numeric"},
+        {inputType: "NullableDecimal18", outputType: "Decimal38Sparse", countRunningType: "BigInt", major: "Numeric"},
+        {inputType: "Decimal28Sparse", outputType: "Decimal38Sparse", countRunningType: "BigInt", major: "Numeric"},
+        {inputType: "NullableDecimal28Sparse", outputType: "Decimal38Sparse", countRunningType: "BigInt", major: "Numeric"},
+        {inputType: "Decimal38Sparse", outputType: "Decimal38Sparse", countRunningType: "BigInt", major: "Numeric"},
+        {inputType: "NullableDecimal38Sparse", outputType: "Decimal38Sparse", countRunningType: "BigInt", major: "Numeric"}
+      ]
+    }
+  ]
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/e987e06c/exec/java-exec/src/main/codegen/templates/Decimal/DecimalAggrTypeFunctions1.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/codegen/templates/Decimal/DecimalAggrTypeFunctions1.java b/exec/java-exec/src/main/codegen/templates/Decimal/DecimalAggrTypeFunctions1.java
new file mode 100644
index 0000000..f284a19
--- /dev/null
+++ b/exec/java-exec/src/main/codegen/templates/Decimal/DecimalAggrTypeFunctions1.java
@@ -0,0 +1,240 @@
+/**
+ * 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.
+ */
+
+import org.apache.drill.exec.expr.annotations.Workspace;
+
+<@pp.dropOutputFile />
+
+
+
+<#list decimalaggrtypes1.aggrtypes as aggrtype>
+<@pp.changeOutputFile name="/org/apache/drill/exec/expr/fn/impl/gaggr/Decimal${aggrtype.className}Functions.java" />
+
+<#include "/@includes/license.ftl" />
+
+<#-- A utility class that is used to generate java code for aggr functions for decimal data type that maintain a single -->
+<#-- running counter to hold the result.  This includes: MIN, MAX, 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;
+import io.netty.buffer.ByteBuf;
+
+@SuppressWarnings("unused")
+
+public class Decimal${aggrtype.className}Functions {
+	static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(${aggrtype.className}Functions.class);
+
+<#list aggrtype.types as type>
+
+@FunctionTemplate(name = "${aggrtype.funcName}", <#if aggrtype.funcName == "sum"> scope = FunctionTemplate.FunctionScope.DECIMAL_SUM_AGGREGATE <#else>scope = FunctionTemplate.FunctionScope.DECIMAL_AGGREGATE</#if>)
+public static class ${type.inputType}${aggrtype.className} implements DrillAggFunc{
+
+  @Param ${type.inputType}Holder in;
+  <#if aggrtype.funcName == "sum">
+  @Workspace java.math.BigDecimal value;
+  @Workspace int outputScale;
+  <#else>
+  @Workspace ${type.runningType}Holder value;
+  </#if>
+  @Workspace ByteBuf buffer;
+  @Output ${type.outputType}Holder out;
+
+  public void setup(RecordBatch b) {
+	<#if aggrtype.funcName == "count">
+  	value = new ${type.runningType}Holder();
+    value.value = 0;
+	<#elseif aggrtype.funcName == "max" || aggrtype.funcName == "min">
+  	value = new ${type.runningType}Holder();
+    <#if type.outputType.endsWith("Dense") || type.outputType.endsWith("Sparse")>
+    buffer = io.netty.buffer.Unpooled.wrappedBuffer(new byte[value.WIDTH]);
+    buffer = new io.netty.buffer.SwappedByteBuf(buffer);
+    value.buffer = buffer;
+    value.start  = 0;
+    <#if aggrtype.funcName == "max">
+    for (int i = 0; i < value.nDecimalDigits; i++) {
+      value.setInteger(i, 0xFFFFFFFF);
+    }
+    value.setSign(true);
+    <#elseif aggrtype.funcName == "min">
+    for (int i = 0; i < value.nDecimalDigits; i++) {
+      value.setInteger(i, 0x7FFFFFFF);
+    }
+    // Set sign to be positive so initial value is maximum
+    value.setSign(false);
+    value.precision = ${type.runningType}Holder.maxPrecision;
+    </#if>
+    <#elseif type.outputType == "Decimal9" || type.outputType == "Decimal18">
+    value.value = ${type.initValue};
+    </#if>
+  <#elseif aggrtype.funcName == "sum">
+    value = java.math.BigDecimal.ZERO;
+    outputScale = Integer.MIN_VALUE;
+	</#if>
+
+  }
+
+  @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>
+    <#if aggrtype.funcName == "count">
+    value.value++;
+    <#elseif aggrtype.funcName == "max">
+    <#if type.outputType.endsWith("Dense")>
+    int cmp = org.apache.drill.common.util.DecimalUtility.compareDenseBytes(in.buffer, in.start, in.getSign(), value.buffer, value.start, value.getSign(), in.WIDTH);
+    if (cmp == 1) {
+      in.buffer.getBytes(in.start, value.buffer, 0, value.WIDTH);
+      value.setSign(in.getSign());
+      value.scale = in.scale;
+      value.precision = in.precision;
+    }
+    <#elseif type.outputType.endsWith("Sparse")>
+    int cmp = org.apache.drill.common.util.DecimalUtility.compareSparseBytes(in.buffer, in.start, in.getSign(),
+      in.scale, in.precision, value.buffer,
+      value.start, value.getSign(), value.precision,
+      value.scale, in.WIDTH, in.nDecimalDigits, false);
+    if (cmp == 1) {
+      in.buffer.getBytes(in.start, value.buffer, 0, value.WIDTH);
+      value.setSign(in.getSign());
+      value.scale = in.scale;
+      value.precision = in.precision;
+    }
+    <#elseif type.outputType == "Decimal9" || type.outputType == "Decimal18">
+    value.value = Math.max(value.value, in.value);
+    </#if>
+    <#elseif aggrtype.funcName == "min">
+    <#if type.outputType.endsWith("Dense")>
+    int cmp = org.apache.drill.common.util.DecimalUtility.compareDenseBytes(in.buffer, in.start, in.getSign(), value.buffer, value.start, value.getSign(), in.WIDTH);
+    if (cmp == -1) {
+      in.buffer.getBytes(in.start, value.buffer, 0, value.WIDTH);
+      value.setSign(in.getSign());
+      value.scale = in.scale;
+      value.precision = in.precision;
+    }
+    <#elseif type.outputType.endsWith("Sparse")>
+    int cmp = org.apache.drill.common.util.DecimalUtility.compareSparseBytes(in.buffer, in.start, in.getSign(),
+      in.scale, in.precision, value.buffer,
+      value.start, value.getSign(), value.precision,
+      value.scale, in.WIDTH, in.nDecimalDigits, false);
+    if (cmp == -1) {
+      in.buffer.getBytes(in.start, value.buffer, 0, value.WIDTH);
+      value.setSign(in.getSign());
+      value.scale = in.scale;
+      value.precision = in.precision;
+    }
+    <#elseif type.outputType == "Decimal9" || type.outputType == "Decimal18">
+    value.value = Math.min(value.value, in.value);
+    </#if>
+    <#elseif aggrtype.funcName == "sum">
+   <#if type.inputType.endsWith("Decimal9") || type.inputType.endsWith("Decimal18")>
+    java.math.BigDecimal currentValue = org.apache.drill.common.util.DecimalUtility.getBigDecimalFromPrimitiveTypes(in.value, in.scale, in.precision);
+    <#else>
+    java.math.BigDecimal currentValue = org.apache.drill.common.util.DecimalUtility.getBigDecimalFromSparse(in.buffer, in.start, in.nDecimalDigits, in.scale);
+    </#if>
+    value = value.add(currentValue);
+    if (outputScale == Integer.MIN_VALUE) {
+      outputScale = in.scale;
+    }
+    </#if>
+	<#if type.inputType?starts_with("Nullable")>
+    } // end of sout block
+	</#if>
+  }
+
+  @Override
+  public void output() {
+    <#if aggrtype.funcName == "count">
+    out.value = value.value;
+    <#elseif aggrtype.funcName == "sum">
+    buffer = io.netty.buffer.Unpooled.wrappedBuffer(new byte[out.WIDTH]);
+    buffer = new io.netty.buffer.SwappedByteBuf(buffer);
+    out.buffer = buffer;
+    out.start  = 0;
+    out.scale = outputScale;
+    out.precision = 38;
+    for (int i = 0; i < out.nDecimalDigits; i++) {
+      out.setInteger(i, 0);
+    }
+    value = value.setScale(out.scale, java.math.BigDecimal.ROUND_HALF_UP);
+    org.apache.drill.common.util.DecimalUtility.getSparseFromBigDecimal(value, out.buffer, out.start, out.scale, out.precision, out.nDecimalDigits);
+    <#else>
+    <#if type.outputType.endsWith("Dense") || type.outputType.endsWith("Sparse") || aggrtype.funcName == "sum">
+    out.buffer = value.buffer;
+    out.start = value.start;
+    out.setSign(value.getSign());
+    <#elseif type.outputType == "Decimal9" || type.outputType == "Decimal18">
+    out.value = value.value;
+    </#if>
+    out.scale = value.scale;
+    out.precision = value.precision;
+    </#if>
+  }
+
+  @Override
+  public void reset() {
+
+	<#if aggrtype.funcName == "count">
+	  value.value = 0;
+	<#elseif aggrtype.funcName == "max" || aggrtype.funcName == "min">
+    <#if type.outputType.endsWith("Dense") || type.outputType.endsWith("Sparse")>
+    buffer = io.netty.buffer.Unpooled.wrappedBuffer(new byte[value.WIDTH]);
+    buffer = new io.netty.buffer.SwappedByteBuf(buffer);
+    value.buffer = buffer;
+    value.start  = 0;
+    for (int i = 0; i < value.nDecimalDigits; i++) {
+      value.setInteger(i, 0xFFFFFFFF);
+    }
+    <#if aggrtype.funcName == "min">
+    // Set sign to be positive so initial value is maximum
+    value.setSign(false);
+    <#elseif aggrtype.funcName == "max">
+    value.setSign(true);
+    </#if>
+    <#elseif type.outputType == "Decimal9" || type.outputType == "Decimal18">
+    value.value = ${type.initValue};
+    </#if>
+  <#elseif aggrtype.funcName == "sum">
+    value = java.math.BigDecimal.ZERO;
+	</#if>
+
+  }
+
+ }
+
+
+</#list>
+}
+</#list>
+

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/e987e06c/exec/java-exec/src/main/codegen/templates/Decimal/DecimalAggrTypeFunctions2.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/codegen/templates/Decimal/DecimalAggrTypeFunctions2.java b/exec/java-exec/src/main/codegen/templates/Decimal/DecimalAggrTypeFunctions2.java
new file mode 100644
index 0000000..60d708a
--- /dev/null
+++ b/exec/java-exec/src/main/codegen/templates/Decimal/DecimalAggrTypeFunctions2.java
@@ -0,0 +1,123 @@
+/**
+ * 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.
+ */
+
+import org.apache.drill.exec.expr.annotations.Workspace;
+
+<@pp.dropOutputFile />
+
+
+
+<#list decimalaggrtypes2.aggrtypes as aggrtype>
+<@pp.changeOutputFile name="/org/apache/drill/exec/expr/fn/impl/gaggr/Decimal${aggrtype.className}Functions.java" />
+
+<#include "/@includes/license.ftl" />
+
+<#-- A utility class that is used to generate java code for aggr functions for decimal data type that maintain a single -->
+<#-- running counter to hold the result.  This includes: MIN, MAX, 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;
+import io.netty.buffer.ByteBuf;
+
+@SuppressWarnings("unused")
+
+public class Decimal${aggrtype.className}Functions {
+<#list aggrtype.types as type>
+
+@FunctionTemplate(name = "${aggrtype.funcName}", scope = FunctionTemplate.FunctionScope.DECIMAL_SUM_AGGREGATE)
+public static class ${type.inputType}${aggrtype.className} implements DrillAggFunc{
+
+  @Param ${type.inputType}Holder in;
+  @Workspace java.math.BigDecimal value;
+  @Workspace ${type.countRunningType}Holder count;
+  @Workspace ByteBuf buffer;
+  @Workspace int outputScale;
+  @Output ${type.outputType}Holder out;
+
+  public void setup(RecordBatch b) {
+    value = java.math.BigDecimal.ZERO;
+    count = new ${type.countRunningType}Holder();
+    count.value = 0;
+    outputScale = Integer.MIN_VALUE;
+  }
+
+  @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>
+    count.value++;
+   <#if type.inputType.endsWith("Decimal9") || type.inputType.endsWith("Decimal18")>
+    java.math.BigDecimal currentValue = org.apache.drill.common.util.DecimalUtility.getBigDecimalFromPrimitiveTypes(in.value, in.scale, in.precision);
+    <#else>
+    java.math.BigDecimal currentValue = org.apache.drill.common.util.DecimalUtility.getBigDecimalFromSparse(in.buffer, in.start, in.nDecimalDigits, in.scale);
+    </#if>
+    value = value.add(currentValue);
+    if (outputScale == Integer.MIN_VALUE) {
+      outputScale = in.scale;
+    }
+	<#if type.inputType?starts_with("Nullable")>
+    } // end of sout block
+	</#if>
+  }
+
+  @Override
+  public void output() {
+    buffer = io.netty.buffer.Unpooled.wrappedBuffer(new byte[out.WIDTH]);
+    buffer = new io.netty.buffer.SwappedByteBuf(buffer);
+    out.buffer = buffer;
+    out.start  = 0;
+    out.scale = outputScale;
+    out.precision = 38;
+    for (int i = 0; i < out.nDecimalDigits; i++) {
+      out.setInteger(i, 0);
+    }
+    java.math.BigDecimal average = value.divide(java.math.BigDecimal.valueOf(count.value, 0), out.scale, java.math.BigDecimal.ROUND_HALF_UP);
+    org.apache.drill.common.util.DecimalUtility.getSparseFromBigDecimal(average, out.buffer, out.start, out.scale, out.precision, out.nDecimalDigits);
+  }
+
+  @Override
+  public void reset() {
+    value = java.math.BigDecimal.ZERO;
+    count = new ${type.countRunningType}Holder();
+    count.value = 0;
+    outputScale = Integer.MIN_VALUE;
+  }
+}
+
+
+</#list>
+}
+</#list>
+

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/e987e06c/exec/java-exec/src/main/codegen/templates/DecimalAggrTypeFunctions1.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/codegen/templates/DecimalAggrTypeFunctions1.java b/exec/java-exec/src/main/codegen/templates/DecimalAggrTypeFunctions1.java
deleted file mode 100644
index c5a927c..0000000
--- a/exec/java-exec/src/main/codegen/templates/DecimalAggrTypeFunctions1.java
+++ /dev/null
@@ -1,204 +0,0 @@
-/**
- * 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 decimalaggrtypes1.aggrtypes as aggrtype>
-<@pp.changeOutputFile name="/org/apache/drill/exec/expr/fn/impl/gaggr/Decimal${aggrtype.className}Functions.java" />
-
-<#include "/@includes/license.ftl" />
-
-<#-- A utility class that is used to generate java code for aggr functions for decimal data type that maintain a single -->
-<#-- running counter to hold the result.  This includes: MIN, MAX, 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;
-import io.netty.buffer.ByteBuf;
-
-@SuppressWarnings("unused")
-
-public class Decimal${aggrtype.className}Functions {
-	static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(${aggrtype.className}Functions.class);
-
-<#list aggrtype.types as type>
-
-@FunctionTemplate(name = "${aggrtype.funcName}", scope = FunctionTemplate.FunctionScope.DECIMAL_AGGREGATE)
-public static class ${type.inputType}${aggrtype.className} implements DrillAggFunc{
-
-  @Param ${type.inputType}Holder in;
-  @Workspace ${type.runningType}Holder value;
-  @Workspace ByteBuf buffer;
-  @Output ${type.outputType}Holder out;
-
-  public void setup(RecordBatch b) {
-	value = new ${type.runningType}Holder();
-	<#if aggrtype.funcName == "count">
-    value.value = 0;
-	<#elseif aggrtype.funcName == "max" || aggrtype.funcName == "min">
-    <#if type.outputType.endsWith("Dense") || type.outputType.endsWith("Sparse")>
-    buffer = io.netty.buffer.Unpooled.wrappedBuffer(new byte[value.WIDTH]);
-    buffer = new io.netty.buffer.SwappedByteBuf(buffer);
-    value.buffer = buffer;
-    value.start  = 0;
-    <#if aggrtype.funcName == "max">
-    for (int i = 0; i < value.nDecimalDigits; i++) {
-      value.setInteger(i, 0xFFFFFFFF);
-    }
-    value.setSign(true);
-    <#elseif aggrtype.funcName == "min">
-    for (int i = 0; i < value.nDecimalDigits; i++) {
-      value.setInteger(i, 0x7FFFFFFF);
-    }
-    // Set sign to be positive so initial value is maximum
-    value.setSign(false);
-    value.precision = ${type.runningType}Holder.maxPrecision;
-    </#if>
-    <#elseif type.outputType == "Decimal9" || type.outputType == "Decimal18">
-    value.value = ${type.initValue};
-    </#if>
-	</#if>
-
-  }
-
-  @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>
-    <#if aggrtype.funcName == "count">
-    value.value++;
-    <#elseif aggrtype.funcName == "max">
-    <#if type.outputType.endsWith("Dense")>
-    int cmp = org.apache.drill.common.util.DecimalUtility.compareDenseBytes(in.buffer, in.start, in.getSign(), value.buffer, value.start, value.getSign(), in.WIDTH);
-    if (cmp == 1) {
-      in.buffer.getBytes(in.start, value.buffer, 0, value.WIDTH);
-      value.setSign(in.getSign());
-      value.scale = in.scale;
-      value.precision = in.precision;
-    }
-    <#elseif type.outputType.endsWith("Sparse")>
-    int cmp = org.apache.drill.common.util.DecimalUtility.compareSparseBytes(in.buffer, in.start, in.getSign(),
-      in.scale, in.precision, value.buffer,
-      value.start, value.getSign(), value.precision,
-      value.scale, in.WIDTH, in.nDecimalDigits, false);
-    if (cmp == 1) {
-      in.buffer.getBytes(in.start, value.buffer, 0, value.WIDTH);
-      value.setSign(in.getSign());
-      value.scale = in.scale;
-      value.precision = in.precision;
-    }
-    <#elseif type.outputType == "Decimal9" || type.outputType == "Decimal18">
-    value.value = Math.max(value.value, in.value);
-    </#if>
-    <#elseif aggrtype.funcName == "min">
-    <#if type.outputType.endsWith("Dense")>
-    int cmp = org.apache.drill.common.util.DecimalUtility.compareDenseBytes(in.buffer, in.start, in.getSign(), value.buffer, value.start, value.getSign(), in.WIDTH);
-    if (cmp == -1) {
-      in.buffer.getBytes(in.start, value.buffer, 0, value.WIDTH);
-      value.setSign(in.getSign());
-      value.scale = in.scale;
-      value.precision = in.precision;
-    }
-    <#elseif type.outputType.endsWith("Sparse")>
-    int cmp = org.apache.drill.common.util.DecimalUtility.compareSparseBytes(in.buffer, in.start, in.getSign(),
-      in.scale, in.precision, value.buffer,
-      value.start, value.getSign(), value.precision,
-      value.scale, in.WIDTH, in.nDecimalDigits, false);
-    if (cmp == -1) {
-      in.buffer.getBytes(in.start, value.buffer, 0, value.WIDTH);
-      value.setSign(in.getSign());
-      value.scale = in.scale;
-      value.precision = in.precision;
-    }
-    <#elseif type.outputType == "Decimal9" || type.outputType == "Decimal18">
-    value.value = Math.min(value.value, in.value);
-    </#if>
-    </#if>
-	<#if type.inputType?starts_with("Nullable")>
-    } // end of sout block
-	</#if>
-  }
-
-  @Override
-  public void output() {
-    <#if aggrtype.funcName == "count">
-    out.value = value.value;
-    <#else>
-    <#if type.outputType.endsWith("Dense") || type.outputType.endsWith("Sparse")>
-    out.buffer = value.buffer;
-    out.start = value.start;
-    out.setSign(value.getSign());
-    <#elseif type.outputType == "Decimal9" || type.outputType == "Decimal18">
-    out.value = value.value;
-    </#if>
-    out.scale = value.scale;
-    out.precision = value.precision;
-    </#if>
-  }
-
-  @Override
-  public void reset() {
-
-	<#if aggrtype.funcName == "count">
-	  value.value = 0;
-	<#elseif aggrtype.funcName == "max" || aggrtype.funcName == "min">
-    <#if type.outputType.endsWith("Dense") || type.outputType.endsWith("Sparse")>
-    buffer = io.netty.buffer.Unpooled.wrappedBuffer(new byte[value.WIDTH]);
-    buffer = new io.netty.buffer.SwappedByteBuf(buffer);
-    value.buffer = buffer;
-    value.start  = 0;
-    for (int i = 0; i < value.nDecimalDigits; i++) {
-      value.setInteger(i, 0xFFFFFFFF);
-    }
-    <#if aggrtype.funcName == "min">
-    // Set sign to be positive so initial value is maximum
-    value.setSign(false);
-    <#elseif aggrtype.funcName == "max">
-    value.setSign(true);
-    </#if>
-    <#elseif type.outputType == "Decimal9" || type.outputType == "Decimal18">
-    value.value = ${type.initValue};
-    </#if>
-	</#if>
-
-  }
-
- }
-
-
-</#list>
-}
-</#list>
-

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/e987e06c/exec/java-exec/src/main/java/org/apache/drill/exec/expr/annotations/FunctionTemplate.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/annotations/FunctionTemplate.java b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/annotations/FunctionTemplate.java
index c2ad3d5..78a22d8 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/annotations/FunctionTemplate.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/annotations/FunctionTemplate.java
@@ -56,6 +56,7 @@ public @interface FunctionTemplate {
     SIMPLE,
     POINT_AGGREGATE,
     DECIMAL_AGGREGATE,
+    DECIMAL_SUM_AGGREGATE,
     HOLISTIC_AGGREGATE,
     RANGE_AGGREGATE,
     DECIMAL_MAX_SCALE,

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/e987e06c/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/DrillDecimalSumAggFuncHolder.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/DrillDecimalSumAggFuncHolder.java b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/DrillDecimalSumAggFuncHolder.java
new file mode 100644
index 0000000..69ab067
--- /dev/null
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/DrillDecimalSumAggFuncHolder.java
@@ -0,0 +1,46 @@
+/**
+ * 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.expr.fn;
+
+import org.apache.drill.common.expression.LogicalExpression;
+import org.apache.drill.common.types.TypeProtos;
+import org.apache.drill.exec.expr.annotations.FunctionTemplate;
+
+import java.util.List;
+import java.util.Map;
+
+public class DrillDecimalSumAggFuncHolder extends DrillAggFuncHolder {
+  public DrillDecimalSumAggFuncHolder(FunctionTemplate.FunctionScope scope, FunctionTemplate.NullHandling nullHandling, boolean isBinaryCommutative, boolean isRandom, String[] registeredNames, ValueReference[] parameters, ValueReference returnValue, WorkspaceReference[] workspaceVars, Map<String, String> methods, List<String> imports) {
+    super(scope, nullHandling, isBinaryCommutative, isRandom, registeredNames, parameters, returnValue, workspaceVars, methods, imports);
+  }
+
+  @Override
+  public TypeProtos.MajorType getReturnType(List<LogicalExpression> args) {
+
+    int scale = 0;
+    int precision = 0;
+
+    // Get the max scale and precision from the inputs
+    for (LogicalExpression e : args) {
+      scale = Math.max(scale, e.getMajorType().getScale());
+      precision = Math.max(precision, e.getMajorType().getPrecision());
+    }
+
+    return (TypeProtos.MajorType.newBuilder().setMinorType(returnValue.type.getMinorType()).setScale(scale).setPrecision(38).setMode(TypeProtos.DataMode.REQUIRED).build());
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/e987e06c/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/FunctionConverter.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/FunctionConverter.java b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/FunctionConverter.java
index 3c8536c..1d7dd0b 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/FunctionConverter.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/FunctionConverter.java
@@ -224,6 +224,9 @@ public class FunctionConverter {
       case DECIMAL_AGGREGATE:
         return new DrillDecimalAggFuncHolder(template.scope(), template.nulls(), template.isBinaryCommutative(),
           template.isRandom(), registeredNames, ps, outputField, works, methods, imports);
+      case DECIMAL_SUM_AGGREGATE:
+        return new DrillDecimalSumAggFuncHolder(template.scope(), template.nulls(), template.isBinaryCommutative(),
+          template.isRandom(), registeredNames, ps, outputField, works, methods, imports);
       case SIMPLE:
         if (outputField.isComplexWriter)
           return new DrillComplexWriterFuncHolder(template.scope(), template.nulls(),