protected boolean areMergeable(ParseContext pctx, TableScanOperator tsOp1, TableScanOperator tsOp2)
      throws SemanticException {
    // If row limit does not match, we currently do not merge
    if (tsOp1.getConf().getRowLimit() != tsOp2.getConf().getRowLimit()) {
      LOG.debug("rowlimit differ {} ~ {}", tsOp1.getConf().getRowLimit(), tsOp2.getConf().getRowLimit());
      return false;
    }
    // If table properties do not match, we currently do not merge
    if (!Objects.equals(tsOp1.getConf().getOpProps(), tsOp2.getConf().getOpProps())) {
      LOG.debug("opProps differ {} ~ {}", tsOp1.getConf().getOpProps(), tsOp2.getConf().getOpProps());
      return false;
    }
    // If partitions do not match, we currently do not merge
    PrunedPartitionList prevTsOpPPList = pctx.getPrunedPartitions(tsOp1);
    PrunedPartitionList tsOpPPList = pctx.getPrunedPartitions(tsOp2);
    if (!prevTsOpPPList.getPartitions().equals(tsOpPPList.getPartitions())) {
      LOG.debug("partitions differ {} ~ {}", prevTsOpPPList.getPartitions().size(), tsOpPPList.getPartitions().size());
      return false;
    }

    if (!Objects.equals(tsOp1.getConf().getIncludedBuckets(), tsOp2.getConf().getIncludedBuckets())) {
      LOG.debug("includedBuckets differ {} ~ {}", tsOp1.getConf().getIncludedBuckets(),
          tsOp2.getConf().getIncludedBuckets());
      return false;
    }

    return true;
  }
Class wrapping shared work optimizer.
This implementation enables merging of TS with different schemas by taking the union of the
{@link TableScanDesc#getNeededColumns()} and {@link TableScanDesc#getNeededColumnIDs()}
from both {@link TableScanOperator}s.
ql/src/java/org/apache/hadoop/hive/ql/optimizer/SharedWorkOptimizer.java