@Override
  public void init() throws IOException {
    QueryContext queryContext = new QueryContext(masterContext.getConf());
    currentRow = 0;

    MasterPlan masterPlan = new MasterPlan(queryId, queryContext, logicalPlan);
    GlobalPlanner globalPlanner =
        new GlobalPlanner(masterContext.getConf(), masterContext.getCatalog());
    try {
      globalPlanner.build(queryContext, masterPlan);
    } catch (PlanningException e) {
      throw new RuntimeException(e);
    }

    ExecutionBlockCursor cursor = new ExecutionBlockCursor(masterPlan);
    ExecutionBlock leafBlock = null;
    for (ExecutionBlock block : cursor) {
      if (masterPlan.isLeaf(block)) {
        leafBlock = block;
        break;
      }
    }

    if (leafBlock == null) {
      throw new InvalidQueryException("Global planner could not find any leaf block.");
    }

    taskContext =
        new TaskAttemptContext(
            queryContext, null, new TaskAttemptId(new TaskId(leafBlock.getId(), 0), 0), null, null);
    physicalExec =
        new SimplePhysicalPlannerImpl(masterContext.getConf())
            .createPlan(taskContext, leafBlock.getPlan());

    tableDesc =
        new TableDesc(
            "table_" + System.currentTimeMillis(),
            physicalExec.getSchema(),
            new TableMeta("SYSTEM", new KeyValueSet()),
            null);
    outSchema = physicalExec.getSchema();
    encoder = RowStoreUtil.createEncoder(getLogicalSchema());

    physicalExec.init();
  }