public ExprNodeGenericFuncEvaluator(ExprNodeGenericFuncDesc expr) { this.expr = expr; children = new ExprNodeEvaluator[expr.getChildExprs().size()]; isEager = false; for (int i = 0; i < children.length; i++) { ExprNodeDesc child = expr.getChildExprs().get(i); ExprNodeEvaluator nodeEvaluator = ExprNodeEvaluatorFactory.get(child); children[i] = nodeEvaluator; // If we have eager evaluators anywhere below us, then we are eager too. if (nodeEvaluator instanceof ExprNodeGenericFuncEvaluator) { if (((ExprNodeGenericFuncEvaluator) nodeEvaluator).isEager) { isEager = true; } // Base case: we are eager if a child is stateful GenericUDF childUDF = ((ExprNodeGenericFuncDesc) child).getGenericUDF(); if (FunctionRegistry.isStateful(childUDF)) { isEager = true; } } } deferredChildren = new GenericUDF.DeferredObject[expr.getChildExprs().size()]; for (int i = 0; i < deferredChildren.length; i++) { if (isEager) { deferredChildren[i] = new EagerExprObject(children[i]); } else { deferredChildren[i] = new DeferredExprObject(children[i]); } } }
// should be called after session registry is checked private FunctionInfo registerToSessionRegistry(String qualifiedName, FunctionInfo function) { FunctionInfo ret = null; ClassLoader prev = Utilities.getSessionSpecifiedClassLoader(); try { // Found UDF in metastore - now add it to the function registry // At this point we should add any relevant jars that would be needed for the UDf. FunctionResource[] resources = function.getResources(); try { FunctionTask.addFunctionResources(resources); } catch (Exception e) { LOG.error("Unable to load resources for " + qualifiedName + ":" + e, e); return null; } ClassLoader loader = Utilities.getSessionSpecifiedClassLoader(); Class<?> udfClass = Class.forName(function.getClassName(), true, loader); ret = FunctionRegistry.registerTemporaryUDF(qualifiedName, udfClass, resources); if (ret == null) { LOG.error(function.getClassName() + " is not a valid UDF class and was not registered."); } if (SessionState.get().isHiveServerQuery()) { SessionState.getRegistryForWrite().addToUDFLoaders(loader); } } catch (ClassNotFoundException e) { // Lookup of UDf class failed LOG.error("Unable to load UDF class: " + e); Utilities.restoreSessionSpecifiedClassLoader(prev); } function.shareStateWith(ret); return ret; }
@Override public boolean isDeterministic() { boolean result = FunctionRegistry.isDeterministic(genericUDF); for (ExprNodeEvaluator child : children) { result = result && child.isDeterministic(); } return result; }
/** * Gets the evaluator class for the UDAF given the parameter types. * * @param argClasses The list of the parameter types. */ public Class<? extends UDAFEvaluator> getEvaluatorClass(List<TypeInfo> argClasses) throws UDFArgumentException { ArrayList<Class<? extends UDAFEvaluator>> classList = new ArrayList<Class<? extends UDAFEvaluator>>(); // Add all the public member classes that implement an evaluator for (Class<?> enclClass : udafClass.getClasses()) { if (UDAFEvaluator.class.isAssignableFrom(enclClass)) { classList.add((Class<? extends UDAFEvaluator>) enclClass); } } // Next we locate all the iterate methods for each of these classes. ArrayList<Method> mList = new ArrayList<Method>(); ArrayList<Class<? extends UDAFEvaluator>> cList = new ArrayList<Class<? extends UDAFEvaluator>>(); for (Class<? extends UDAFEvaluator> evaluator : classList) { for (Method m : evaluator.getMethods()) { if (m.getName().equalsIgnoreCase("iterate")) { mList.add(m); cList.add(evaluator); } } } Method m = FunctionRegistry.getMethodInternal(udafClass, mList, false, argClasses); // Find the class that has this method. // Note that Method.getDeclaringClass() may not work here because the method // can be inherited from a base class. int found = -1; for (int i = 0; i < mList.size(); i++) { if (mList.get(i) == m) { if (found == -1) { found = i; } else { throw new AmbiguousMethodException(udafClass, null, null); } } } assert (found != -1); return cList.get(found); }
@Override public boolean isAggregationFunction(QualifiedName name) { return functions.isAggregationFunction(name); }
@Override public FunctionInfo getFunction(Signature handle) { return functions.get(handle); }
@Override public FunctionInfo getFunction(QualifiedName name, List<Type> parameterTypes) { return functions.get(name, parameterTypes); }
@Override public void addFunctions(List<FunctionInfo> functionInfos) { functions.addFunctions(functionInfos); }
@Override public List<FunctionInfo> listFunctions() { return functions.list(); }