// traversing origin, find ExprNodeDesc in sources and replaces it with ExprNodeDesc // in targets having same index. // return null if failed to find public static ExprNodeDesc replace( ExprNodeDesc origin, List<ExprNodeDesc> sources, List<ExprNodeDesc> targets) { int index = indexOf(origin, sources); if (index >= 0) { return targets.get(index); } // encountered column or field which cannot be found in sources if (origin instanceof ExprNodeColumnDesc || origin instanceof ExprNodeFieldDesc) { return null; } // for ExprNodeGenericFuncDesc, it should be deterministic and stateless if (origin instanceof ExprNodeGenericFuncDesc) { ExprNodeGenericFuncDesc func = (ExprNodeGenericFuncDesc) origin; if (!FunctionRegistry.isDeterministic(func.getGenericUDF()) || FunctionRegistry.isStateful(func.getGenericUDF())) { return null; } List<ExprNodeDesc> children = new ArrayList<ExprNodeDesc>(); for (int i = 0; i < origin.getChildren().size(); i++) { ExprNodeDesc child = replace(origin.getChildren().get(i), sources, targets); if (child == null) { return null; } children.add(child); } // duplicate function with possibly replaced children ExprNodeGenericFuncDesc clone = (ExprNodeGenericFuncDesc) func.clone(); clone.setChildren(children); return clone; } // constant or null, just return it return origin; }
private ObjectInspector initExprNodeEvaluator( ExprNodeEvaluator exprEval, ExprNodeDesc exprNode, ShapeDetails inpShape) throws HiveException { ObjectInspector outOI; outOI = exprEval.initialize(inpShape.getOI()); /* * if there are any LeadLag functions in this Expression Tree: - setup a * duplicate Evaluator for the 1st arg of the LLFuncDesc - initialize it * using the InputInfo provided for this Expr tree - set the duplicate * evaluator on the LLUDF instance. */ List<ExprNodeGenericFuncDesc> llFuncExprs = llInfo.getLLFuncExprsInTopExpr(exprNode); if (llFuncExprs != null) { for (ExprNodeGenericFuncDesc llFuncExpr : llFuncExprs) { ExprNodeDesc firstArg = llFuncExpr.getChildren().get(0); ExprNodeEvaluator dupExprEval = WindowingExprNodeEvaluatorFactory.get(llInfo, firstArg); dupExprEval.initialize(inpShape.getOI()); GenericUDFLeadLag llFn = (GenericUDFLeadLag) llFuncExpr.getGenericUDF(); llFn.setExprEvaluator(dupExprEval); } } return outOI; }
public static boolean isConstant(ExprNodeDesc value) { if (value instanceof ExprNodeConstantDesc) { return true; } if (value instanceof ExprNodeGenericFuncDesc) { ExprNodeGenericFuncDesc func = (ExprNodeGenericFuncDesc) value; if (!FunctionRegistry.isDeterministic(func.getGenericUDF())) { return false; } for (ExprNodeDesc child : func.getChildren()) { if (!isConstant(child)) { return false; } } return true; } return false; }
private static ExprNodeConstantDesc foldConstant(ExprNodeGenericFuncDesc func) { GenericUDF udf = func.getGenericUDF(); if (!FunctionRegistry.isDeterministic(udf) || FunctionRegistry.isStateful(udf)) { return null; } try { // If the UDF depends on any external resources, we can't fold because the // resources may not be available at compile time. if (udf instanceof GenericUDFBridge) { UDF internal = ReflectionUtils.newInstance(((GenericUDFBridge) udf).getUdfClass(), null); if (internal.getRequiredFiles() != null || internal.getRequiredJars() != null) { return null; } } else { if (udf.getRequiredFiles() != null || udf.getRequiredJars() != null) { return null; } } if (func.getChildren() != null) { for (ExprNodeDesc child : func.getChildren()) { if (child instanceof ExprNodeConstantDesc) { continue; } if (child instanceof ExprNodeGenericFuncDesc) { if (foldConstant((ExprNodeGenericFuncDesc) child) != null) { continue; } } return null; } } ExprNodeEvaluator evaluator = ExprNodeEvaluatorFactory.get(func); ObjectInspector output = evaluator.initialize(null); Object constant = evaluator.evaluate(null); Object java = ObjectInspectorUtils.copyToStandardJavaObject(constant, output); return new ExprNodeConstantDesc(java); } catch (Exception e) { return null; } }