databendlabs/databend · error

internal error: entered unreachable code

Error message

internal error: entered unreachable code

What it means

In the mark-join-to-semi-join rewrite, the code has already established (via mark_index checks) that the join is a LeftMark or RightMark join before this match; any other JoinType reaching the match violates that precondition and hits `unreachable!()`, panicking with "internal error: entered unreachable code". The invariant lives in the caller's filtering logic (mark_index lookup and outer-join type checks), not in this match itself.

Solutions

  1. Verify the mark_index used to locate the join actually corresponds to this join's output column (check metadata mark join index registration).
  2. Confirm the rule's matchers only select MarkJoin S-expressions.
  3. Replace `_ => unreachable!()` with `_ => return Ok((s_expr.clone(), false))` to skip ineligible joins defensively.
  4. Add a debug assertion/log of join_type before the match to ease diagnosis.

Example fix

// before
_ => unreachable!(),
// after
_ => return Ok((s_expr.clone(), false)),
Defensive patterns

Strategy: try-catch

Try / catch

// Session-level guard: treat internal errors as planner bugs
if err.message().contains("internal error: entered unreachable code") {
    retry_with_optimizer_disabled_or_simplified_query(err);
}

Prevention

When it happens

Trigger: Calling convert_mark_to_semi_join on a Join whose mark_index resolves but whose join_type is not LeftMark/RightMark — e.g. the wrong column index was extracted from the mark join cache, or the join was rewritten by another rule between selection and conversion.

Common situations: Occurs during optimization of queries with scalar subqueries / EXISTS rewritten into mark joins, typically after partial rule application or a bug in index bookkeeping in push_down_filter_join passes.

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


AI-assisted analysis of databendlabs/databend@288d84d76e (2026-09-11). Data as JSON: /api/errors/a21c2c9d17c3908d. Report an issue: GitHub.

Appendix: source

Thrown at src/query/sql/src/planner/optimizer/optimizers/rule/join_rules/push_down_filter_join/mark_join_to_semi_join.rs:68

            if col.column.index == mark_index {
                find_mark_index = true;
                filter.predicates.remove(idx);
                break;
            }
        }
        // Check if the predicate used mark, if so, we won't convert it to semi join
        return Ok((s_expr.clone(), false));
    }

    if !find_mark_index {
        // To be conservative, we do not convert
        return Ok((s_expr.clone(), false));
    }

    join.join_type = match join.join_type {
        JoinType::LeftMark => JoinType::RightSemi,
        JoinType::RightMark => JoinType::LeftSemi,
        _ => unreachable!(),
    };

    metadata.write().add_removed_mark_index(mark_index);

    // clear is null equal sign
    join.equi_conditions.iter_mut().for_each(|c| {
        c.is_null_equal = false;
    });

    let s_join_expr = s_expr.child(0)?;
    let mut result = SExpr::create_binary(
        Arc::new(join.into()),
        Arc::new(s_join_expr.child(0)?.clone()),
        Arc::new(s_join_expr.child(1)?.clone()),
    );

    if !filter.predicates.is_empty() {
        result = SExpr::create_unary(Arc::new(filter.into()), Arc::new(result));

View on GitHub (pinned to 288d84d76e)