/** * Returns true if des is a descendant of ans (ancestor) */ private boolean isDescendant(Node ans, Node des) { if (ans.getChildren() == null) { return false; } for (Node c : ans.getChildren()) { if (c == des) { return true; } if (isDescendant(c, des)) { return true; } } return false; }
/** * This function returns the cost of the rule for the specified stack. Returns 1 if there is * an exact match with the entire stack, otherwise -1 * * If any proper substack of the stack matches it will return -1. It only returns 1 if the * entire stack matches the rule exactly. * * @param stack * Node stack encountered so far * @return cost of the function * @throws SemanticException */ @Override public int cost(Stack<Node> stack) throws SemanticException { int numElems = (stack != null ? stack.size() : 0); if (numElems != pattern.length) { return -1; } for (int pos = numElems - 1; pos >= 0; pos--) { if(!stack.get(pos).getName().equals(pattern[pos])) { return -1; } } return numElems; }
@Override public Object process(Node nd, Stack<Node> stack, NodeProcessorCtx procCtx, Object... nodeOutputs) throws SemanticException { LOG.info("Processing for " + nd.getName() + "(" + ((Operator) nd).getIdentifier() + ")"); OpWalkerInfo owi = (OpWalkerInfo) procCtx; // The lateral view forward operator has 2 children, a SELECT(*) and // a SELECT(cols) (for the UDTF operator) The child at index 0 is the // SELECT(*) because that's the way that the DAG was constructed. We // only want to get the predicates from the SELECT(*). ExprWalkerInfo childPreds = owi .getPrunedPreds((Operator<? extends OperatorDesc>) nd.getChildren() .get(0)); owi.putPrunedPreds((Operator<? extends OperatorDesc>) nd, childPreds); return null; }
@Override public Object process(Node nd, Stack<Node> stack, NodeProcessorCtx procCtx, Object... nodeOutputs) throws SemanticException { LOG.info("Processing for " + nd.getName() + "(" + ((Operator) nd).getIdentifier() + ")"); OpWalkerInfo owi = (OpWalkerInfo) procCtx; // The lateral view forward operator has 2 children, a SELECT(*) and // a SELECT(cols) (for the UDTF operator) The child at index 0 is the // SELECT(*) because that's the way that the DAG was constructed. We // only want to get the predicates from the SELECT(*). ExprWalkerInfo childPreds = owi .getPrunedPreds((Operator<? extends OperatorDesc>) nd.getChildren() .get(0)); owi.putPrunedPreds((Operator<? extends OperatorDesc>) nd, childPreds); return null; }
/** * Returns dispatch result */ public <T> T dispatchAndReturn(Node nd, Stack<Node> ndStack) throws SemanticException { Object[] nodeOutputs = null; if (nd.getChildren() != null) { nodeOutputs = new Object[nd.getChildren().size()]; int i = 0; for (Node child : nd.getChildren()) { nodeOutputs[i++] = retMap.get(child); } } Object retVal = dispatcher.dispatch(nd, ndStack, nodeOutputs); retMap.put(nd, retVal); return (T) retVal; }
/** * This function returns the cost of the rule for the specified stack. Returns 1 if there is * an exact match with the entire stack, otherwise -1 * * If any proper substack of the stack matches it will return -1. It only returns 1 if the * entire stack matches the rule exactly. * * @param stack * Node stack encountered so far * @return cost of the function * @throws SemanticException */ @Override public int cost(Stack<Node> stack) throws SemanticException { int numElems = (stack != null ? stack.size() : 0); if (numElems != pattern.length) { return -1; } for (int pos = numElems - 1; pos >= 0; pos--) { if(!stack.get(pos).getName().equals(pattern[pos])) { return -1; } } return numElems; }
@Override public Object process(Node nd, Stack<Node> stack, NodeProcessorCtx procCtx, Object... nodeOutputs) throws SemanticException { LOG.info("Processing for " + nd.getName() + "(" + ((Operator) nd).getIdentifier() + ")"); OpWalkerInfo owi = (OpWalkerInfo) procCtx; ExprWalkerInfo childPreds = owi .getPrunedPreds((Operator<? extends Serializable>) nd.getChildren() .get(0)); owi.putPrunedPreds((Operator<? extends Serializable>) nd, childPreds); return null; }
/** * Returns true if des is a descendant of ans (ancestor) */ private boolean isDescendant(Node ans, Node des) { if (ans.getChildren() == null) { return false; } for (Node c : ans.getChildren()) { if (c == des) { return true; } if (isDescendant(c, des)) { return true; } } return false; }
/** * This function returns the cost of the rule for the specified stack when the pattern * matched for has wildcard character in it. The function expects patternWithWildCardChar * to be not null. * * @param stack * Node stack encountered so far * @return cost of the function * @throws SemanticException */ private int costPatternWithWildCardChar(Stack<Node> stack) throws SemanticException { int numElems = (stack != null ? stack.size() : 0); StringBuilder name = new StringBuilder(); Matcher m = patternWithWildCardChar.matcher(""); for (int pos = numElems - 1; pos >= 0; pos--) { String nodeName = stack.get(pos).getName() + "%"; name.insert(0, nodeName); m.reset(name); if (m.matches()) { return name.length(); } } return -1; }
/** * Returns dispatch result */ public <T> T dispatchAndReturn(Node nd, Stack<Node> ndStack) throws SemanticException { Object[] nodeOutputs = null; if (nd.getChildren() != null) { nodeOutputs = new Object[nd.getChildren().size()]; int i = 0; for (Node child : nd.getChildren()) { nodeOutputs[i++] = retMap.get(child); } } Object retVal = dispatcher.dispatch(nd, ndStack, nodeOutputs); retMap.put(nd, retVal); return (T) retVal; }
/** * This function returns the cost of the rule for the specified stack when the pattern * matched for has no wildcard character in it. The function expects patternWithoutWildCardChar * to be not null. * @param stack * Node stack encountered so far * @return cost of the function * @throws SemanticException */ private int costPatternWithoutWildCardChar(Stack<Node> stack) throws SemanticException { int numElems = (stack != null ? stack.size() : 0); // No elements if (numElems == 0) { return -1; } int patLen = patternWithoutWildCardChar.length(); StringBuilder name = new StringBuilder(patLen + numElems); for (int pos = numElems - 1; pos >= 0; pos--) { String nodeName = stack.get(pos).getName() + "%"; name.insert(0, nodeName); if (name.length() >= patLen) { if (patternWithoutWildCardChar.contentEquals(name)) { return patLen; } break; } } return -1; }
private static boolean isNullOpPresentInAllBranches(TableScanOperator ts, Node causeOfNullNode) { Queue<Node> middleNodes = new ArrayDeque<>(); middleNodes.add(ts); while (!middleNodes.isEmpty()) { Node curNode = middleNodes.remove(); List<? extends Node> curChd = curNode.getChildren(); for (Node chd: curChd) { List<? extends Node> children = chd.getChildren(); if (CollectionUtils.isEmpty(children) || chd == causeOfNullNode) { // If there is an end node that not the limit0/wherefalse.. if (chd != causeOfNullNode) { return false; } } else { middleNodes.add(chd); } } } return true; }
/** * This function returns the cost of the rule for the specified stack when the pattern * matched for has wildcard character in it. The function expects patternWithWildCardChar * to be not null. * * @param stack * Node stack encountered so far * @return cost of the function * @throws SemanticException */ private int costPatternWithWildCardChar(Stack<Node> stack) throws SemanticException { int numElems = (stack != null ? stack.size() : 0); StringBuilder name = new StringBuilder(); Matcher m = patternWithWildCardChar.matcher(""); for (int pos = numElems - 1; pos >= 0; pos--) { String nodeName = stack.get(pos).getName() + "%"; name.insert(0, nodeName); m.reset(name); if (m.matches()) { return name.length(); } } return -1; }
/** * Dispatch the current operator. * * @param nd * node being walked * @param ndStack * stack of nodes encountered * @throws SemanticException */ public void dispatch(Node nd, Stack<Node> ndStack,TaskGraphWalkerContext walkerCtx) throws SemanticException { Object[] nodeOutputs = null; if (nd.getChildren() != null) { nodeOutputs = new Object[nd.getChildren().size()+1]; nodeOutputs[0] = walkerCtx; int i = 1; for (Node child : nd.getChildren()) { nodeOutputs[i++] = retMap.get(child); } }else{ nodeOutputs = new Object[1]; nodeOutputs[0] = walkerCtx; } Object retVal = dispatcher.dispatch(nd, ndStack, nodeOutputs); retMap.put(nd, retVal); }
/** * @param nd * @param ewi */ protected void logExpr(Node nd, ExprWalkerInfo ewi) { if (!LOG.isDebugEnabled()) { return; } for (Entry<String, List<ExprNodeDesc>> e : ewi.getFinalCandidates().entrySet()) { StringBuilder sb = new StringBuilder("Pushdown predicates of ").append(nd.getName()) .append(" for alias ").append(e.getKey()).append(": "); boolean isFirst = true; for (ExprNodeDesc n : e.getValue()) { if (!isFirst) { sb.append("; "); } isFirst = false; sb.append(n.getExprString()); } LOG.debug(sb.toString()); } }
private static <T> List<Collection<? extends Node>> iterate(List<Collection<? extends Node>> listNodes, Class<T> clazz, Function<T> function, Set<Node> visited) { List<Collection<? extends Node>> childListNodes = new ArrayList<>(); for (Collection<? extends Node> nodes : listNodes) { for (Node node : nodes) { if (!visited.add(node)) { continue; } if (clazz.isInstance(node)) { function.apply(clazz.cast(node)); } if (node.getChildren() != null) { childListNodes.add(node.getChildren()); } } } return childListNodes; }
/** * This function returns the cost of the rule for the specified stack when the pattern * matched for has no wildcard character in it. The function expects patternWithoutWildCardChar * to be not null. * @param stack * Node stack encountered so far * @return cost of the function * @throws SemanticException */ private int costPatternWithoutWildCardChar(Stack<Node> stack) throws SemanticException { int numElems = (stack != null ? stack.size() : 0); // No elements if (numElems == 0) { return -1; } int patLen = patternWithoutWildCardChar.length(); StringBuilder name = new StringBuilder(patLen + numElems); for (int pos = numElems - 1; pos >= 0; pos--) { String nodeName = stack.get(pos).getName() + "%"; name.insert(0, nodeName); if (name.length() >= patLen) { if (patternWithoutWildCardChar.contentEquals(name)) { return patLen; } break; } } return -1; }
private static <T> void iterate(Node node, Class<T> clazz, Function<T> function, Set<Node> visited) { if (!visited.add(node)) { return; } if (clazz.isInstance(node)) { function.apply(clazz.cast(node)); } if (node.getChildren() != null) { for (Node child : node.getChildren()) { iterate(child, clazz, function, visited); } } }
/** * @param nd * @param ewi */ protected void logExpr(Node nd, ExprWalkerInfo ewi) { if (!LOG.isDebugEnabled()) return; for (Entry<String, List<ExprNodeDesc>> e : ewi.getFinalCandidates().entrySet()) { StringBuilder sb = new StringBuilder("Pushdown predicates of ").append(nd.getName()) .append(" for alias ").append(e.getKey()).append(": "); boolean isFirst = true; for (ExprNodeDesc n : e.getValue()) { if (!isFirst) { sb.append("; "); } isFirst = false; sb.append(n.getExprString()); } LOG.debug(sb.toString()); } }
/** * Dispatch the current operator. * * @param nd * node being walked * @param ndStack * stack of nodes encountered * @throws SemanticException */ public void dispatch(Node nd, Stack<Node> ndStack,TaskGraphWalkerContext walkerCtx) throws SemanticException { Object[] nodeOutputs = null; if (nd.getChildren() != null) { nodeOutputs = new Object[nd.getChildren().size()+1]; nodeOutputs[0] = walkerCtx; int i = 1; for (Node child : nd.getChildren()) { nodeOutputs[i++] = retMap.get(child); } }else{ nodeOutputs = new Object[1]; nodeOutputs[0] = walkerCtx; } Object retVal = dispatcher.dispatch(nd, ndStack, nodeOutputs); retMap.put(nd, retVal); }