influxdata/influxdb · error
split_times[ ]: must be smaller than split_times[ ]
Error message
split_times[{}]: {} must be smaller than split_times[{}]: {} What it means
split_plan requires split_times to be strictly increasing: each entry must be smaller than the next, since they generate a chain of (time <= split_times[i]) predicates. A non-increasing pair would produce empty or overlapping plans, so the function panics naming the offending indices and values.
Solutions
- Sort split_times ascending and deduplicate before calling split_plan.
- Derive boundaries from sorted chunk statistics (min/max time).
- Validate strict monotonicity at the call site and reject the reorg request otherwise.
- For frequent external input, wrap split_plan behind a function returning Result instead of panicking.
Example fix
// before db.split_plan(&t, &schema, chunks, &[200, 100])?; // after let mut split_times = vec![200, 100]; split_times.sort_unstable(); split_times.dedup(); db.split_plan(&t, &schema, chunks, &split_times)?;
Defensive patterns
Strategy: validation
Validate before calling
let mut split_times = split_times; split_times.sort_unstable(); split_times.dedup(); assert!(split_times.windows(2).all(|w| w[0] < w[1]), "split_times must be strictly increasing");
Try / catch
// panic-based invariant: validate strictly increasing order before calling assert!(split_times.windows(2).all(|w| w[0] < w[1])); let plan = split_plan(...);
Prevention
- Always sort and dedup split_times before calling split_plan.
- Derive boundaries from sorted chunk statistics rather than ad-hoc lists.
- Add a unit test asserting monotonicity of boundary computation.
When it happens
Trigger: Calling split_plan with split_times containing duplicates (split_times[i-1] == split_times[i]) or a descending pair (split_times[i-1] > split_times[i]).
Common situations: Split boundaries derived from unsorted chunk max timestamps; deduplication removed but did not sort boundary candidates; hand-written split times in tests.
Related errors
- Split plan does not accept empty split_times
- Key column, , of current batch has no data
- Key column, , of last_batch has no data
- No statistics for input plan
- at least one expr
AI-assisted analysis of influxdata/influxdb@06200ef96b (2026-09-19).
Data as JSON: /api/errors/9d621055fb348cc7.
Report an issue: GitHub.
Appendix: source
Thrown at core/iox_query/src/frontend/reorg.rs:215
table_id,
})?;
let plan_builder = Arc::new(provider)
.into_logical_plan_builder()
.context(BuildingPlanSnafu)?;
let sort_expr = logical_sort_key_exprs(&output_sort_key);
let plan = plan_builder
.sort(sort_expr)
.context(BuildingPlanSnafu)?
.build()
.context(BuildingPlanSnafu)?;
let mut split_exprs = Vec::with_capacity(split_times.len());
// time <= split_times[0]
split_exprs.push(col(TIME_COLUMN_NAME).lt_eq(lit_timestamptz_nano(split_times[0])));
// split_times[i-1] , time <= split_time[i]
for i in 1..split_times.len() {
if split_times[i - 1] >= split_times[i] {
panic!(
"split_times[{}]: {} must be smaller than split_times[{}]: {}",
i - 1,
split_times[i - 1],
i,
split_times[i]
);
}
split_exprs.push(
col(TIME_COLUMN_NAME)
.gt(lit_timestamptz_nano(split_times[i - 1]))
.and(col(TIME_COLUMN_NAME).lt_eq(lit_timestamptz_nano(split_times[i]))),
);
}
let plan = make_stream_split(plan, split_exprs);
debug!(table_name=table_name.as_ref(), table_id=%table_id, plan=%plan.display_indent_schema(),
"created split plan for table");
View on GitHub (pinned to 06200ef96b)