diff --git a/ql/src/java/org/apache/hadoop/hive/ql/parse/SemanticAnalyzer.java b/ql/src/java/org/apache/hadoop/hive/ql/parse/SemanticAnalyzer.java index d2c3a7c..f3d7057 100644 --- a/ql/src/java/org/apache/hadoop/hive/ql/parse/SemanticAnalyzer.java +++ b/ql/src/java/org/apache/hadoop/hive/ql/parse/SemanticAnalyzer.java @@ -26,6 +26,8 @@ import java.security.AccessControlException; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; @@ -155,6 +157,7 @@ import org.apache.hadoop.hive.ql.plan.ExprNodeConstantDesc; import org.apache.hadoop.hive.ql.plan.ExprNodeDesc; import org.apache.hadoop.hive.ql.plan.ExprNodeDescUtils; +import org.apache.hadoop.hive.ql.plan.ExprNodeFieldDesc; import org.apache.hadoop.hive.ql.plan.ExprNodeGenericFuncDesc; import org.apache.hadoop.hive.ql.plan.FileSinkDesc; import org.apache.hadoop.hive.ql.plan.FilterDesc; @@ -10496,8 +10499,16 @@ private ExprNodeDesc getExprNodeDescCached(ASTNode expr, RowResolver input) return nodeOutputs; } + Map nodeToText = new HashMap<>(); + List> fieldDescList = new ArrayList<>(); + for (Map.Entry entry : nodeOutputs.entrySet()) { if (!(entry.getValue() instanceof ExprNodeColumnDesc)) { + // we need to translate the ExprNodeFieldDesc too, e.g., identifiers in + // struct<>. + if (entry.getValue() instanceof ExprNodeFieldDesc) { + fieldDescList.add(entry); + } continue; } ASTNode node = entry.getKey(); @@ -10513,9 +10524,35 @@ private ExprNodeDesc getExprNodeDescCached(ASTNode expr, RowResolver input) replacementText.append(HiveUtils.unparseIdentifier(tmp[0], conf)); replacementText.append("."); replacementText.append(HiveUtils.unparseIdentifier(tmp[1], conf)); + nodeToText.put(columnDesc, replacementText.toString()); unparseTranslator.addTranslation(node, replacementText.toString()); } + if (fieldDescList.size() != 0) { + // Sorting the list based on the length of fieldName + // For example, in Column[a].b.c and Column[a].b, Column[a].b should be + // unparsed before Column[a].b.c + Collections.sort(fieldDescList, new Comparator>() { + public int compare(Entry o1, Entry o2) { + ExprNodeFieldDesc fieldDescO1 = (ExprNodeFieldDesc) o1.getValue(); + ExprNodeFieldDesc fieldDescO2 = (ExprNodeFieldDesc) o2.getValue(); + return fieldDescO1.toString().length() < fieldDescO2.toString().length() ? -1 : 1; + } + }); + for (Map.Entry entry : fieldDescList) { + ASTNode node = entry.getKey(); + ExprNodeFieldDesc fieldDesc = (ExprNodeFieldDesc) entry.getValue(); + ExprNodeDesc exprNodeDesc = fieldDesc.getDesc(); + String fieldName = fieldDesc.getFieldName(); + StringBuilder replacementText = new StringBuilder(); + replacementText.append(nodeToText.get(exprNodeDesc)); + replacementText.append("."); + replacementText.append(HiveUtils.unparseIdentifier(fieldName, conf)); + nodeToText.put(fieldDesc, replacementText.toString()); + unparseTranslator.addTranslation(node, replacementText.toString()); + } + } + return nodeOutputs; }