citus icon indicating copy to clipboard operation
citus copied to clipboard

EXPLAIN ANALYZE - Prevent execution of the plan during the plan-print

Open tejeswarm opened this issue 9 months ago • 2 comments

DESCRIPTION: Fixed a bug in EXPLAIN ANALYZE to prevent unintended (duplicate) execution of the plan during the plan-print phase.

Fixes #4212

🐞 Bug #4212 : Redundant (Subplan) Execution in EXPLAIN ANALYZE codepath

🔍 Background

In the standard PostgreSQL execution path, ExplainOnePlan() is responsible for two distinct operations depending on whether EXPLAIN ANALYZE is requested:

  1. Execute the plan

    if (es->analyze)
        ExecutorRun(queryDesc, direction, 0L, true);
    
  2. Print the plan tree

    ExplainPrintPlan(es, queryDesc);
    

When printing the plan, the executor should not run the plan again. Execution is only expected to happen once—at the top level when es->analyze = true.


⚠️ Issue in Citus

In the Citus implementation of CustomScanMethods.ExplainCustomScan = CitusExplainScan, which is a custom scan explain callback function used to print explain information of a Citus plan incorrectly performs redundant execution inside the explain path of ExplainPrintPlan()

ExplainOnePlan()
  ExplainPrintPlan()
      ExplainNode()
        CitusExplainScan()
          if (distributedPlan->subPlanList != NIL)
          {
              ExplainSubPlans(distributedPlan, es);
             {
              PlannedStmt *plan = subPlan->plan;
              ExplainOnePlan(plan, ...);  // ⚠️ May re-execute subplan if es->analyze is true
             }
         }

This causes the subplans to be executed again, even though they have already been executed during the top-level plan execution. This behavior violates the expectation in PostgreSQL where EXPLAIN ANALYZE should execute each node exactly once for analysis.


✅ Fix (proposed)

To align with PostgreSQL’s expectations and avoid double execution:

es->analyze = false;
es->timing = false;

is now set explicitly in ExplainSubPlans() before recursively calling ExplainOnePlan(). This ensures that subplans are explained for shape only—not executed again.


tejeswarm avatar May 20 '25 23:05 tejeswarm