risingwavelabs/risingwave · error
Type mismatched between when clause and condition
Error message
Type mismatched between when clause and condition
What it means
In `build_case_expr`, every WHEN condition expression must return BOOLEAN, since CASE conditions are logically evaluated as predicates. A non-boolean WHEN type means the query plan is malformed, so the builder rejects it.
Source
Thrown at src/expr/impl/src/scalar/case.rs:349
.boxed());
}
None => None,
};
Ok(ConstantLookupExpression::new(return_type, sync_arms, fallback, operand).boxed())
}
#[build_function("case(...) -> any", type_infer = "unreachable")]
fn build_case_expr(
return_type: DataType,
children: Vec<BoxedExpression>,
) -> Result<BoxedExpression> {
// children: (when, then)+, (else_clause)?
let len = children.len();
let mut when_clauses = Vec::with_capacity(len / 2);
let mut iter = children.into_iter().array_chunks();
for [when, then] in iter.by_ref() {
if when.return_type() != DataType::Boolean {
bail!("Type mismatched between when clause and condition");
}
if then.return_type() != return_type {
bail!("Type mismatched between then clause and case");
}
when_clauses.push(WhenClause { when, then });
}
let else_clause = 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 sync_when_clauses = match try_convert_all(
when_clauses,
|WhenClause { when, then }| match (when, then) {View on GitHub (pinned to 6469eb736d)
Solutions
- Wrap the condition in an explicit comparison: `CASE WHEN col = 1 THEN ...` instead of `CASE WHEN col THEN ...`.
- Add an explicit cast/comparison so the condition is boolean.
- Verify the frontend type coercion rules for searched CASE conditions.
Example fix
// before CASE WHEN status THEN 'active' ELSE 'inactive' END -- status is int // after CASE WHEN status = 1 THEN 'active' ELSE 'inactive' END
Defensive patterns
Strategy: validation
Validate before calling
-- ensure condition is boolean before CASE CASE WHEN status = 1 THEN ... -- not CASE WHEN status THEN ... -- app-side guard: if (whenExpr.returnType !== 'boolean') wrapInComparison(whenExpr);
Prevention
- Never rely on truthy integer semantics in searched CASE.
- Always write conditions as explicit boolean comparisons.
- Check for schema drift turning boolean columns into other types.
When it happens
Trigger: `build_case_expr` receiving a (when, then) pair whose `when` expression's return type is not `DataType::Boolean` — e.g. an integer used directly as a condition without an explicit comparison, or a planner that failed to insert a boolean cast.
Common situations: Porting SQL that relies on non-standard truthy semantics (e.g. `CASE x WHEN 1 THEN ...` translated incorrectly to searched CASE); frontend type inference bugs; schema changes turning a boolean column into int.
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
- failed to evaluate the input for fallback arm
- failed to evaluate the input for normal arm
- failed to lookup and evaluate the expression in `eval`
- Type mismatched between else and case.
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/2c162baf579fffcb.
Report an issue: GitHub.