private void patchUpAfterCTASorMaterializedView(List<Task<?>> rootTasks,
      Set<ReadEntity> inputs, Set<WriteEntity> outputs, Task<?> createTask,
      boolean createTaskAfterMoveTask) {
    // clear the mapredWork output file from outputs for CTAS
    // DDLWork at the tail of the chain will have the output
    Iterator<WriteEntity> outIter = outputs.iterator();
    while (outIter.hasNext()) {
      switch (outIter.next().getType()) {
      case DFS_DIR:
      case LOCAL_DIR:
        outIter.remove();
        break;
      default:
        break;
      }
    }

    // find all leaf tasks and make the DDLTask as a dependent task on all of them
    Set<Task<?>> leaves = new LinkedHashSet<>();
    getLeafTasks(rootTasks, leaves);
    assert (leaves.size() > 0);
    // Target task is supposed to be the last task
    Task<?> targetTask = createTask;
    for (Task<?> task : leaves) {
      if (task instanceof StatsTask) {
        // StatsTask require table to already exist
        for (Task<?> parentOfStatsTask : task.getParentTasks()) {
          if (parentOfStatsTask instanceof MoveTask && !createTaskAfterMoveTask) {
            // For partitioned CTAS, we need to create the table before the move task
            // as we need to create the partitions in metastore and for that we should
            // have already registered the table
            interleaveTask(parentOfStatsTask, createTask);
          } else {
            parentOfStatsTask.addDependentTask(createTask);
          }
        }
        for (Task<?> parentOfCrtTblTask : createTask.getParentTasks()) {
          parentOfCrtTblTask.removeDependentTask(task);
        }
        createTask.addDependentTask(task);
        targetTask = task;
      } else if (task instanceof MoveTask && !createTaskAfterMoveTask) {
        // For partitioned CTAS, we need to create the table before the move task
        // as we need to create the partitions in metastore and for that we should
        // have already registered the table
        interleaveTask(task, createTask);
        targetTask = task;
      } else {
        task.addDependentTask(createTask);
      }
    }

    // Add task to insert / delete materialized view from registry if needed
    if (createTask instanceof DDLTask) {
      DDLTask ddlTask = (DDLTask)createTask;
      DDLWork work = ddlTask.getWork();
      DDLDesc desc = work.getDDLDesc();
      if (desc instanceof CreateMaterializedViewDesc) {
        CreateMaterializedViewDesc createViewDesc = (CreateMaterializedViewDesc)desc;
        String tableName = createViewDesc.getViewName();
        boolean retrieveAndInclude = createViewDesc.isRewriteEnabled();
        MaterializedViewUpdateDesc materializedViewUpdateDesc =
            new MaterializedViewUpdateDesc(tableName, retrieveAndInclude, false, false);
        DDLWork ddlWork = new DDLWork(inputs, outputs, materializedViewUpdateDesc);
        targetTask.addDependentTask(TaskFactory.get(ddlWork, conf));
      } else if (desc instanceof AlterMaterializedViewRewriteDesc) {
        AlterMaterializedViewRewriteDesc alterMVRewriteDesc = (AlterMaterializedViewRewriteDesc)desc;
        String tableName = alterMVRewriteDesc.getMaterializedViewName();
        boolean retrieveAndInclude = alterMVRewriteDesc.isRewriteEnable();
        boolean disableRewrite = !alterMVRewriteDesc.isRewriteEnable();
        MaterializedViewUpdateDesc materializedViewUpdateDesc =
            new MaterializedViewUpdateDesc(tableName, retrieveAndInclude, disableRewrite, false);
        DDLWork ddlWork = new DDLWork(inputs, outputs, materializedViewUpdateDesc);
        targetTask.addDependentTask(TaskFactory.get(ddlWork, conf));
      }
    }
  }
TaskCompiler is the base class for classes that compile
operator pipelines into tasks.
ql/src/java/org/apache/hadoop/hive/ql/parse/TaskCompiler.java