public void doDistributedPlan() {
    this.distributedPlan = planner.doDistributionPlan(analysis, logicalPlan, context);

    // if is this Statement is ShowQueryStatement, set its instances to the highest priority, so
    // that the sub-tasks of the ShowQueries instances could be executed first.
    if (analysis.needSetHighestPriority()) {
      distributedPlan.getInstances().forEach(instance -> instance.setHighestPriority(true));
    }

    if (LOGGER.isDebugEnabled() && isQuery()) {
      LOGGER.debug(
          "distribution plan done. Fragment instance count is {}, details is: \n {}",
          distributedPlan.getInstances().size(),
          printFragmentInstances(distributedPlan.getInstances()));
    }

    // check timeout after building distribution plan because it could be time-consuming in some
    // cases.
    checkTimeOutForQuery();
  }
QueryExecution stores all the status of a query which is being prepared or running inside the MPP
frame. It takes three main responsibilities: 1. Prepare a query. Transform a query from statement
to DistributedQueryPlan with fragment instances. 2. Dispatch all the fragment instances to
corresponding physical nodes. 3. Collect and monitor the progress/states of this query.
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/QueryExecution.java