databendlabs/databend · error
not implemented
Error message
not implemented
What it means
In PhysicalSort's build_pipeline2, when a sort step leaves the main pipeline with more than one output and max_threads == 1, the code deliberately panics with unimplemented!() — the comment notes the query would otherwise hang in MultiSortMergeProcessor. So single-threaded execution of this sort shape is unsupported and raises 'not implemented'.
Solutions
- Increase max_threads to >= 2 for the session/query (SET max_threads = 2 or higher).
- Remove/adjust settings or resource-group limits that pin execution to a single thread.
- Rewrite the query to avoid the multi-output sort shape, or add an explicit LIMIT that lets the planner collapse outputs.
- For maintainers: replace the panic by merging outputs into one stream (resize pipeline) or fixing MultiSortMergeProcessor for max_threads == 1.
Example fix
-- before SET max_threads = 1; -- then ORDER BY query panics -- after SET max_threads = 4;
Defensive patterns
Strategy: validation
Validate before calling
-- ensure multi-threaded execution for sort-heavy queries
SELECT if(current_setting('max_threads')::int < 2, 'raise max_threads to >= 2', 'ok') AS check; Type guard
fn single_threaded(ctx: &dyn TableContext) -> bool { ctx.get_settings().get_max_threads().unwrap_or(1) <= 1 } Try / catch
match build_pipeline2(builder, ctx) {
Err(e) if e.to_string().contains("not implemented") && ctx.get_max_threads() == 1 => {
retry_with_min_threads(2)?
}
other => other?,
} Prevention
- Keep max_threads >= 2 in sessions that run ORDER BY queries.
- Avoid forcing max_threads = 1 globally or in resource-group limits.
- Add CI coverage for ORDER BY under single-thread settings to catch regressions early.
- For single-core environments, prefer queries whose plans avoid multi-output sort steps.
When it happens
Trigger: Executing a query with a sort (SortStep) whose pipeline output_len != 1 while running with max_threads == 1 (e.g. single-threaded query settings, constrained executor config, or resource-group limiting threads to 1).
Common situations: Environments that force single-threaded execution: setting max_threads=1 / max_threads setting to 1 in the query context, CI tests with single-thread runtimes, or resource-constrained deployments; certain ORDER BY queries then panic instead of completing.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- internal error: entered unreachable code
- internal error: entered unreachable code
- internal error: entered unreachable code
- Unsupported column type for encoding
- Unsupported column type for length calculation
AI-assisted analysis of databendlabs/databend@288d84d76e (2026-09-11).
Data as JSON: /api/errors/289a5d7245978c5e.
Report an issue: GitHub.
Appendix: source
Thrown at src/query/service/src/physical_plans/physical_sort.rs:290
Ok(())
}
SortStep::Shuffled => {
if Exchange::check_physical_plan(&self.input) {
let exchange = TransformSortBuilder::exchange_injector();
let old_inject = std::mem::replace(&mut builder.exchange_injector, exchange);
self.input.build_pipeline(builder)?;
builder.exchange_injector = old_inject;
} else {
self.input.build_pipeline(builder)?;
}
if builder.main_pipeline.output_len() == 1 {
return Ok(());
}
if max_threads == 1 {
// TODO(Winter): the query will hang in MultiSortMergeProcessor when max_threads == 1 and output_len != 1
unimplemented!();
}
sort_builder.build_bounded_merge_sort(&mut builder.main_pipeline)
}
SortStep::Route => {
if builder.main_pipeline.output_len() == 1 {
builder
.main_pipeline
.add_transformer(TransformSortBuilder::build_dummy_route);
Ok(())
} else {
TransformSortBuilder::add_route(&mut builder.main_pipeline)
}
}
}
}
}
impl Sort {View on GitHub (pinned to 288d84d76e)