risingwavelabs/risingwave · critical

internal error: entered unreachable code

Error message

internal error: entered unreachable code

What it means

After binding CREATE INDEX columns, each index expression must be either a plain column reference (InputRef) or a function call; anything else is an invariant violation and hits unreachable!(). The binder is expected to have normalized/rejected other expression shapes earlier.

Solutions

  1. Simplify the index expression to plain columns or simple function calls
  2. Index only supported expression forms (columns and deterministic function calls)
  3. Report the SQL to RisingWave if a valid-looking expression triggers this — it is likely a bug

Example fix

-- before
CREATE INDEX idx ON t (1 + 2); -- non-column/function expr
-- after
CREATE INDEX idx ON t (col_a, upper(col_b));
Defensive patterns

Strategy: validation

Validate before calling

-- Verify index expressions are columns or function calls only
CREATE INDEX idx ON t (col_a, fn(col_b)); -- allowed forms

Prevention

When it happens

Trigger: CREATE INDEX ON t (expr) where expr survives as an ExprImpl variant other than InputRef or FunctionCall (e.g. a subquery, literal, or unnormalized expression) reaching the filter in gen_create_index_plan.

Common situations: Indexing expressions the binder didn't fully normalize; SQL dialect edges where a complex expression slips past earlier validation.

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 risingwavelabs/risingwave@6469eb736d (2026-09-11). Data as JSON: /api/errors/144927b29ae819e9. Report an issue: GitHub.

Appendix: source

Thrown at src/frontend/src/handler/create_index.rs:316

        return Err(ErrorCode::InvalidInputSyntax(
            "vector index cannot define DISTRIBUTED BY".to_owned(),
        )
        .into());
    }

    for column in distributed_by {
        let expr_impl = binder.bind_expr(&column)?;
        distributed_columns_expr.push(expr_impl);
    }

    // Remove duplicate column of index columns
    let mut set = HashSet::new();
    index_columns_ordered_expr = index_columns_ordered_expr
        .into_iter()
        .filter(|(expr, _)| match expr {
            ExprImpl::InputRef(input_ref) => set.insert(input_ref.index),
            ExprImpl::FunctionCall(_) => true,
            _ => unreachable!(),
        })
        .collect_vec();

    // Remove include columns are already in index columns
    include_columns_expr = include_columns_expr
        .into_iter()
        .filter(|expr| match expr {
            ExprImpl::InputRef(input_ref) => set.insert(input_ref.index),
            _ => unreachable!(),
        })
        .collect_vec();

    // Remove duplicate columns of distributed by columns
    let mut set = HashSet::new();
    let distributed_columns_expr = distributed_columns_expr
        .into_iter()
        .filter(|expr| match expr {
            ExprImpl::InputRef(input_ref) => set.insert(input_ref.index),

View on GitHub (pinned to 6469eb736d)