databendlabs/databend · error
internal error: entered unreachable code
Error message
internal error: entered unreachable code
What it means
RuleNormalizeScalar's apply_matcher destructures the matched plan expecting only Scan or EvalScalar shapes; any other RelOperator reaching the arm panics with "internal error: entered unreachable code". The rule's matchers are supposed to guarantee the two supported shapes, so this panic marks a divergence between matcher declarations and the patterns handled in apply_matcher.
Solutions
- Compare matchers() against every arm of the match in apply_matcher; extend the match to cover each declared matcher.
- Reproduce with the failing query and dump the S-expression to identify the unmatched operator.
- Replace `_ => unreachable!()` with `_ => Ok(())` / no-op so unmatched shapes are skipped instead of panicking.
- Add a unit test asserting apply_matcher is total over the rule's declared matchers.
Example fix
// before _ => unreachable!(), // after _ => Ok(()),
Defensive patterns
Strategy: try-catch
Try / catch
// Wrap query submission; on planner panic, simplify and retry
let res = exec(sql);
if let Err(e) = &res, e.to_string().contains("internal error") {
exec(simplify_predicates(sql));
} Prevention
- Keep pushdown predicates (WHERE over scans/projections) in forms already supported by the rule.
- After adding new matchers to a rule, audit the corresponding match arms.
- Add regression tests covering every declared matcher.
- Report new operator variants introduced by upgrades that bypass scalar normalization.
When it happens
Trigger: A matcher (e.g. Operator::EvalScalar or Operator::Scan) matched an S-expression whose actual plan body is another operator variant — commonly after adding a new matcher without extending the match in apply_matcher.
Common situations: Hit during scalar normalization (predicate pushdown into scans) when planner rule sets change or when a new logical operator is introduced without updating this rule.
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
- internal error: entered unreachable code
- internal error: entered unreachable code
- internal error: entered unreachable code
- {}
- Temp table id used up
AI-assisted analysis of databendlabs/databend@288d84d76e (2026-09-11).
Data as JSON: /api/errors/24e66a90d2cc3a57.
Report an issue: GitHub.
Appendix: source
Thrown at src/query/sql/src/planner/optimizer/optimizers/rule/scalar_rules/rule_normalize_scalar.rs:96
return Ok(());
};
state.add_result(s_expr.replace_plan(Filter { predicates }));
Ok(())
}
1 => {
let scan = s_expr.plan.as_scan().unwrap();
let Some(predicates) = &scan.push_down_predicates else {
return Ok(());
};
let Some(predicates) = RewritePredicates {}.rewrite(predicates)? else {
return Ok(());
};
let mut scan = scan.clone();
scan.push_down_predicates = Some(predicates);
state.add_result(s_expr.replace_plan(scan));
Ok(())
}
_ => unreachable!(),
}
}
fn matchers(&self) -> &[Matcher] {
&self.matchers
}
}
impl Default for RuleNormalizeScalarFilter {
fn default() -> Self {
Self::new()
}
}
struct RewritePredicates {}
impl RewritePredicates {
fn rewrite(&mut self, predicates: &[ScalarExpr]) -> Result<Option<Vec<ScalarExpr>>> {View on GitHub (pinned to 288d84d76e)