You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Unparser silently drops CASE operand and ELSE branch when they fail to unparse #26295
When unparsing Expr::Case, Unparser::expr_to_sql_inner discards errors from the CASE operand and the ELSE branch instead of returning them (unparser/expr.rs#L249-L262):
let operand = match expr.as_ref(){Some(e) => matchself.expr_to_sql_inner(e){Ok(sql_expr) => Some(Box::new(sql_expr)),Err(_) => None,},None => None,};let else_result = match else_expr.as_ref(){Some(e) => matchself.expr_to_sql_inner(e){Ok(sql_expr) => Some(Box::new(sql_expr)),Err(_) => None,},None => None,};
If the operand fails to unparse, CASE x WHEN 1 THEN ... END is emitted as CASE WHEN 1 THEN ... END, a searched CASE with different semantics. If the ELSE expression fails, the ELSE branch is silently dropped, so the generated SQL returns NULL where the plan returns a value. In both cases the caller gets valid-looking SQL that means something else, with no error.
The WHEN/THEN conditions immediately above already propagate errors with ?, so this looks unintentional.
To Reproduce
Unparse a CASE expression whose operand or ELSE expression is one the unparser cannot handle (any sub-expression for which expr_to_sql_inner returns an error). The resulting SQL omits the operand or the ELSE branch instead of returning that error.
Expected behavior
plan_to_sql / expr_to_sql return the error from the operand or ELSE expression, the same way they do for WHEN/THEN expressions:
let operand = expr.as_ref().map(|e| self.expr_to_sql_inner(e).map(Box::new)).transpose()?;let else_result = else_expr.as_ref().map(|e| self.expr_to_sql_inner(e).map(Box::new)).transpose()?;
Activity
fix: propagate CASE unparser errors (apache#26311)