diff --git a/ql/src/java/org/apache/hadoop/hive/ql/plan/ExprNodeDescUtils.java b/ql/src/java/org/apache/hadoop/hive/ql/plan/ExprNodeDescUtils.java index fb3c4a3..d1b32cb 100644 --- a/ql/src/java/org/apache/hadoop/hive/ql/plan/ExprNodeDescUtils.java +++ b/ql/src/java/org/apache/hadoop/hive/ql/plan/ExprNodeDescUtils.java @@ -278,6 +278,57 @@ private static ExprNodeDesc backtrack(ExprNodeColumnDesc column, Operator cur throw new SemanticException("Met multiple parent operators"); } + public static List forwardTrack(List sourceList, Operator childOp) { + ArrayList result = new ArrayList(sourceList.size()); + for (ExprNodeDesc source : sourceList) { + result.add(forwardTrack(source, childOp)); + } + return result; + } + + /** + * Do the opposite of backtrack() - resolve the source expression using the column expressions from the child operator. + * @param source + * @param childOp + * @return + */ + public static ExprNodeDesc forwardTrack(ExprNodeDesc source, Operator childOp) { + if (source instanceof ExprNodeGenericFuncDesc) { + // all children expression should be resolved + ExprNodeGenericFuncDesc function = (ExprNodeGenericFuncDesc) source.clone(); + List newChildren = forwardTrack(function.getChildren(), childOp); + for (ExprNodeDesc newChild : newChildren) { + if (newChild == null) { + // Could not resolve all of the function children, fail + return null; + } + } + function.setChildren(newChildren); + return function; + } + if (source instanceof ExprNodeColumnDesc) { + ExprNodeColumnDesc column = (ExprNodeColumnDesc) source; + // Not sure if this is the best/correct way to do this + ColumnInfo columnInfo = childOp.getSchema().getColumnInfo(column.getTabAlias(), column.getColumn()); + if (columnInfo == null) { + return null; + } + return new ExprNodeColumnDesc(columnInfo); + } + if (source instanceof ExprNodeFieldDesc) { + // field expression should be resolved + ExprNodeFieldDesc field = (ExprNodeFieldDesc) source.clone(); + ExprNodeDesc fieldDesc = forwardTrack(field.getDesc(), childOp); + if (fieldDesc == null) { + return null; + } + field.setDesc(fieldDesc); + return field; + } + // constant or null expr, just return + return source; + } + public static ExprNodeDesc[] extractComparePair(ExprNodeDesc expr1, ExprNodeDesc expr2) { expr1 = extractConstant(expr1); expr2 = extractConstant(expr2);