use of org.apache.hadoop.hive.serde2.objectinspector.PrimitiveObjectInspector.PrimitiveCategory in project hive by apache.
the class FunctionRegistry method getMethodInternal.
/**
* Gets the closest matching method corresponding to the argument list from a
* list of methods.
*
* @param mlist
* The list of methods to inspect.
* @param exact
* Boolean to indicate whether this is an exact match or not.
* @param argumentsPassed
* The classes for the argument.
* @return The matching method.
*/
public static Method getMethodInternal(Class<?> udfClass, List<Method> mlist, boolean exact, List<TypeInfo> argumentsPassed) throws UDFArgumentException {
// result
List<Method> udfMethods = new ArrayList<Method>();
// The cost of the result
int leastConversionCost = Integer.MAX_VALUE;
for (Method m : mlist) {
List<TypeInfo> argumentsAccepted = TypeInfoUtils.getParameterTypeInfos(m, argumentsPassed.size());
if (argumentsAccepted == null) {
// null means the method does not accept number of arguments passed.
continue;
}
boolean match = (argumentsAccepted.size() == argumentsPassed.size());
int conversionCost = 0;
for (int i = 0; i < argumentsPassed.size() && match; i++) {
int cost = matchCost(argumentsPassed.get(i), argumentsAccepted.get(i), exact);
if (cost == -1) {
match = false;
} else {
conversionCost += cost;
}
}
if (LOG.isDebugEnabled()) {
LOG.debug("Method " + (match ? "did" : "didn't") + " match: passed = " + argumentsPassed + " accepted = " + argumentsAccepted + " method = " + m);
}
if (match) {
// Always choose the function with least implicit conversions.
if (conversionCost < leastConversionCost) {
udfMethods.clear();
udfMethods.add(m);
leastConversionCost = conversionCost;
// Found an exact match
if (leastConversionCost == 0) {
break;
}
} else if (conversionCost == leastConversionCost) {
// Ambiguous call: two methods with the same number of implicit
// conversions
udfMethods.add(m);
// Don't break! We might find a better match later.
} else {
// do nothing if implicitConversions > leastImplicitConversions
}
}
}
if (udfMethods.size() == 0) {
// No matching methods found
throw new NoMatchingMethodException(udfClass, argumentsPassed, mlist);
}
if (udfMethods.size() > 1) {
// First try selecting methods based on the type affinity of the arguments passed
// to the candidate method arguments.
filterMethodsByTypeAffinity(udfMethods, argumentsPassed);
}
if (udfMethods.size() > 1) {
// if the only difference is numeric types, pick the method
// with the smallest overall numeric type.
int lowestNumericType = Integer.MAX_VALUE;
boolean multiple = true;
Method candidate = null;
List<TypeInfo> referenceArguments = null;
for (Method m : udfMethods) {
int maxNumericType = 0;
List<TypeInfo> argumentsAccepted = TypeInfoUtils.getParameterTypeInfos(m, argumentsPassed.size());
if (referenceArguments == null) {
// keep the arguments for reference - we want all the non-numeric
// arguments to be the same
referenceArguments = argumentsAccepted;
}
Iterator<TypeInfo> referenceIterator = referenceArguments.iterator();
for (TypeInfo accepted : argumentsAccepted) {
TypeInfo reference = referenceIterator.next();
boolean acceptedIsPrimitive = false;
PrimitiveCategory acceptedPrimCat = PrimitiveCategory.UNKNOWN;
if (accepted.getCategory() == Category.PRIMITIVE) {
acceptedIsPrimitive = true;
acceptedPrimCat = ((PrimitiveTypeInfo) accepted).getPrimitiveCategory();
}
if (acceptedIsPrimitive && TypeInfoUtils.numericTypes.containsKey(acceptedPrimCat)) {
// We're looking for the udf with the smallest maximum numeric type.
int typeValue = TypeInfoUtils.numericTypes.get(acceptedPrimCat);
maxNumericType = typeValue > maxNumericType ? typeValue : maxNumericType;
} else if (!accepted.equals(reference)) {
// another. We give up at this point.
throw new AmbiguousMethodException(udfClass, argumentsPassed, mlist);
}
}
if (lowestNumericType > maxNumericType) {
multiple = false;
lowestNumericType = maxNumericType;
candidate = m;
} else if (maxNumericType == lowestNumericType) {
// multiple udfs with the same max type. Unless we find a lower one
// we'll give up.
multiple = true;
}
}
if (!multiple) {
return candidate;
} else {
throw new AmbiguousMethodException(udfClass, argumentsPassed, mlist);
}
}
return udfMethods.get(0);
}
use of org.apache.hadoop.hive.serde2.objectinspector.PrimitiveObjectInspector.PrimitiveCategory in project hive by apache.
the class MapJoinKey method isSupportedField.
public static boolean isSupportedField(TypeInfo typeInfo) {
// not supported
if (typeInfo.getCategory() != Category.PRIMITIVE)
return false;
PrimitiveTypeInfo primitiveTypeInfo = (PrimitiveTypeInfo) typeInfo;
PrimitiveCategory pc = primitiveTypeInfo.getPrimitiveCategory();
// not supported
if (!SUPPORTED_PRIMITIVES.contains(pc))
return false;
return true;
}
use of org.apache.hadoop.hive.serde2.objectinspector.PrimitiveObjectInspector.PrimitiveCategory in project hive by apache.
the class VectorizationContext method castConstantToLong.
private Long castConstantToLong(Object scalar, TypeInfo type, PrimitiveCategory integerPrimitiveCategory) throws HiveException {
if (null == scalar) {
return null;
}
PrimitiveTypeInfo ptinfo = (PrimitiveTypeInfo) type;
String typename = type.getTypeName();
switch(ptinfo.getPrimitiveCategory()) {
case FLOAT:
case DOUBLE:
case BYTE:
case SHORT:
case INT:
case LONG:
return ((Number) scalar).longValue();
case DECIMAL:
HiveDecimal decimalVal = (HiveDecimal) scalar;
switch(integerPrimitiveCategory) {
case BYTE:
if (!decimalVal.isByte()) {
// Accurate byte value cannot be obtained.
return null;
}
break;
case SHORT:
if (!decimalVal.isShort()) {
// Accurate short value cannot be obtained.
return null;
}
break;
case INT:
if (!decimalVal.isInt()) {
// Accurate int value cannot be obtained.
return null;
}
break;
case LONG:
if (!decimalVal.isLong()) {
// Accurate long value cannot be obtained.
return null;
}
break;
default:
throw new RuntimeException("Unexpected integer primitive type " + integerPrimitiveCategory);
}
// We only store longs in our LongColumnVector.
return decimalVal.longValue();
default:
throw new HiveException("Unsupported type " + typename + " for cast to Long");
}
}
use of org.apache.hadoop.hive.serde2.objectinspector.PrimitiveObjectInspector.PrimitiveCategory in project hive by apache.
the class VectorizationContext method getGenericUDFBridgeVectorExpression.
/**
* Invoke special handling for expressions that can't be vectorized by regular
* descriptor based lookup.
*/
private VectorExpression getGenericUDFBridgeVectorExpression(GenericUDFBridge udf, List<ExprNodeDesc> childExpr, VectorExpressionDescriptor.Mode mode, TypeInfo returnType) throws HiveException {
Class<? extends UDF> cl = udf.getUdfClass();
VectorExpression ve = null;
if (isCastToIntFamily(cl)) {
PrimitiveCategory integerPrimitiveCategory = getAnyIntegerPrimitiveCategoryFromUdfClass(cl);
ve = getCastToLongExpression(childExpr, integerPrimitiveCategory);
} else if (cl.equals(UDFToBoolean.class)) {
ve = getCastToBoolean(childExpr);
} else if (isCastToFloatFamily(cl)) {
ve = getCastToDoubleExpression(cl, childExpr, returnType);
} else if (cl.equals(UDFToString.class)) {
ve = getCastToString(childExpr, returnType);
}
if (ve == null && childExpr instanceof ExprNodeGenericFuncDesc) {
ve = getCustomUDFExpression((ExprNodeGenericFuncDesc) childExpr, mode);
}
return ve;
}
use of org.apache.hadoop.hive.serde2.objectinspector.PrimitiveObjectInspector.PrimitiveCategory in project hive by apache.
the class VectorSerializeRow method init.
public void init(List<String> typeNames, int[] columnMap) throws HiveException {
final int size = typeNames.size();
categories = new Category[size];
primitiveCategories = new PrimitiveCategory[size];
outputColumnNums = Arrays.copyOf(columnMap, size);
TypeInfo typeInfo;
for (int i = 0; i < size; i++) {
typeInfo = TypeInfoUtils.getTypeInfoFromTypeString(typeNames.get(i));
categories[i] = typeInfo.getCategory();
if (categories[i] == Category.PRIMITIVE) {
primitiveCategories[i] = ((PrimitiveTypeInfo) typeInfo).getPrimitiveCategory();
}
}
}
Aggregations