PageRenderTime 42ms CodeModel.GetById 15ms RepoModel.GetById 1ms app.codeStats 0ms

/tags/release-0.1-rc2/hive/external/ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDAFSum.java

#
Java | 237 lines | 178 code | 28 blank | 31 comment | 17 complexity | 5138b819e8496f27dd58c004575f24f5 MD5 | raw file
Possible License(s): Apache-2.0, BSD-3-Clause, JSON, CPL-1.0
  1. /**
  2. * Licensed to the Apache Software Foundation (ASF) under one
  3. * or more contributor license agreements. See the NOTICE file
  4. * distributed with this work for additional information
  5. * regarding copyright ownership. The ASF licenses this file
  6. * to you under the Apache License, Version 2.0 (the
  7. * "License"); you may not use this file except in compliance
  8. * with the License. You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an "AS IS" BASIS,
  14. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. */
  18. package org.apache.hadoop.hive.ql.udf.generic;
  19. import org.apache.commons.logging.Log;
  20. import org.apache.commons.logging.LogFactory;
  21. import org.apache.hadoop.hive.ql.exec.Description;
  22. import org.apache.hadoop.hive.ql.exec.UDFArgumentTypeException;
  23. import org.apache.hadoop.hive.ql.metadata.HiveException;
  24. import org.apache.hadoop.hive.ql.parse.SemanticException;
  25. import org.apache.hadoop.hive.serde2.io.DoubleWritable;
  26. import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector;
  27. import org.apache.hadoop.hive.serde2.objectinspector.PrimitiveObjectInspector;
  28. import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorFactory;
  29. import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorUtils;
  30. import org.apache.hadoop.hive.serde2.typeinfo.PrimitiveTypeInfo;
  31. import org.apache.hadoop.hive.serde2.typeinfo.TypeInfo;
  32. import org.apache.hadoop.io.LongWritable;
  33. import org.apache.hadoop.util.StringUtils;
  34. /**
  35. * GenericUDAFSum.
  36. *
  37. */
  38. @Description(name = "sum", value = "_FUNC_(x) - Returns the sum of a set of numbers")
  39. public class GenericUDAFSum extends AbstractGenericUDAFResolver {
  40. static final Log LOG = LogFactory.getLog(GenericUDAFSum.class.getName());
  41. @Override
  42. public GenericUDAFEvaluator getEvaluator(TypeInfo[] parameters)
  43. throws SemanticException {
  44. if (parameters.length != 1) {
  45. throw new UDFArgumentTypeException(parameters.length - 1,
  46. "Exactly one argument is expected.");
  47. }
  48. if (parameters[0].getCategory() != ObjectInspector.Category.PRIMITIVE) {
  49. throw new UDFArgumentTypeException(0,
  50. "Only primitive type arguments are accepted but "
  51. + parameters[0].getTypeName() + " is passed.");
  52. }
  53. switch (((PrimitiveTypeInfo) parameters[0]).getPrimitiveCategory()) {
  54. case BYTE:
  55. case SHORT:
  56. case INT:
  57. case LONG:
  58. return new GenericUDAFSumLong();
  59. case FLOAT:
  60. case DOUBLE:
  61. case STRING:
  62. return new GenericUDAFSumDouble();
  63. case BOOLEAN:
  64. default:
  65. throw new UDFArgumentTypeException(0,
  66. "Only numeric or string type arguments are accepted but "
  67. + parameters[0].getTypeName() + " is passed.");
  68. }
  69. }
  70. /**
  71. * GenericUDAFSumDouble.
  72. *
  73. */
  74. public static class GenericUDAFSumDouble extends GenericUDAFEvaluator {
  75. private PrimitiveObjectInspector inputOI;
  76. private DoubleWritable result;
  77. @Override
  78. public ObjectInspector init(Mode m, ObjectInspector[] parameters) throws HiveException {
  79. assert (parameters.length == 1);
  80. super.init(m, parameters);
  81. result = new DoubleWritable(0);
  82. inputOI = (PrimitiveObjectInspector) parameters[0];
  83. return PrimitiveObjectInspectorFactory.writableDoubleObjectInspector;
  84. }
  85. /** class for storing double sum value. */
  86. static class SumDoubleAgg implements AggregationBuffer {
  87. boolean empty;
  88. double sum;
  89. }
  90. @Override
  91. public AggregationBuffer getNewAggregationBuffer() throws HiveException {
  92. SumDoubleAgg result = new SumDoubleAgg();
  93. reset(result);
  94. return result;
  95. }
  96. @Override
  97. public void reset(AggregationBuffer agg) throws HiveException {
  98. SumDoubleAgg myagg = (SumDoubleAgg) agg;
  99. myagg.empty = true;
  100. myagg.sum = 0;
  101. }
  102. boolean warned = false;
  103. @Override
  104. public void iterate(AggregationBuffer agg, Object[] parameters) throws HiveException {
  105. assert (parameters.length == 1);
  106. try {
  107. merge(agg, parameters[0]);
  108. } catch (NumberFormatException e) {
  109. if (!warned) {
  110. warned = true;
  111. LOG.warn(getClass().getSimpleName() + " "
  112. + StringUtils.stringifyException(e));
  113. LOG
  114. .warn(getClass().getSimpleName()
  115. + " ignoring similar exceptions.");
  116. }
  117. }
  118. }
  119. @Override
  120. public Object terminatePartial(AggregationBuffer agg) throws HiveException {
  121. return terminate(agg);
  122. }
  123. @Override
  124. public void merge(AggregationBuffer agg, Object partial) throws HiveException {
  125. if (partial != null) {
  126. SumDoubleAgg myagg = (SumDoubleAgg) agg;
  127. myagg.empty = false;
  128. myagg.sum += PrimitiveObjectInspectorUtils.getDouble(partial, inputOI);
  129. }
  130. }
  131. @Override
  132. public Object terminate(AggregationBuffer agg) throws HiveException {
  133. SumDoubleAgg myagg = (SumDoubleAgg) agg;
  134. if (myagg.empty) {
  135. return null;
  136. }
  137. result.set(myagg.sum);
  138. return result;
  139. }
  140. }
  141. /**
  142. * GenericUDAFSumLong.
  143. *
  144. */
  145. public static class GenericUDAFSumLong extends GenericUDAFEvaluator {
  146. private PrimitiveObjectInspector inputOI;
  147. private LongWritable result;
  148. @Override
  149. public ObjectInspector init(Mode m, ObjectInspector[] parameters) throws HiveException {
  150. assert (parameters.length == 1);
  151. super.init(m, parameters);
  152. result = new LongWritable(0);
  153. inputOI = (PrimitiveObjectInspector) parameters[0];
  154. return PrimitiveObjectInspectorFactory.writableLongObjectInspector;
  155. }
  156. /** class for storing double sum value. */
  157. static class SumLongAgg implements AggregationBuffer {
  158. boolean empty;
  159. long sum;
  160. }
  161. @Override
  162. public AggregationBuffer getNewAggregationBuffer() throws HiveException {
  163. SumLongAgg result = new SumLongAgg();
  164. reset(result);
  165. return result;
  166. }
  167. @Override
  168. public void reset(AggregationBuffer agg) throws HiveException {
  169. SumLongAgg myagg = (SumLongAgg) agg;
  170. myagg.empty = true;
  171. myagg.sum = 0;
  172. }
  173. private boolean warned = false;
  174. @Override
  175. public void iterate(AggregationBuffer agg, Object[] parameters) throws HiveException {
  176. assert (parameters.length == 1);
  177. try {
  178. merge(agg, parameters[0]);
  179. } catch (NumberFormatException e) {
  180. if (!warned) {
  181. warned = true;
  182. LOG.warn(getClass().getSimpleName() + " "
  183. + StringUtils.stringifyException(e));
  184. }
  185. }
  186. }
  187. @Override
  188. public Object terminatePartial(AggregationBuffer agg) throws HiveException {
  189. return terminate(agg);
  190. }
  191. @Override
  192. public void merge(AggregationBuffer agg, Object partial) throws HiveException {
  193. if (partial != null) {
  194. SumLongAgg myagg = (SumLongAgg) agg;
  195. myagg.sum += PrimitiveObjectInspectorUtils.getLong(partial, inputOI);
  196. myagg.empty = false;
  197. }
  198. }
  199. @Override
  200. public Object terminate(AggregationBuffer agg) throws HiveException {
  201. SumLongAgg myagg = (SumLongAgg) agg;
  202. if (myagg.empty) {
  203. return null;
  204. }
  205. result.set(myagg.sum);
  206. return result;
  207. }
  208. }
  209. }