// 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; }
/** return true if predicate is already included in source */ public static boolean containsPredicate(ExprNodeDesc source, ExprNodeDesc predicate) { if (source.isSame(predicate)) { return true; } if (FunctionRegistry.isOpAnd(source)) { if (containsPredicate(source.getChildren().get(0), predicate) || containsPredicate(source.getChildren().get(1), predicate)) { return true; } } return false; }
/** Return false if the expression has any non deterministic function */ public static boolean isDeterministic(ExprNodeDesc desc) { if (desc instanceof ExprNodeGenericFuncDesc) { if (!FunctionRegistry.isDeterministic(((ExprNodeGenericFuncDesc) desc).getGenericUDF())) { return false; } } if (desc.getChildren() != null) { for (ExprNodeDesc child : desc.getChildren()) { if (!isDeterministic(child)) { return false; } } } return true; }
/** bind two predicates by AND op */ public static ExprNodeGenericFuncDesc mergePredicates(ExprNodeDesc prev, ExprNodeDesc next) { final List<ExprNodeDesc> children = new ArrayList<ExprNodeDesc>(2); if (FunctionRegistry.isOpAnd(prev)) { children.addAll(prev.getChildren()); } else { children.add(prev); } if (FunctionRegistry.isOpAnd(next)) { children.addAll(next.getChildren()); } else { children.add(next); } return new ExprNodeGenericFuncDesc( TypeInfoFactory.booleanTypeInfo, FunctionRegistry.getGenericUDFForAnd(), children); }
// Check if ExprNodeColumnDesc is wrapped in expr. // If so, peel off. Otherwise return itself. private ExprNodeDesc getColumnExpr(ExprNodeDesc expr) { if (expr instanceof ExprNodeColumnDesc) { return expr; } ExprNodeGenericFuncDesc funcDesc = null; if (expr instanceof ExprNodeGenericFuncDesc) { funcDesc = (ExprNodeGenericFuncDesc) expr; } if (null == funcDesc) { return expr; } GenericUDF udf = funcDesc.getGenericUDF(); // check if its a simple cast expression. if ((udf instanceof GenericUDFBridge || udf instanceof GenericUDFToBinary || udf instanceof GenericUDFToChar || udf instanceof GenericUDFToVarchar || udf instanceof GenericUDFToDecimal || udf instanceof GenericUDFToDate || udf instanceof GenericUDFToUnixTimeStamp || udf instanceof GenericUDFToUtcTimestamp) && funcDesc.getChildren().size() == 1 && funcDesc.getChildren().get(0) instanceof ExprNodeColumnDesc) { return expr.getChildren().get(0); } return expr; }
/** * Get Map of ExprNodeColumnDesc HashCode to ExprNodeColumnDesc. * * @param exprDesc * @param hashCodeToColumnDescMap Assumption: If two ExprNodeColumnDesc have same hash code then * they are logically referring to same projection */ public static void getExprNodeColumnDesc( ExprNodeDesc exprDesc, Map<Integer, ExprNodeDesc> hashCodeToColumnDescMap) { if (exprDesc instanceof ExprNodeColumnDesc) { hashCodeToColumnDescMap.put(exprDesc.hashCode(), exprDesc); } else if (exprDesc instanceof ExprNodeColumnListDesc) { for (ExprNodeDesc child : exprDesc.getChildren()) { getExprNodeColumnDesc(child, hashCodeToColumnDescMap); } } else if (exprDesc instanceof ExprNodeGenericFuncDesc) { for (ExprNodeDesc child : exprDesc.getChildren()) { getExprNodeColumnDesc(child, hashCodeToColumnDescMap); } } else if (exprDesc instanceof ExprNodeFieldDesc) { getExprNodeColumnDesc(((ExprNodeFieldDesc) exprDesc).getDesc(), hashCodeToColumnDescMap); } }
void dumpFilterExpr(ExprNodeDesc expr) { if (expr == null) return; List<ExprNodeDesc> children = expr.getChildren(); if (children != null && children.size() > 0) { for (ExprNodeDesc e : children) { dumpFilterExpr(e); } } }
public static String extractColName(ExprNodeDesc root) { if (root instanceof ExprNodeColumnDesc) { return ((ExprNodeColumnDesc) root).getColumn(); } else { if (root.getChildren() == null) { return null; } String column = null; for (ExprNodeDesc d : root.getChildren()) { String candidate = extractColName(d); if (column != null && candidate != null) { return null; } else if (candidate != null) { column = candidate; } } return column; } }
/** Recommend name for the expression */ public static String recommendInputName(ExprNodeDesc desc) { if (desc instanceof ExprNodeColumnDesc) { return ((ExprNodeColumnDesc) desc).getColumn(); } List<ExprNodeDesc> children = desc.getChildren(); if (FunctionRegistry.isOpPreserveInputName(desc) && !children.isEmpty() && children.get(0) instanceof ExprNodeColumnDesc) { return ((ExprNodeColumnDesc) children.get(0)).getColumn(); } return null; }
/** split predicates by AND op */ public static List<ExprNodeDesc> split(ExprNodeDesc current, List<ExprNodeDesc> splitted) { if (FunctionRegistry.isOpAnd(current)) { for (ExprNodeDesc child : current.getChildren()) { split(child, splitted); } return splitted; } if (indexOf(current, splitted) < 0) { splitted.add(current); } return splitted; }
public static ExprNodeColumnDesc getColumnExpr(ExprNodeDesc expr) { while (FunctionRegistry.isOpCast(expr)) { expr = expr.getChildren().get(0); } return (expr instanceof ExprNodeColumnDesc) ? (ExprNodeColumnDesc) expr : null; }