private MapredWork convertSMBWorkToJoinWork(MapredWork currWork, SMBMapJoinOperator oldSMBJoinOp)
      throws SemanticException {
    try {
      // deep copy a new mapred work
      MapredWork currJoinWork = SerializationUtilities.clonePlan(currWork);
      SMBMapJoinOperator newSMBJoinOp = getSMBMapJoinOp(currJoinWork);

      // change the newly created map-red plan as if it was a join operator
      genSMBJoinWork(currJoinWork.getMapWork(), newSMBJoinOp);
      return currJoinWork;
    } catch (Exception e) {
      throw new SemanticException("Generate Map Join Task Error", e);
    }
  }
Iterator over each task. If the task has a smb join, convert the task to a conditional task.
The conditional task will first try all mapjoin possibilities, and go the the smb join if the
mapjoin fails. The smb join will be a backup task for all the mapjoin tasks.
ql/src/java/org/apache/hadoop/hive/ql/optimizer/physical/SortMergeJoinTaskDispatcher.java