databendlabs/databend · critical
a partially folded top-level cast must remain a cast
Error message
a partially folded top-level cast must remain a cast
What it means
A defensive assertion in Databend's scalar function resolver: after constant folding, the code expects that any expression still needing a cast remains a top-level CastExpr. If the folded expression has a different shape, the match arm fails and panics with "a partially folded top-level cast must remain a cast". It indicates the constant folder produced an expression shape the resolver did not anticipate.
Solutions
- Simplify the query: hoist constant casts out of IN lists / OR chains into literals or separate expressions
- Apply casts explicitly to columns rather than to deeply nested constant expressions
- Reduce the query to a minimal reproducer and test against the latest Databend release — this is a folder regression likely already fixed upstream
- Report the bug with the failing SQL if it reproduces on the latest version
Example fix
// before
SELECT * FROM t WHERE a IN (CAST('1' AS INT) + 1, 3);
// after: precompute the constant
SELECT * FROM t WHERE a IN (2, 3); Defensive patterns
Strategy: fallback
Validate before calling
-- avoid deep constant-folded casts inside IN/OR predicates
-- precompute: SELECT CAST('1' AS INT) + 1; and inline the literal Try / catch
match res {
Err(e) if e.to_string().contains("partially folded top-level cast") => {
// rewrite query with precomputed constants and retry
}
r => r,
} Prevention
- Precompute constant expressions in application code or via literals instead of nested casts inside predicates
- Keep Databend up to date — folding regressions are fixed quickly upstream
- Simplify OR/IN predicates with explicit literal values
When it happens
Trigger: resolve_scalar_function_call folding arguments of casts/functions (reached via resolve_in_list, merge_or_level, fold_or_levels, resolve_array/map/tuple) where the folding of a CAST expression rewrites the top-level node into something other than CastExpr — e.g. nested casts of constant expressions under unusual type combinations.
Common situations: Complex constant expressions mixing casts, arrays, tuples, and OR-lists (e.g. WHERE x IN (...CAST...)) in queries run against a version where the folder was recently changed; upgraded Databend binaries where a folding optimization regressed.
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
- unexpected value type for grouping function
- Unsupported unit
- internal error: entered unreachable code
- internal error: entered unreachable code
- internal error: entered unreachable code
AI-assisted analysis of databendlabs/databend@288d84d76e (2026-09-11).
Data as JSON: /api/errors/f2c6f133cd29a048.
Report an issue: GitHub.
Appendix: source
Thrown at src/query/sql/src/planner/semantic/type_check/scalar_function.rs:686
if !expr.is_deterministic(&BUILTIN_FUNCTIONS) {
self.adapter.set_result_cache_uncacheable();
}
let expr = match self.try_fold_constant(expr) {
Ok(constant) => return Ok(constant),
Err(expr) => expr,
};
if is_top_level_cast {
let expr::Expr::Cast(expr::Cast {
span,
is_try,
dest_type,
..
}) = expr
else {
unreachable!("a partially folded top-level cast must remain a cast");
};
assert_eq!(folded_args.len(), 1);
return Ok(Box::new((
CastExpr {
span,
is_try,
argument: Box::new(folded_args.pop().unwrap()),
target_type: Box::new(dest_type.clone()),
}
.into(),
dest_type,
)));
}
// reorder
if func_name == "eq"
&& folded_args.len() == 2
&& matches!(folded_args[0], ScalarExpr::ConstantExpr(_))View on GitHub (pinned to 288d84d76e)