package brickhouse.udf.collect;
/**
* Copyright 2012 Klout, Inc
*
* Licensed 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.hadoop.hive.ql.exec.Description;
import org.apache.hadoop.hive.ql.exec.UDFArgumentException;
import org.apache.hadoop.hive.ql.metadata.HiveException;
import org.apache.hadoop.hive.ql.udf.generic.GenericUDTF;
import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector.Category;
import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspectorFactory;
import org.apache.hadoop.hive.serde2.objectinspector.StructObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.primitive.IntObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorFactory;
import java.util.ArrayList;
/**
* NumericRange is a UDTF for generating
* a range of integers, useful for accessing array elements during
* a lateral view.
*/
@Description(name = "numeric_range",
value = "_FUNC_(a,b,c) - Generates a range of integers from a to b incremented by c"
+ " or the elements of a map into multiple rows and columns ")
public class NumericRange extends GenericUDTF {
private IntObjectInspector startInspector = null;
private IntObjectInspector endInspector = null;
private IntObjectInspector incrementInspector = null;
@Override
public StructObjectInspector initialize(ObjectInspector[] argOIs)
throws UDFArgumentException {
if (argOIs.length == 0 || argOIs.length > 3) {
throw new UDFArgumentException("NumericRange takes 1 to 3 integer arguments");
}
for (ObjectInspector oi : argOIs) {
if (oi.getCategory() != Category.PRIMITIVE) {
throw new UDFArgumentException("NumericRange takes 1 to 3 integer arguments");
}
}
if (argOIs.length == 1) {
endInspector = (IntObjectInspector) argOIs[0];
} else if (argOIs.length == 2) {
startInspector = (IntObjectInspector) argOIs[0];
endInspector = (IntObjectInspector) argOIs[1];
} else if (argOIs.length == 3) {
startInspector = (IntObjectInspector) argOIs[0];
endInspector = (IntObjectInspector) argOIs[1];
incrementInspector = (IntObjectInspector) argOIs[2];
}
ArrayList<String> fieldNames = new ArrayList<String>();
fieldNames.add("n");
ArrayList<ObjectInspector> fieldOIs = new ArrayList<ObjectInspector>();
fieldOIs.add(PrimitiveObjectInspectorFactory.javaIntObjectInspector);
return ObjectInspectorFactory.getStandardStructObjectInspector(fieldNames,
fieldOIs);
}
private final Object[] forwardListObj = new Object[1];
@Override
public void process(Object[] args) throws HiveException {
int start = 0;
int nd = 0;
int incr = 1;
switch (args.length) {
case 1:
nd = endInspector.get(args[0]);
break;
case 2:
start = startInspector.get(args[0]);
nd = endInspector.get(args[1]);
break;
case 3:
start = startInspector.get(args[0]);
nd = endInspector.get(args[1]);
incr = incrementInspector.get(args[2]);
break;
}
for (int i = start; i < nd; i += incr) {
forwardListObj[0] = new Integer(i);
this.forward(forwardListObj);
}
}
@Override
public void close() throws HiveException {
}
}