public ParseContext transform(ParseContext pCtx) throws SemanticException {
    // create a walker which walks the tree in a BFS manner while maintaining
    // the operator stack.
    Map<SemanticRule, SemanticNodeProcessor> opRules = new LinkedHashMap<SemanticRule, SemanticNodeProcessor>();
    opRules.put(new RuleRegExp("R1",
      ReduceSinkOperator.getOperatorName() + "%.*" + UnionOperator.getOperatorName() + "%"),
      UnionProcFactory.getMapRedUnion());
    opRules.put(new RuleRegExp("R2",
      UnionOperator.getOperatorName() + "%.*" + UnionOperator.getOperatorName() + "%"),
      UnionProcFactory.getUnknownUnion());
    opRules.put(new RuleRegExp("R3",
      TableScanOperator.getOperatorName() + "%.*" + UnionOperator.getOperatorName() + "%"),
      UnionProcFactory.getMapUnion());

    // The dispatcher fires the processor for the matching rule and passes the
    // context along
    UnionProcContext uCtx = new UnionProcContext();
    uCtx.setParseContext(pCtx);
    SemanticDispatcher disp = new DefaultRuleDispatcher(UnionProcFactory.getNoUnion(),
        opRules, uCtx);
    LevelOrderWalker ogw = new LevelOrderWalker(disp);
    ogw.setNodeTypes(UnionOperator.class);

    // Create a list of topop nodes
    ArrayList<Node> topNodes = new ArrayList<Node>();
    topNodes.addAll(pCtx.getTopOps().values());
    ogw.startWalking(topNodes, null);
    pCtx.setUCtx(uCtx);

    // Walk the tree again to see if the union can be removed completely
    HiveConf conf = pCtx.getConf();
    opRules.clear();
    if (conf.getBoolVar(HiveConf.ConfVars.HIVE_OPTIMIZE_UNION_REMOVE)) {

      opRules.put(new RuleRegExp("R5", UnionOperator.getOperatorName() + "%" +
                                 ".*" + FileSinkOperator.getOperatorName() + "%"),
        UnionProcFactory.getUnionNoProcessFile());

      disp = new DefaultRuleDispatcher(UnionProcFactory.getNoUnion(), opRules, uCtx);
      ogw = new LevelOrderWalker(disp);
      ogw.setNodeTypes(FileSinkOperator.class);

      // Create a list of topop nodes
      topNodes.clear();
      topNodes.addAll(pCtx.getTopOps().values());
      ogw.startWalking(topNodes, null);
    }

    return pCtx;
  }
Transform the query tree. For each union, store the fact whether both the
sub-queries are map-only

@param pCtx
         the current parse context
ql/src/java/org/apache/hadoop/hive/ql/optimizer/unionproc/UnionProcessor.java