public static ExprNodeDesc findConstantExprOrigin(String dpCol, Operator<? extends OperatorDesc> op) {
    ExprNodeDesc expr = op.getColumnExprMap().get(dpCol);
    ExprNodeDesc foldedExpr;
    // If it is a function, we try to fold it
    if (expr instanceof ExprNodeGenericFuncDesc) {
      foldedExpr = ConstantPropagateProcFactory.foldExpr((ExprNodeGenericFuncDesc)expr);
      if (foldedExpr == null) {
        foldedExpr = expr;
      }
    } else {
      foldedExpr = expr;
    }
    // If it is a column reference, we will try to resolve it
    if (foldedExpr instanceof ExprNodeColumnDesc) {
      Operator<? extends OperatorDesc> originOp = null;
      for(Operator<? extends OperatorDesc> parentOp : op.getParentOperators()) {
        if (parentOp.getColumnExprMap() != null) {
          originOp = parentOp;
          break;
        }
      }
      if (originOp != null) {
        return findConstantExprOrigin(((ExprNodeColumnDesc)foldedExpr).getColumn(), originOp);
      }
    }
    // Otherwise, we return the expression
    return foldedExpr;
  }
A normal reduce operator's rowObjectInspector looks like a struct containing
 nested key/value structs that contain the column values:
 { key: { reducesinkkey0:int }, value: { _col0:int, _col1:int, .. } }

While the rowObjectInspector looks the same for vectorized queries during
compilation time, within the tasks at query execution the rowObjectInspector
has changed to a flatter structure without nested key/value structs:
 { 'key.reducesinkkey0':int, 'value._col0':int, 'value._col1':int, .. }

Trying to fetch 'key.reducesinkkey0' by name from the list of flattened
ObjectInspectors does not work because the '.' gets interpreted as a field member,
even though it is a flattened list of column values.
This workaround converts the column name referenced in the ExprNodeDesc
from a nested field name (key.reducesinkkey0) to key_reducesinkkey0,
simply by replacing '.' with '_'.
@param source
@return
ql/src/java/org/apache/hadoop/hive/ql/plan/ExprNodeDescUtils.java