blob: df06a839c822cc25e9d8c48e09f6c42a2fbe1f83 [file] [log] [blame]
/*
* 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.fn.hive;
import org.apache.hadoop.hive.common.type.HiveChar;
import org.apache.hadoop.hive.common.type.HiveDecimal;
import org.apache.hadoop.hive.common.type.HiveVarchar;
import org.apache.hadoop.hive.ql.exec.Description;
import org.apache.hadoop.hive.ql.exec.UDFArgumentException;
import org.apache.hadoop.hive.ql.exec.UDFArgumentLengthException;
import org.apache.hadoop.hive.ql.metadata.HiveException;
import org.apache.hadoop.hive.ql.udf.generic.GenericUDF;
import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector.Category;
import org.apache.hadoop.hive.serde2.objectinspector.PrimitiveObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.PrimitiveObjectInspector.PrimitiveCategory;
import org.apache.hadoop.hive.serde2.objectinspector.primitive.BinaryObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.primitive.BooleanObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.primitive.ByteObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.primitive.DateObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.primitive.DoubleObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.primitive.FloatObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.primitive.HiveCharObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.primitive.HiveDecimalObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.primitive.HiveVarcharObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.primitive.IntObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.primitive.LongObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorFactory;
import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorUtils;
import org.apache.hadoop.hive.serde2.objectinspector.primitive.ShortObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.primitive.StringObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.primitive.TimestampObjectInspector;
/**
* Contains test Hive UDF that take a particular data type and return the same data type and value.
* These test UDFs exercise the code paths in Drill ObjectInspectors and parsing the return value from Hive UDF
* for all supported data types in Hive UDF.
*/
public class HiveTestUDFImpls {
public static abstract class GenericUDFTestBase extends GenericUDF {
protected final String udfName;
protected final PrimitiveCategory inputType;
protected final PrimitiveCategory outputType;
protected ObjectInspector argumentOI;
public GenericUDFTestBase(String udfName, PrimitiveCategory type) {
this(udfName, type, type);
}
public GenericUDFTestBase(String udfName, PrimitiveCategory inputType, PrimitiveCategory outputType) {
this.udfName = udfName;
this.inputType = inputType;
this.outputType = outputType;
}
@Override
public ObjectInspector initialize(ObjectInspector[] arguments) throws UDFArgumentException {
if (arguments.length != 1) {
throw new UDFArgumentLengthException(String.format("%s needs 1 argument, got %d", udfName, arguments.length));
}
if (arguments[0].getCategory() != Category.PRIMITIVE ||
((PrimitiveObjectInspector) arguments[0]).getPrimitiveCategory() != inputType) {
String actual = arguments[0].getCategory() + (arguments[0].getCategory() == Category.PRIMITIVE ?
"[" + ((PrimitiveObjectInspector) arguments[0]).getPrimitiveCategory() + "]" : "");
throw new UDFArgumentException(
String.format("%s only takes primitive type %s, got %s", udfName, inputType, actual));
}
argumentOI = arguments[0];
return PrimitiveObjectInspectorFactory.getPrimitiveJavaObjectInspector(outputType);
}
@Override
public String getDisplayString(String[] children) {
StringBuilder sb = new StringBuilder();
sb.append(udfName);
sb.append("(");
if (children.length > 0) {
sb.append(children[0]);
for (int i = 1; i < children.length; i++) {
sb.append(",");
sb.append(children[i]);
}
}
sb.append(")");
return sb.toString();
}
@Override
public Object evaluate(DeferredObject[] arguments) throws HiveException {
if (arguments[0] == null || arguments[0].get() == null) {
return null;
}
Object input = arguments[0].get();
switch(inputType) {
case BOOLEAN:
return ((BooleanObjectInspector)argumentOI).get(input) ? Boolean.TRUE : Boolean.FALSE;
case BYTE:
return Byte.valueOf(((ByteObjectInspector)argumentOI).get(input));
case SHORT:
return Short.valueOf(((ShortObjectInspector)argumentOI).get(input));
case INT:
return Integer.valueOf(((IntObjectInspector)argumentOI).get(input));
case LONG:
return Long.valueOf(((LongObjectInspector)argumentOI).get(input));
case FLOAT:
return Float.valueOf(((FloatObjectInspector)argumentOI).get(input));
case DOUBLE:
return Double.valueOf(((DoubleObjectInspector)argumentOI).get(input));
case STRING:
return PrimitiveObjectInspectorUtils.getString(input, (StringObjectInspector)argumentOI);
case BINARY:
return PrimitiveObjectInspectorUtils.getBinary(input, (BinaryObjectInspector) argumentOI).getBytes();
case VARCHAR:
if (outputType == PrimitiveCategory.CHAR) {
HiveVarchar hiveVarchar = PrimitiveObjectInspectorUtils.getHiveVarchar(input, (HiveVarcharObjectInspector) argumentOI);
return new HiveChar(hiveVarchar.getValue(), HiveChar.MAX_CHAR_LENGTH);
} else {
return PrimitiveObjectInspectorUtils.getHiveVarchar(input, (HiveVarcharObjectInspector)argumentOI);
}
case CHAR:
return PrimitiveObjectInspectorUtils.getHiveChar(input, (HiveCharObjectInspector) argumentOI);
case DATE:
return PrimitiveObjectInspectorUtils.getDate(input, (DateObjectInspector) argumentOI);
case TIMESTAMP:
return PrimitiveObjectInspectorUtils.getTimestamp(input, (TimestampObjectInspector) argumentOI);
case DECIMAL:
// return type is a HiveVarchar
HiveDecimal decimalValue =
PrimitiveObjectInspectorUtils.getHiveDecimal(input, (HiveDecimalObjectInspector) argumentOI);
return new HiveVarchar(decimalValue.toString(), HiveVarchar.MAX_VARCHAR_LENGTH);
}
throw new UnsupportedOperationException(String.format("Unexpected input type '%s' in Test UDF", inputType));
}
}
@Description(name = "testHiveUDFBOOLEAN", value = "_FUNC_(BOOLEAN) - Tests boolean data as input and output")
public static class GenericUDFTestBOOLEAN extends GenericUDFTestBase {
public GenericUDFTestBOOLEAN() {
super("testHiveUDFBOOLEAN", PrimitiveCategory.BOOLEAN);
}
}
// TODO(DRILL-2470) - re-enable the test case for this function in TestSampleHiveUDFs
@Description(name = "testHiveUDFBYTE", value = "_FUNC_(BYTE) - Tests byte data as input and output")
public static class GenericUDFTestBYTE extends GenericUDFTestBase {
public GenericUDFTestBYTE() {
super("testHiveUDFBYTE", PrimitiveCategory.BYTE);
}
}
// TODO(DRILL-2470) - re-enable the test case for this function in TestSampleHiveUDFs
@Description(name = "testHiveUDFSHORT", value = "_FUNC_(SHORT) - Tests short data as input and output")
public static class GenericUDFTestSHORT extends GenericUDFTestBase {
public GenericUDFTestSHORT() {
super("testHiveUDFSHORT", PrimitiveCategory.SHORT);
}
}
@Description(name = "testHiveUDFINT", value = "_FUNC_(INT) - Tests int data as input and output")
public static class GenericUDFTestINT extends GenericUDFTestBase {
public GenericUDFTestINT() {
super("testHiveUDFINT", PrimitiveCategory.INT);
}
}
@Description(name = "testHiveUDFLONG", value = "_FUNC_(LONG) - Tests long data as input and output")
public static class GenericUDFTestLONG extends GenericUDFTestBase {
public GenericUDFTestLONG() {
super("testHiveUDFLONG", PrimitiveCategory.LONG);
}
}
@Description(name = "testHiveUDFFLOAT", value = "_FUNC_(FLOAT) - Tests float data as input and output")
public static class GenericUDFTestFLOAT extends GenericUDFTestBase {
public GenericUDFTestFLOAT() {
super("testHiveUDFFLOAT", PrimitiveCategory.FLOAT);
}
}
@Description(name = "testHiveUDFDOUBLE", value = "_FUNC_(DOUBLE) - Tests double data as input and output")
public static class GenericUDFTestDOUBLE extends GenericUDFTestBase {
public GenericUDFTestDOUBLE() {
super("testHiveUDFDOUBLE", PrimitiveCategory.DOUBLE);
}
}
@Description(name = "testHiveUDFVARCHAR", value = "_FUNC_(VARCHAR) - Tests varchar data as input and output")
public static class GenericUDFTestVARCHAR extends GenericUDFTestBase {
public GenericUDFTestVARCHAR() {
super("testHiveUDFVARCHAR", PrimitiveCategory.VARCHAR);
}
}
@Description(name = "testHiveUDFCHAR", value = "_FUNC_(VARCHAR) - Tests varchar data as input and char data as output")
public static class GenericUDFTestCHAR extends GenericUDFTestBase {
public GenericUDFTestCHAR() {
super("testHiveUDFCHAR", PrimitiveCategory.VARCHAR, PrimitiveCategory.CHAR);
}
}
@Description(name = "testHiveUDFSTRING", value = "_FUNC_(STRING) - Tests string data as input and output")
public static class GenericUDFTestSTRING extends GenericUDFTestBase {
public GenericUDFTestSTRING() {
super("testHiveUDFSTRING", PrimitiveCategory.STRING);
}
}
@Description(name = "testHiveUDFBINARY", value = "_FUNC_(BINARY) - Tests binary data as input and output")
public static class GenericUDFTestBINARY extends GenericUDFTestBase {
public GenericUDFTestBINARY() {
super("testHiveUDFBINARY", PrimitiveCategory.BINARY);
}
}
@Description(name = "testHiveUDFTIMESTAMP", value = "_FUNC_(TIMESTAMP) - Tests timestamp data as input and output")
public static class GenericUDFTestTIMESTAMP extends GenericUDFTestBase {
public GenericUDFTestTIMESTAMP() {
super("testHiveUDFTIMESTAMP", PrimitiveCategory.TIMESTAMP);
}
}
@Description(name = "testHiveUDFDATE", value = "_FUNC_(DATE) - Tests date data as input and output")
public static class GenericUDFTestDATE extends GenericUDFTestBase {
public GenericUDFTestDATE() {
super("testHiveUDFDATE", PrimitiveCategory.DATE);
}
}
@Description(name = "testHiveUDFDECIMAL", value = "_FUNC_(DECIMAL) - Tests decimal data as input and output")
public static class GenericUDFTestDECIMAL extends GenericUDFTestBase {
public GenericUDFTestDECIMAL() {
super("testHiveUDFDECIMAL", PrimitiveCategory.DECIMAL, PrimitiveCategory.VARCHAR);
}
}
}