@Override
    public Object process(Node nd, Stack<Node> stack, NodeProcessorCtx ctx,
        Object... nodeOutputs) throws SemanticException {
      SelectOperator op = (SelectOperator) nd;
      ColumnPrunerProcCtx cppCtx = (ColumnPrunerProcCtx) ctx;


      if (op.getChildOperators() != null) {
        for (Operator<? extends OperatorDesc> child : op.getChildOperators()) {
          // UDTF is not handled yet, so the parent SelectOp of UDTF should just assume
          // all columns.
          if ((child instanceof UDTFOperator)) {
            cppCtx.getPrunedColLists()
                .put(op, cppCtx.getColsFromSelectExpr(op));
            return null;
          }
        }
      }

      LateralViewJoinOperator lvJoin = null;
      if (op.getConf().isSelStarNoCompute()) {
        assert op.getNumChild() == 1;
        Operator<? extends OperatorDesc> child = op.getChildOperators().get(0);
        if (child instanceof LateralViewJoinOperator) { // this SEL is SEL(*)
                                                        // for LV
          lvJoin = (LateralViewJoinOperator) child;
        }
      }

      List<FieldNode> cols = cppCtx.genColLists(op);

      SelectDesc conf = op.getConf();

      if (lvJoin != null) {
        // get columns for SEL(*) from LVJ
        if (cols != null) {
          RowSchema rs = op.getSchema();
          cppCtx.getPrunedColLists().put(op,
              cppCtx.getSelectColsFromLVJoin(rs, cols));
        }
        return null;
      }
      // The input to the select does not matter. Go over the expressions
      // and return the ones which have a marked column
      cppCtx.getPrunedColLists().put(op,
          cppCtx.getSelectColsFromChildren(op, cols));
      if (cols == null || conf.isSelStarNoCompute()) {
        return null;
      }

      // do we need to prune the select operator?
      List<ExprNodeDesc> originalColList = op.getConf().getColList();
      // by now, 'prunedCols' are columns used by child operators, and 'columns'
      // are columns used by this select operator.
      List<String> originalOutputColumnNames = conf.getOutputColumnNames();
      // get view column authorization.
      if (cppCtx.getParseContext().getColumnAccessInfo() != null
          && cppCtx.getParseContext().getViewProjectToTableSchema() != null
          && cppCtx.getParseContext().getViewProjectToTableSchema().containsKey(op)) {
        for (FieldNode col : cols) {
          int index = originalOutputColumnNames.indexOf(col.getFieldName());
          Table tab = cppCtx.getParseContext().getViewProjectToTableSchema().get(op);
          List<FieldSchema> fullFieldList = new ArrayList<FieldSchema>(tab.getCols());
          fullFieldList.addAll(tab.getPartCols());
          cppCtx.getParseContext().getColumnAccessInfo()
              .add(tab.getCompleteName(), fullFieldList.get(index).getName());
        }
      }
      if (cols.size() < originalOutputColumnNames.size()) {
        List<ExprNodeDesc> newColList = new ArrayList<ExprNodeDesc>();
        List<String> newOutputColumnNames = new ArrayList<String>();
        List<ColumnInfo> rs_oldsignature = op.getSchema().getSignature();
        List<ColumnInfo> rs_newsignature = new ArrayList<ColumnInfo>();
        // The pruning needs to preserve the order of columns in the input schema
        Set<String> colNames = new HashSet<String>();
        for (FieldNode col : cols) {
          colNames.add(col.getFieldName());
        }
        for (int i = 0; i < originalOutputColumnNames.size(); i++) {
          String colName = originalOutputColumnNames.get(i);
          if (colNames.contains(colName)) {
            newOutputColumnNames.add(colName);
            newColList.add(originalColList.get(i));
            rs_newsignature.add(rs_oldsignature.get(i));
          }
        }
        op.getSchema().setSignature(rs_newsignature);
        conf.setColList(newColList);
        conf.getColumnExprMap().keySet().retainAll(colNames);
        conf.setOutputColumnNames(newOutputColumnNames);
        handleChildren(op, toColumnNames(cols), cppCtx);
      }

      return null;
    }
The Node Processor for Column Pruning on Select Operators.
ql/src/java/org/apache/hadoop/hive/ql/optimizer/ColumnPrunerProcFactory.java