diff --git ql/src/java/org/apache/hadoop/hive/ql/parse/PTFTranslator.java ql/src/java/org/apache/hadoop/hive/ql/parse/PTFTranslator.java index e0cd398..38e5c5f 100644 --- ql/src/java/org/apache/hadoop/hive/ql/parse/PTFTranslator.java +++ ql/src/java/org/apache/hadoop/hive/ql/parse/PTFTranslator.java @@ -1000,8 +1000,7 @@ protected static RowResolver buildRowResolverForNoop(String tabAlias, * If the cInfo is for an ASTNode, this function returns the ASTNode that it is for. */ public static ASTNode getASTNode(ColumnInfo cInfo, RowResolver rr) throws SemanticException { - for (Map.Entry entry : rr.getExpressionMap().entrySet()) { - ASTNode expr = entry.getValue(); + for (ASTNode expr : rr.getASTNodes()) { if (rr.getExpression(expr).equals(cInfo)) { return expr; } diff --git ql/src/java/org/apache/hadoop/hive/ql/parse/ParseUtils.java ql/src/java/org/apache/hadoop/hive/ql/parse/ParseUtils.java index 18f0180..bf1b5d4 100644 --- ql/src/java/org/apache/hadoop/hive/ql/parse/ParseUtils.java +++ ql/src/java/org/apache/hadoop/hive/ql/parse/ParseUtils.java @@ -18,9 +18,16 @@ package org.apache.hadoop.hive.ql.parse; -import java.util.*; +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Queue; +import java.util.Set; +import java.util.Stack; -import org.apache.hadoop.hive.common.JavaUtils; +import org.antlr.runtime.tree.Tree; import org.apache.hadoop.hive.common.type.HiveDecimal; import org.apache.hadoop.hive.metastore.api.FieldSchema; import org.apache.hadoop.hive.ql.ErrorMsg; @@ -266,4 +273,44 @@ public static boolean containsTokenOfType(ASTNode root, PTFUtils.Predicate stack = new Stack(); + stack.push(node); + Stack otherStack = new Stack(); + otherStack.push(otherNode); + + while (!stack.empty() && !otherStack.empty()) { + Tree p = stack.pop(); + Tree otherP = otherStack.pop(); + + if (p.isNil() != otherP.isNil()) { + return false; + } + if (!p.isNil()) { + if (!p.toString().equals(otherP.toString())) { + return false; + } + } + if (p.getChildCount() != otherP.getChildCount()) { + return false; + } + for (int i = p.getChildCount()-1; i >= 0; i--) { + Tree t = p.getChild(i); + stack.push(t); + Tree otherT = otherP.getChild(i); + otherStack.push(otherT); + } + } + + return stack.empty() && otherStack.empty(); + } } diff --git ql/src/java/org/apache/hadoop/hive/ql/parse/RowResolver.java ql/src/java/org/apache/hadoop/hive/ql/parse/RowResolver.java index 5190bda..4b20e1f 100644 --- ql/src/java/org/apache/hadoop/hive/ql/parse/RowResolver.java +++ ql/src/java/org/apache/hadoop/hive/ql/parse/RowResolver.java @@ -49,7 +49,7 @@ * invRslvMap. */ private final Map altInvRslvMap; - private Map expressionMap; + private final Map astNodeToColName; // TODO: Refactor this and do in a more object oriented manner private boolean isExprResolver; @@ -61,7 +61,7 @@ public RowResolver() { rslvMap = new HashMap>(); invRslvMap = new HashMap(); altInvRslvMap = new HashMap(); - expressionMap = new HashMap(); + astNodeToColName = new HashMap(); isExprResolver = false; } @@ -69,21 +69,43 @@ public RowResolver() { * Puts a resolver entry corresponding to a source expression which is to be * used for identical expression recognition (e.g. for matching expressions * in the SELECT list with the GROUP BY clause). The convention for such - * entries is an empty-string ("") as the table alias together with the - * string rendering of the ASTNode as the column alias. + * entries is an empty-string ("") as the table alias together with a + * unique string representing the ASTNode as the column alias. */ public void putExpression(ASTNode node, ColumnInfo colInfo) { - String treeAsString = node.toStringTree(); - expressionMap.put(treeAsString, node); - put("", treeAsString, colInfo); + for (ASTNode expr: astNodeToColName.keySet()) { + if (ParseUtils.sameTree(node, expr)) { + put("", astNodeToColName.get(expr), colInfo); + return; + } + } + final String astColName = genAstColName(); + astNodeToColName.put(node, astColName); + put("", astColName, colInfo); + } + + public String genAstColName() { + final String baseAstColName = "astCol_"; + int i = -1; + String astColName; + do { + i++; + astColName = baseAstColName + i; + } while (getPosition(astColName) != -1); + return astColName; } /** * Retrieves the ColumnInfo corresponding to a source expression which - * exactly matches the string rendering of the given ASTNode. + * exactly matches the ASTNode. */ public ColumnInfo getExpression(ASTNode node) throws SemanticException { - return get("", node.toStringTree()); + for (ASTNode expr: astNodeToColName.keySet()) { + if (ParseUtils.sameTree(node, expr)) { + return get("", astNodeToColName.get(expr)); + } + } + return null; } /** @@ -91,7 +113,12 @@ public ColumnInfo getExpression(ASTNode node) throws SemanticException { * string rendering exactly. */ public ASTNode getExpressionSource(ASTNode node) { - return expressionMap.get(node.toStringTree()); + for (ASTNode expr: astNodeToColName.keySet()) { + if (ParseUtils.sameTree(node, expr)) { + return expr; + } + } + return null; } public void put(String tab_alias, String col_alias, ColumnInfo colInfo) { @@ -325,8 +352,8 @@ public RowSchema getRowSchema() { return invRslvMap; } - public Map getExpressionMap() { - return expressionMap; + public Set getASTNodes() { + return astNodeToColName.keySet(); } public void setExprResolver(boolean isExprResolver) { @@ -346,10 +373,6 @@ public void setInvRslvMap(HashMap invRslvMap) { this.invRslvMap = invRslvMap; } - public void setExpressionMap(Map expressionMap) { - this.expressionMap = expressionMap; - } - private static class IntRef { public int val = 0; } @@ -472,7 +495,7 @@ public RowResolver duplicate() { resolver.rslvMap.putAll(rslvMap); resolver.invRslvMap.putAll(invRslvMap); resolver.altInvRslvMap.putAll(altInvRslvMap); - resolver.expressionMap.putAll(expressionMap); + resolver.astNodeToColName.putAll(astNodeToColName); resolver.isExprResolver = isExprResolver; return resolver; }