databendlabs/databend · error

internal error: entered unreachable code

Error message

internal error: entered unreachable code

What it means

replace_query_s_expr destructures self with a let-else expecting the Plan::Query variant; any other Plan variant hits `unreachable!()`. The function is public but is only meant to be called on query plans (rewriting the s_expr of a bound SELECT), so callers passing Explain/Insert/DDL plans violate the function's contract and panic.

Solutions

  1. Guard call sites: only invoke replace_query_s_expr after matching Plan::Query.
  2. Replace the let-else `unreachable!()` with returning an error (e.g. ErrorCode::Internal) naming the received plan variant.
  3. Consider making the method take a Query plan by construction to eliminate the bad call shape.
  4. Add a debug log of the plan variant before the destructure when debugging.

Example fix

// before
} else {
    unreachable!()
};
// after
} else {
    return Err(ErrorCode::Internal("replace_query_s_expr called on non-Query plan"));
};
Defensive patterns

Strategy: type-guard

Validate before calling

// In Rust call sites, narrow before calling:
if let Plan::Query { .. } = &plan {
    let new_plan = plan.replace_query_s_expr(s_expr, metadata, bind_context, ...)?;
}

Type guard

fn is_query_plan(p: &Plan) -> bool { matches!(p, Plan::Query { .. }) }

Prevention

When it happens

Trigger: Calling Plan::replace_query_s_expr on a non-Query plan — e.g. invoking it from a rewrite pass that also handles EXPLAIN, INSERT, or catalog plans without checking the variant first.

Common situations: Hit by internal optimizer passes that rewrite materialized-view or query plans and forget to filter to Plan::Query; users see it as an internal error during query preparation.

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/e0759067697b9a9d. Report an issue: GitHub.

Appendix: source

Thrown at src/query/sql/src/planner/plans/plan.rs:739

    pub fn bind_context(&self) -> Option<BindContext> {
        if let Plan::Query { bind_context, .. } = self {
            Some(*bind_context.clone())
        } else {
            None
        }
    }

    pub fn replace_query_s_expr(&self, s_expr: SExpr) -> Self {
        let Plan::Query {
            metadata,
            bind_context,
            rewrite_kind,
            formatted_ast,
            ignore_result,
            ..
        } = self
        else {
            unreachable!()
        };

        Plan::Query {
            s_expr: Box::new(s_expr),
            metadata: metadata.clone(),
            bind_context: bind_context.clone(),
            rewrite_kind: rewrite_kind.clone(),
            formatted_ast: formatted_ast.clone(),
            ignore_result: *ignore_result,
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]

View on GitHub (pinned to 288d84d76e)