package com.facebook.hive.udf;
import org.apache.hadoop.hive.ql.exec.Description;
import org.apache.hadoop.hive.ql.exec.UDFArgumentLengthException;
import org.apache.hadoop.hive.ql.metadata.HiveException;
import org.apache.hadoop.hive.ql.parse.SemanticException;
import org.apache.hadoop.hive.ql.udf.generic.AbstractGenericUDAFResolver;
import org.apache.hadoop.hive.ql.udf.generic.GenericUDAFEvaluator;
import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspectorUtils;
import org.apache.hadoop.hive.serde2.typeinfo.TypeInfo;
/**
* For a given grouping, return one array from the grouping. Good when you
* want to associate each key with an arbitrary value, or for when you are
* certain that every item in the grouping is the same.
*
* This replaces UDAFFirst.
*
* Note that this function does not guarantee that you will get the first
* item, only that you will get one of the items.
*
* TODO: Make this work with Hive STRUCT types.
*/
@Description(name = "chooseone", value="_FUNC_(value) - Return an arbitrary value from the group")
public final class UDAFChooseOne extends AbstractGenericUDAFResolver {
public GenericUDAFEvaluator getEvaluator(TypeInfo[] parameters) throws SemanticException {
if (parameters.length != 1) {
throw new UDFArgumentLengthException("Only one paramter expected, but you provided " + parameters.length);
}
return new Evaluator();
}
public static class Evaluator extends GenericUDAFEvaluator {
ObjectInspector inputOI;
@Override
public ObjectInspector init(Mode m, ObjectInspector[] parameters) throws HiveException {
super.init(m, parameters);
inputOI = parameters[0];
return ObjectInspectorUtils.getStandardObjectInspector(inputOI);
}
static class State implements AggregationBuffer {
Object state = null;
}
@Override
public AggregationBuffer getNewAggregationBuffer() throws HiveException {
return new State();
}
@Override
public void iterate(AggregationBuffer agg, Object[] input) throws HiveException {
State s = (State) agg;
if (s.state == null) {
s.state = ObjectInspectorUtils.copyToStandardObject(input[0], inputOI);
}
}
@Override
public void merge(AggregationBuffer agg, Object partial) throws HiveException {
State s = (State) agg;
if (s.state == null) {
s.state = ObjectInspectorUtils.copyToStandardObject(partial, inputOI);
}
}
@Override
public void reset(AggregationBuffer agg) {
State s = (State) agg;
s.state = null;
}
@Override
public Object terminate(AggregationBuffer agg) throws HiveException {
State s = (State) agg;
return s.state;
}
@Override
public Object terminatePartial(AggregationBuffer agg) throws HiveException {
State s = (State) agg;
return s.state;
}
}
}