influxdata/influxdb · error
should have a single merged statistic
Error message
should have a single merged statistic
What it means
Panics via `.expect("should have a single merged statistic")` in RepartitionExec::statistics_by_partition. merge_partitions_no_projection is expected to return exactly one merged Statistics entry for repartitioned input; if it returns zero entries, the pop panics. This signals that input partition statistics were never produced.
Solutions
- Verify the child executor of RepartitionExec reports statistics for its partitions
- Make merge_partitions_no_projection return an error instead of an empty vec when inputs have no statistics
- File a bug if this occurs with stock IOx/DataFusion plans
Example fix
// before
let merged_single = merged.pop().expect("should have a single merged statistic");
// after
let merged_single = merged.pop().ok_or_else(|| {
internal_datafusion_err!("repartition input produced no merged statistics")
})?; Defensive patterns
Strategy: try-catch
Validate before calling
if child.statistics()?.partition_statistics.is_empty() { /* skip repartition stats path */ } Try / catch
// wrap statistics_by_partition in catch_unwind for custom executors let res = std::panic::catch_unwind(|| exec.statistics_by_partition());
Prevention
- Ensure child executors always report statistics
- Return Err instead of empty vecs from merge helpers
- Test RepartitionExec over statistics-less sources
When it happens
Trigger: Calling statistics_by_partition on a RepartitionExec whose input yielded no partition statistics (empty merged vec), typically because the child executor's statistics are unavailable or the child plan has no partitions.
Common situations: Custom child executors returning empty statistics vectors; plans where repartition sits on top of a source that reports no row statistics; regressions after changing merge_partitions_no_projection.
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
- min ( ) > max ( )
- should not be absent
- sorted column is not in the schema
- column id in series key should be valid
- duration not to overflow
AI-assisted analysis of influxdata/influxdb@06200ef96b (2026-09-19).
Data as JSON: /api/errors/6320f072a16d6790.
Report an issue: GitHub.
Appendix: source
Thrown at core/iox_query/src/statistics/partition_statistics/mod.rs:258
}
impl PartitionStatistics for SortExec {
fn statistics_by_partition(&self) -> Result<PartitionedStatistics> {
if self.preserve_partitioning() {
preserve_partitioning_no_projection_apply_fetch(self, self.fetch(), 0)
} else {
merge_partitions_no_projection_apply_fetch(self, self.fetch(), 0)
}
}
}
impl PartitionStatistics for RepartitionExec {
fn statistics_by_partition(&self) -> Result<PartitionedStatistics> {
// takes N input partitions, returning M output partitions.
// the statistics are "merged" into the same value (because any input can go to any output)
let mut merged = merge_partitions_no_projection(self)?;
let merged_single = merged.pop().expect("should have a single merged statistic");
let merged_single = Arc::unwrap_or_clone(merged_single);
// then the merged stat is turned to inexact (since unknown division across output partitions)
let inexact_merged = Arc::new(Statistics {
num_rows: Precision::Absent,
total_byte_size: Precision::Absent,
column_statistics: make_column_statistics_inexact(merged_single.column_statistics),
});
// finally, all output partitions have the same merged stat
Ok(vec![inexact_merged; partition_count(self)])
}
}
impl PartitionStatistics for AggregateExec {
fn statistics_by_partition(&self) -> Result<PartitionedStatistics> {
if self.aggr_expr().is_empty() {
let inner_stats_per_partition = statistics_by_partition(self.input.as_ref())?;View on GitHub (pinned to 06200ef96b)