private static int[] extractMergeDirections(HiveConf hiveConf, ReduceSinkOperator cRS, ReduceSinkOperator pRS,
      int minReducer) throws SemanticException {
    ReduceSinkDesc cConf = cRS.getConf();
    ReduceSinkDesc pConf = pRS.getConf();
    // If there is a PTF between cRS and pRS we cannot ignore the order direction
    final boolean checkStrictEquality = isStrictEqualityNeeded(cRS, pRS);
    Integer moveRSOrderTo = checkOrder(checkStrictEquality, cConf.getOrder(), pConf.getOrder(),
            cConf.getNullOrder(), pConf.getNullOrder());
    if (moveRSOrderTo == null) {
      return null;
    }
    // if cRS is being used for distinct - the two reduce sinks are incompatible
    if (cConf.getDistinctColumnIndices().size() >= 2) {
      return null;
    }
    if (cConf.getBucketingVersion() != pConf.getBucketingVersion()) {
      return null;
    }
    Integer moveReducerNumTo = checkNumReducer(cConf.getNumReducers(), pConf.getNumReducers());
    if (moveReducerNumTo == null ||
        moveReducerNumTo > 0 && cConf.getNumReducers() < minReducer) {
      return null;
    }
    List<ExprNodeDesc> ckeys = cConf.getKeyCols();
    List<ExprNodeDesc> pkeys = pConf.getKeyCols();
    Integer moveKeyColTo = checkExprs(ckeys, pkeys, cRS, pRS);
    if (moveKeyColTo == null) {
      return null;
    }
    List<ExprNodeDesc> cpars = cConf.getPartitionCols();
    List<ExprNodeDesc> ppars = pConf.getPartitionCols();
    Integer movePartitionColTo = checkExprs(cpars, ppars, cRS, pRS);
    if (movePartitionColTo == null) {
      return null;
    }
    if (canReplaceParentWithChildPartioning(movePartitionColTo, cpars, ppars)) {
      long oldParallelism = estimateReducers(hiveConf, pRS);
      long newParallelism = estimateReducers(hiveConf, cRS);
      if (newParallelism < oldParallelism && newParallelism < minReducer) {
        return null;
      }
    }
    Integer moveNumDistKeyTo = checkNumDistributionKey(cConf.getNumDistributionKeys(),
        pConf.getNumDistributionKeys());
    return new int[] {moveKeyColTo, movePartitionColTo, moveRSOrderTo,
        moveReducerNumTo, moveNumDistKeyTo};
  }
Returns merge directions between two RSs for criterias (ordering, number of reducers,
reducer keys, partition keys). Returns null if any of categories is not mergeable.

Values for each index can be -1, 0, 1
1. 0 means two configuration in the category is the same
2. for -1, configuration of parent RS is more specific than child RS
3. for 1, configuration of child RS is more specific than parent RS
ql/src/java/org/apache/hadoop/hive/ql/optimizer/correlation/ReduceSinkDeDuplicationUtils.java