*/
public static exprNodeDesc getFuncExprNodeDesc(String udfName, List<exprNodeDesc> children) {
// Find the corresponding method
ArrayList<Class<?>> argumentClasses = new ArrayList<Class<?>>(children.size());
for(int i=0; i<children.size(); i++) {
exprNodeDesc child = children.get(i);
assert(child != null);
TypeInfo childTypeInfo = child.getTypeInfo();
assert(childTypeInfo != null);
// Note: we don't pass the element types of MAP/LIST to UDF.
// That will work for null test and size but not other more complex functionalities like list slice etc.
// For those more complex functionalities, we plan to have a ComplexUDF interface which has an evaluate
// method that accepts a list of objects and a list of objectinspectors.
switch (childTypeInfo.getCategory()) {
case PRIMITIVE: {
argumentClasses.add(childTypeInfo.getPrimitiveClass());
break;
}
case MAP: {
argumentClasses.add(Map.class);
break;
}
case LIST: {
argumentClasses.add(List.class);
break;
}
case STRUCT: {
argumentClasses.add(Object.class);
break;
}
default: {
// should never happen
assert(false);
}
}
}
Method udfMethod = FunctionRegistry.getUDFMethod(udfName, argumentClasses);
if (udfMethod == null) return null;
ArrayList<exprNodeDesc> ch = new ArrayList<exprNodeDesc>();
Class<?>[] pTypes = udfMethod.getParameterTypes();
for (int i = 0; i < children.size(); i++)
{
exprNodeDesc desc = children.get(i);
Class<?> pType = ObjectInspectorUtils.generalizePrimitive(pTypes[i]);
if (desc instanceof exprNodeNullDesc) {
exprNodeConstantDesc newCh = new exprNodeConstantDesc(TypeInfoFactory.getPrimitiveTypeInfo(pType), null);
ch.add(newCh);
} else if (pType.isAssignableFrom(argumentClasses.get(i))) {