public LogicalQueryPlan plan(Analysis analysis) {
    long startTime = System.nanoTime();
    PlanNode rootNode =
        new LogicalPlanVisitor(analysis).process(analysis.getTreeStatement(), context);

    // optimize the query logical plan
    if (analysis.isQuery()) {

      long planFinishTime = System.nanoTime();
      long logicalPlanCost = planFinishTime - startTime;
      context.setLogicalPlanCost(logicalPlanCost);
      QueryPlanCostMetricSet.getInstance().recordTreePlanCost(LOGICAL_PLANNER, logicalPlanCost);

      for (PlanOptimizer optimizer : optimizers) {
        rootNode = optimizer.optimize(rootNode, analysis, context);
      }
      long logicalOptimizationCost = System.nanoTime() - planFinishTime;
      context.setLogicalOptimizationCost(logicalOptimizationCost);
      QueryPlanCostMetricSet.getInstance()
          .recordTreePlanCost(LOGICAL_PLAN_OPTIMIZE, logicalOptimizationCost);
    }

    return new LogicalQueryPlan(context, rootNode);
  }
Generate a logical plan for the statement.
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/LogicalPlanner.java