public static ColumnOrigin findColumnOrigin(ExprNodeDesc expr, Operator<?> op) {
    if (expr == null || op == null) {
      // bad input
      return null;
    }

    ExprNodeColumnDesc col = ExprNodeDescUtils.getColumnExpr(expr);
    if (col == null) {
      // not a column
      return null;
    }

    Operator<?> parentOp = null;
    int numParents = op.getNumParent();
    if (numParents == 0) {
      return new ColumnOrigin(col, op);
    }

    ExprNodeDesc parentExpr = findParentExpr(col, op);
    if (parentExpr == null) {
      // couldn't find proper parent column expr
      return null;
    }

    if (numParents == 1) {
      parentOp = op.getParentOperators().get(0);
    } else {
      // Multiple parents - find the right one based on the table alias in the parentExpr
      ExprNodeColumnDesc parentCol = ExprNodeDescUtils.getColumnExpr(parentExpr);
      if (parentCol != null) {
        for (Operator<?> currParent : op.getParentOperators()) {
          RowSchema schema = currParent.getSchema();
          if (schema == null) {
            // Happens in case of TezDummyStoreOperator
            return null;
          }
          if (schema.getTableNames().contains(parentCol.getTabAlias())) {
            parentOp = currParent;
            break;
          }
        }
      }
    }

    if (parentOp == null) {
      return null;
    }

    return findColumnOrigin(parentExpr, parentOp);
  }
Checks whether the keys of a child operator are a prefix of the keys of a
parent operator.
@param childKeys keys of the child operator
@param parentKeys keys of the parent operator
@param childOp child operator
@param parentOp parent operator
@return true if the keys are a prefix, false otherwise
@throws SemanticException
ql/src/java/org/apache/hadoop/hive/ql/plan/ExprNodeDescUtils.java