private static List<String> getKeyColNames(List<ExprNodeDesc> keys) {
    List<String> colList = new ArrayList<String>();
    for (ExprNodeDesc expr: keys) {
      if (expr instanceof ExprNodeColumnDesc) {
        ExprNodeColumnDesc colExpr = (ExprNodeColumnDesc)expr;
        colList.add(colExpr.getColumn());
      } else if (expr instanceof ExprNodeConstantDesc) {
        continue;
      } else {
        return null;
      }
    }
    return colList;
  }
This method traces up from the given operator to the root
of the operator graph until a TableScanOperator is reached.
Along the way, if any operators are present that do not
provide a direct mapping from columns of the base table to
the keys on the input operator, the trace-back is stopped at that
point. If the trace back can be done successfully, the method
returns the root TableScanOperator as well as the list of column
names on that table that map to the keys used for the input
operator (which is currently only a join or group by).
ql/src/java/org/apache/hadoop/hive/ql/parse/TableAccessAnalyzer.java