@Override
  public ParseContext transform(ParseContext pctx) throws SemanticException {
    // 0. We check the conditions to apply this transformation,
    //    if we do not meet them we bail out
    final boolean cboEnabled = HiveConf.getBoolVar(pctx.getConf(), HiveConf.ConfVars.HIVE_CBO_ENABLED);
    final boolean returnPathEnabled = HiveConf.getBoolVar(pctx.getConf(), HiveConf.ConfVars.HIVE_CBO_RETPATH_HIVEOP);
    final boolean cboSucceeded = pctx.getContext().isCboSucceeded();
    if(cboEnabled && returnPathEnabled && cboSucceeded) {
      return pctx;
    }

    // 1. We apply the transformation
    Map<SemanticRule, SemanticNodeProcessor> opRules = new LinkedHashMap<SemanticRule, SemanticNodeProcessor>();
    opRules.put(new RuleRegExp("R1",
      "(" + SelectOperator.getOperatorName() + "%)"), new ProjectRemover());
    SemanticGraphWalker ogw = new DefaultGraphWalker(new DefaultRuleDispatcher(null, opRules, null));
    ArrayList<Node> topNodes = new ArrayList<Node>();
    topNodes.addAll(pctx.getTopOps().values());
    ogw.startWalking(topNodes, null);
    return pctx;
  }
This optimization tries to remove {@link SelectOperator} from tree which don't do any
processing except forwarding columns from its parent to its children.
e.g., select * from (select * from src where key = value) t1 join (select * from src where key = value) t2;
Query tree

 Without this optimization:

 TS -&gt; FIL -&gt; SEL -&gt; RS -&gt;
                            JOIN -&gt; SEL -&gt; FS
 TS -&gt; FIL -&gt; SEL -&gt; RS -&gt;

 With this optimization

 TS -&gt; FIL -&gt; RS -&gt;
                     JOIN -&gt; FS
 TS -&gt; FIL -&gt; RS -&gt;

 Note absence of select operator after filter and after join operator.
 Also, see : identity_proj_remove.q
ql/src/java/org/apache/hadoop/hive/ql/optimizer/IdentityProjectRemover.java