databendlabs/databend · error
internal error: entered unreachable code
Error message
internal error: entered unreachable code
What it means
Inside outer_join_to_anti_join, the null-tested equi-condition check matches on JoinType::Left and JoinType::Right only; any other join type (e.g. Full/Semi/Mark) inside the matched condition hits `unreachable!()`. The enclosing logic is supposed to only run this check on plain outer joins, so this panic means an unexpected join type reached the condition scan.
Solutions
- Confirm the rule's matcher only fires for Left/Right outer joins with a NULL-test filter on the non-preserved side.
- Inspect the S-expression right before the panic to see the actual join_type.
- Make the match defensive: return false for unexpected join types inside the closure instead of panicking.
- Re-run the failing query on a recent build to check whether a known optimizer fix already covers it.
Example fix
// before _ => unreachable!(), // after _ => false,
Defensive patterns
Strategy: try-catch
Try / catch
// Catch at query execution layer and fall back to a rewritten query
match run(query) {
Err(e) if is_internal_planner_error(&e) => run(rewrite_anti_join_manually(query)),
r => r,
} Prevention
- Prefer writing NOT EXISTS with an explicit join instead of LEFT JOIN ... WHERE right IS NULL anti-join idioms.
- Keep outer-join + IS NULL filter patterns simple so rule eligibility checks are exercised less.
- Upgrade once the optimizer fix for outer-join-to-anti-join lands.
- Run EXPLAIN RAW on affected queries in staging before production deploys.
When it happens
Trigger: A filter-over-outer-join pattern being converted to anti join where the join_type is no longer Left/Right at the point of the equi_conditions check — e.g. after another rule mutated join_type, or the rule's eligibility pre-check missed a join kind.
Common situations: Seen when optimizing queries like SELECT ... FROM a LEFT JOIN b ... WHERE b.x IS NULL after optimizer refactors; surfaces as an internal error panic during planning.
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/a8486d631b9f5519.
Report an issue: GitHub.
Appendix: source
Thrown at src/query/sql/src/planner/optimizer/optimizers/rule/join_rules/push_down_filter_join/outer_join_to_anti_join.rs:61
let join_expr = s_expr.unary_child();
let join = join_expr.plan().as_join().unwrap();
let anti_join_type = match join.join_type {
JoinType::Left => JoinType::LeftAnti,
JoinType::Right => JoinType::RightAnti,
_ => return Ok(None),
};
let Some(predicate_index) = filter.predicates.iter().position(|predicate| {
let Some(null_tested_expr) = null_tested_expr(predicate) else {
return false;
};
join.equi_conditions.iter().any(|condition| {
!condition.is_null_equal
&& match join.join_type {
JoinType::Left => condition.right == *null_tested_expr,
JoinType::Right => condition.left == *null_tested_expr,
_ => unreachable!(),
}
})
}) else {
return Ok(None);
};
// An anti join outputs only its preserved side, while the original
// outer-join/filter shape still exposes the other side as NULL. Recreate
// those symbols so upper operators preserve their schema.
let null_extended_prop = match join.join_type {
JoinType::Left => join_expr.right_child().derive_relational_prop()?,
JoinType::Right => join_expr.left_child().derive_relational_prop()?,
_ => unreachable!(),
};
let metadata = metadata.read();
let null_items = null_extended_prop
.output_columns
.iter()View on GitHub (pinned to 288d84d76e)