PageRenderTime 52ms CodeModel.GetById 10ms app.highlight 37ms 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
  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 */
 18package org.apache.hadoop.hive.ql.udf.generic;
 19
 20import org.apache.commons.logging.Log;
 21import org.apache.commons.logging.LogFactory;
 22import org.apache.hadoop.hive.ql.exec.Description;
 23import org.apache.hadoop.hive.ql.exec.UDFArgumentTypeException;
 24import org.apache.hadoop.hive.ql.metadata.HiveException;
 25import org.apache.hadoop.hive.ql.parse.SemanticException;
 26import org.apache.hadoop.hive.serde2.io.DoubleWritable;
 27import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector;
 28import org.apache.hadoop.hive.serde2.objectinspector.PrimitiveObjectInspector;
 29import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorFactory;
 30import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorUtils;
 31import org.apache.hadoop.hive.serde2.typeinfo.PrimitiveTypeInfo;
 32import org.apache.hadoop.hive.serde2.typeinfo.TypeInfo;
 33import org.apache.hadoop.io.LongWritable;
 34import org.apache.hadoop.util.StringUtils;
 35
 36/**
 37 * GenericUDAFSum.
 38 *
 39 */
 40@Description(name = "sum", value = "_FUNC_(x) - Returns the sum of a set of numbers")
 41public class GenericUDAFSum extends AbstractGenericUDAFResolver {
 42
 43  static final Log LOG = LogFactory.getLog(GenericUDAFSum.class.getName());
 44
 45  @Override
 46  public GenericUDAFEvaluator getEvaluator(TypeInfo[] parameters)
 47    throws SemanticException {
 48    if (parameters.length != 1) {
 49      throw new UDFArgumentTypeException(parameters.length - 1,
 50          "Exactly one argument is expected.");
 51    }
 52
 53    if (parameters[0].getCategory() != ObjectInspector.Category.PRIMITIVE) {
 54      throw new UDFArgumentTypeException(0,
 55          "Only primitive type arguments are accepted but "
 56          + parameters[0].getTypeName() + " is passed.");
 57    }
 58    switch (((PrimitiveTypeInfo) parameters[0]).getPrimitiveCategory()) {
 59    case BYTE:
 60    case SHORT:
 61    case INT:
 62    case LONG:
 63      return new GenericUDAFSumLong();
 64    case FLOAT:
 65    case DOUBLE:
 66    case STRING:
 67      return new GenericUDAFSumDouble();
 68    case BOOLEAN:
 69    default:
 70      throw new UDFArgumentTypeException(0,
 71          "Only numeric or string type arguments are accepted but "
 72          + parameters[0].getTypeName() + " is passed.");
 73    }
 74  }
 75
 76  /**
 77   * GenericUDAFSumDouble.
 78   *
 79   */
 80  public static class GenericUDAFSumDouble extends GenericUDAFEvaluator {
 81    private PrimitiveObjectInspector inputOI;
 82    private DoubleWritable result;
 83
 84    @Override
 85    public ObjectInspector init(Mode m, ObjectInspector[] parameters) throws HiveException {
 86      assert (parameters.length == 1);
 87      super.init(m, parameters);
 88      result = new DoubleWritable(0);
 89      inputOI = (PrimitiveObjectInspector) parameters[0];
 90      return PrimitiveObjectInspectorFactory.writableDoubleObjectInspector;
 91    }
 92
 93    /** class for storing double sum value. */
 94    static class SumDoubleAgg implements AggregationBuffer {
 95      boolean empty;
 96      double sum;
 97    }
 98
 99    @Override
100    public AggregationBuffer getNewAggregationBuffer() throws HiveException {
101      SumDoubleAgg result = new SumDoubleAgg();
102      reset(result);
103      return result;
104    }
105
106    @Override
107    public void reset(AggregationBuffer agg) throws HiveException {
108      SumDoubleAgg myagg = (SumDoubleAgg) agg;
109      myagg.empty = true;
110      myagg.sum = 0;
111    }
112
113    boolean warned = false;
114
115    @Override
116    public void iterate(AggregationBuffer agg, Object[] parameters) throws HiveException {
117      assert (parameters.length == 1);
118      try {
119        merge(agg, parameters[0]);
120      } catch (NumberFormatException e) {
121        if (!warned) {
122          warned = true;
123          LOG.warn(getClass().getSimpleName() + " "
124              + StringUtils.stringifyException(e));
125          LOG
126              .warn(getClass().getSimpleName()
127              + " ignoring similar exceptions.");
128        }
129      }
130    }
131
132    @Override
133    public Object terminatePartial(AggregationBuffer agg) throws HiveException {
134      return terminate(agg);
135    }
136
137    @Override
138    public void merge(AggregationBuffer agg, Object partial) throws HiveException {
139      if (partial != null) {
140        SumDoubleAgg myagg = (SumDoubleAgg) agg;
141        myagg.empty = false;
142        myagg.sum += PrimitiveObjectInspectorUtils.getDouble(partial, inputOI);
143      }
144    }
145
146    @Override
147    public Object terminate(AggregationBuffer agg) throws HiveException {
148      SumDoubleAgg myagg = (SumDoubleAgg) agg;
149      if (myagg.empty) {
150        return null;
151      }
152      result.set(myagg.sum);
153      return result;
154    }
155
156  }
157
158  /**
159   * GenericUDAFSumLong.
160   *
161   */
162  public static class GenericUDAFSumLong extends GenericUDAFEvaluator {
163    private PrimitiveObjectInspector inputOI;
164    private LongWritable result;
165
166    @Override
167    public ObjectInspector init(Mode m, ObjectInspector[] parameters) throws HiveException {
168      assert (parameters.length == 1);
169      super.init(m, parameters);
170      result = new LongWritable(0);
171      inputOI = (PrimitiveObjectInspector) parameters[0];
172      return PrimitiveObjectInspectorFactory.writableLongObjectInspector;
173    }
174
175    /** class for storing double sum value. */
176    static class SumLongAgg implements AggregationBuffer {
177      boolean empty;
178      long sum;
179    }
180
181    @Override
182    public AggregationBuffer getNewAggregationBuffer() throws HiveException {
183      SumLongAgg result = new SumLongAgg();
184      reset(result);
185      return result;
186    }
187
188    @Override
189    public void reset(AggregationBuffer agg) throws HiveException {
190      SumLongAgg myagg = (SumLongAgg) agg;
191      myagg.empty = true;
192      myagg.sum = 0;
193    }
194
195    private boolean warned = false;
196
197    @Override
198    public void iterate(AggregationBuffer agg, Object[] parameters) throws HiveException {
199      assert (parameters.length == 1);
200      try {
201        merge(agg, parameters[0]);
202      } catch (NumberFormatException e) {
203        if (!warned) {
204          warned = true;
205          LOG.warn(getClass().getSimpleName() + " "
206              + StringUtils.stringifyException(e));
207        }
208      }
209    }
210
211    @Override
212    public Object terminatePartial(AggregationBuffer agg) throws HiveException {
213      return terminate(agg);
214    }
215
216    @Override
217    public void merge(AggregationBuffer agg, Object partial) throws HiveException {
218      if (partial != null) {
219        SumLongAgg myagg = (SumLongAgg) agg;
220        myagg.sum += PrimitiveObjectInspectorUtils.getLong(partial, inputOI);
221        myagg.empty = false;
222      }
223    }
224
225    @Override
226    public Object terminate(AggregationBuffer agg) throws HiveException {
227      SumLongAgg myagg = (SumLongAgg) agg;
228      if (myagg.empty) {
229        return null;
230      }
231      result.set(myagg.sum);
232      return result;
233    }
234
235  }
236
237}