{"record":{"id":"9d621055fb348cc7","repo":"influxdata/influxdb","slug":"split-times-must-be-smaller-than-split-times","errorCode":null,"errorMessage":"split_times[{}]: {} must be smaller than split_times[{}]: {}","messagePattern":"split_times\\[(.+?)\\]: (.+?) must be smaller than split_times\\[(.+?)\\]: (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/iox_query/src/frontend/reorg.rs","lineNumber":215,"sourceCode":"            table_id,\n        })?;\n        let plan_builder = Arc::new(provider)\n            .into_logical_plan_builder()\n            .context(BuildingPlanSnafu)?;\n        let sort_expr = logical_sort_key_exprs(&output_sort_key);\n        let plan = plan_builder\n            .sort(sort_expr)\n            .context(BuildingPlanSnafu)?\n            .build()\n            .context(BuildingPlanSnafu)?;\n\n        let mut split_exprs = Vec::with_capacity(split_times.len());\n        // time <= split_times[0]\n        split_exprs.push(col(TIME_COLUMN_NAME).lt_eq(lit_timestamptz_nano(split_times[0])));\n        // split_times[i-1] , time <= split_time[i]\n        for i in 1..split_times.len() {\n            if split_times[i - 1] >= split_times[i] {\n                panic!(\n                    \"split_times[{}]: {} must be smaller than split_times[{}]: {}\",\n                    i - 1,\n                    split_times[i - 1],\n                    i,\n                    split_times[i]\n                );\n            }\n            split_exprs.push(\n                col(TIME_COLUMN_NAME)\n                    .gt(lit_timestamptz_nano(split_times[i - 1]))\n                    .and(col(TIME_COLUMN_NAME).lt_eq(lit_timestamptz_nano(split_times[i]))),\n            );\n        }\n        let plan = make_stream_split(plan, split_exprs);\n\n        debug!(table_name=table_name.as_ref(), table_id=%table_id, plan=%plan.display_indent_schema(),\n               \"created split plan for table\");\n","sourceCodeStart":197,"sourceCodeEnd":233,"githubUrl":"https://github.com/influxdata/influxdb/blob/06200ef96ba82c5f6727e5038a83af8e722c6875/core/iox_query/src/frontend/reorg.rs#L197-L233","documentation":"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.","triggerScenarios":"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]).","commonSituations":"Split boundaries derived from unsorted chunk max timestamps; deduplication removed but did not sort boundary candidates; hand-written split times in tests.","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."],"exampleFix":"// before\ndb.split_plan(&t, &schema, chunks, &[200, 100])?;\n// after\nlet mut split_times = vec![200, 100];\nsplit_times.sort_unstable();\nsplit_times.dedup();\ndb.split_plan(&t, &schema, chunks, &split_times)?;","handlingStrategy":"validation","validationCode":"let mut split_times = split_times;\nsplit_times.sort_unstable();\nsplit_times.dedup();\nassert!(split_times.windows(2).all(|w| w[0] < w[1]), \"split_times must be strictly increasing\");","typeGuard":null,"tryCatchPattern":"// panic-based invariant: validate strictly increasing order before calling\nassert!(split_times.windows(2).all(|w| w[0] < w[1]));\nlet plan = split_plan(...);","preventionTips":["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."],"tags":["query","reorg","panic","argument-out-of-range"],"backgroundTag":"argument-out-of-range","analyzedSha":"06200ef96ba82c5f6727e5038a83af8e722c6875","analyzedAt":"2026-09-19T12:55:30.003Z","contentChangedAt":"2026-09-19T12:55:30.003Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}