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

  1. Sort split_times ascending and deduplicate before calling split_plan.
  2. Derive boundaries from sorted chunk statistics (min/max time).
  3. Validate strict monotonicity at the call site and reject the reorg request otherwise.
  4. 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

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


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)