influxdata/influxdb · error

No statistics for input plan

Error message

No statistics for input plan

What it means

The per-plan statistics aggregation visitor keeps a stack of input statistics that must mirror the plan tree traversal: every child plan pushed statistics during pre_visit. When post_visit pops the stack and it is empty, the traversal invariant is broken; expect() panics with 'No statistics for input plan'.

Solutions

  1. Ensure every custom plan node is handled in pre_visit so its input statistics get pushed.
  2. Check the statistics source covers all node types in your plan (no unimplemented branches).
  3. Update the iox_query statistics aggregation after DataFusion version upgrades that alter plan structures.
  4. In a fork, replace expect with returning an internal-error Result for cleaner failure.

Example fix

// before
let statistics = self.statistics.pop_back().expect("No statistics for input plan");
// after
let statistics = self.statistics.pop_back().ok_or_else(|| {
    internal_err!("No statistics for input plan")
})?;
Defensive patterns

Strategy: try-catch

Validate before calling

// before running aggregation, ensure every plan node type is handled:
// walk the plan and confirm each node's children are known to the stats source
assert_plan_nodes_supported(&plan);

Try / catch

// this is a panic from expect(); catch via catch_unwind at integration boundaries only
let result = std::panic::catch_unwind(|| compute_statistics(&plan));
match result {
    Ok(stats) => stats,
    Err(_) => /* fall back to default statistics */,
}

Prevention

When it happens

Trigger: Running the statistics aggregation over a logical plan where a custom/modified plan node or an overridden pre_visit skipped pushing statistics for a child, so post_visit finds the stack empty.

Common situations: Integrating custom LogicalPlan nodes not recognized by the statistics source; patched DataFusion plan visitors; bugs in statistics collection after planner upgrades changing node child counts.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


AI-assisted analysis of influxdata/influxdb@06200ef96b (2026-09-19). Data as JSON: /api/errors/f37d74bd784bbee8. Report an issue: GitHub.

Appendix: source

Thrown at core/iox_query/src/statistics/aggregate_per_plan.rs:190

                    .is_some()
            {
                true
            } else if plan.as_any().downcast_ref::<ProjectionExec>().is_some() {
                // ProjectionExec is a special case. Only union stats if it includes pure columns
                projection_includes_pure_columns(
                    plan.as_any().downcast_ref::<ProjectionExec>().unwrap(),
                )
            } else {
                false
            };

            // pop statistics of all inputs from the stack
            let num_inputs = plan.children().len();
            // num_input must > 0. Pop the first one
            let mut statistics = self
                .statistics
                .pop_back()
                .expect("No statistics for input plan");
            // pop the rest and update the min and max
            for _ in 1..num_inputs {
                let input_statistics = self
                    .statistics
                    .pop_back()
                    .expect("No statistics for input plan");

                if union_stats {
                    // Conservatively union min max
                    statistics.null_count = statistics.null_count.add(&input_statistics.null_count);
                    statistics.max_value = statistics.max_value.max(&input_statistics.max_value);
                    statistics.min_value = statistics.min_value.min(&input_statistics.min_value);
                    statistics.distinct_count = Precision::Absent;
                };
            }

            if union_stats {
                self.statistics.push_back(statistics);

View on GitHub (pinned to 06200ef96b)