risingwavelabs/risingwave · error
Type mismatched between else and case.
Error message
Type mismatched between else and case.
What it means
In `build_constant_lookup_expr`, the optional trailing ELSE clause must have the same return type as the CASE's declared return type. A mismatch would make the output column type inconsistent at runtime, so the builder rejects it during construction.
Source
Thrown at src/expr/impl/src/scalar/case.rs:288
let mut children = children;
let operand = children.remove(0);
let mut arms = HashMap::new();
// Build the `arms` with iterating over `when` & `then` clauses
let mut iter = children.into_iter().array_chunks();
for [when, then] in iter.by_ref() {
let Ok(Some(s)) = when.eval_const() else {
bail!("expect when expression to be const");
};
arms.insert(s, then);
}
let fallback = if let Some(else_clause) = iter.into_remainder().next() {
if else_clause.return_type() != return_type {
bail!("Type mismatched between else and case.");
}
Some(else_clause)
} else {
None
};
let BoxedExpression::Sync(operand) = operand else {
return Ok(ConstantLookupExpression::new(return_type, arms, fallback, operand).boxed());
};
let arms: Vec<_> = arms.into_iter().collect();
let sync_arms: HashMap<ScalarImpl, Arc<dyn SyncExpression>> = match try_convert_all(
arms,
|(key, expr)| match expr {
BoxedExpression::Sync(expr) => Ok((key, expr)),
expr @ BoxedExpression::Async(_) => Err((key, expr)),
},
|(key, expr)| (key, BoxedExpression::Sync(expr)),
) {View on GitHub (pinned to 6469eb736d)
Solutions
- Add an explicit cast on the ELSE clause to match the CASE return type.
- Verify the type inference pass assigned a common return type across all THEN/ELSE arms.
- Check for schema drift in the columns referenced by the ELSE expression.
Example fix
// before CASE key WHEN 1 THEN 'a' ELSE 42 END -- else is int, case is varchar // after CASE key WHEN 1 THEN 'a' ELSE 42::varchar END
Defensive patterns
Strategy: validation
Validate before calling
-- assert else type matches case return type before build -- app-side check: if (elseExpr.returnType !== caseReturnType) addCast(elseExpr, caseReturnType);
Prevention
- Always cast ELSE to the common CASE type explicitly.
- Verify return types of all THEN/ELSE arms when writing SQL.
- Watch for schema changes altering a column's type used in ELSE.
When it happens
Trigger: Building a constant-lookup CASE where the ELSE expression's DataType differs from the CASE return_type (e.g. ELSE returns INT when the CASE was typed as VARCHAR), typically when RETURN_TYPE coercion was skipped or types were declared incorrectly upstream.
Common situations: Hand-built expression trees; frontend type-inference bugs where implicit casts to the common type were not inserted; schema changes altering a column type used in ELSE.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- Expect Array Type
- Type mismatched between when clause and condition
- Join key types are not aligned: LHS: {outer_type:?}, RHS: {i
- Join key types are not aligned: LHS: {outer_type:?}, RHS: {i
- partition_spec_id should be a u64
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/6efafeef2d059e94.
Report an issue: GitHub.