risingwavelabs/risingwave · critical

should contains only one statement

Error message

should contains only one statement

What it means

After successfully parsing the relation definition, alter_relation_rename asserts exactly one statement via Itertools::exactly_one().expect("should contains only one statement"). Stored definitions are expected to be a single CREATE statement; multiple statements indicate corrupt or malformed stored state.

Source

Thrown at src/meta/src/controller/rename.rs:40

    FunctionArgList, Ident, ObjectName, Query, SelectItem, SetExpr, Statement, TableAlias,
    TableFactor, TableWithJoins, Window,
};
use risingwave_sqlparser::parser::Parser;

/// `alter_relation_rename` renames a relation to a new name in its `Create` statement, and returns
/// the updated definition raw sql. Note that the `definition` must be a `Create` statement and the
/// `new_name` must be a valid identifier, it should be validated before calling this function. To
/// update all relations that depend on the renamed one, use `alter_relation_rename_refs`.
pub fn alter_relation_rename(definition: &str, new_name: &str) -> String {
    // This happens when we try to rename a table that's created by `CREATE TABLE AS`. Remove it
    // when we support `SHOW CREATE TABLE` for `CREATE TABLE AS`.
    if definition.is_empty() {
        tracing::warn!("found empty definition when renaming relation, ignored.");
        return definition.into();
    }
    let ast = Parser::parse_sql(definition).expect("failed to parse relation definition");
    let mut stmt =
        Itertools::exactly_one(ast.into_iter()).expect("should contains only one statement");

    match &mut stmt {
        Statement::CreateTable { name, .. }
        | Statement::CreateView { name, .. }
        | Statement::CreateIndex { name, .. }
        | Statement::CreateSource {
            stmt: CreateSourceStatement {
                source_name: name, ..
            },
        }
        | Statement::CreateSubscription {
            stmt:
                CreateSubscriptionStatement {
                    subscription_name: name,
                    ..
                },
        }
        | Statement::CreateSink {

View on GitHub (pinned to 6469eb736d)

Solutions

  1. Inspect the stored definition; ensure it is a single CREATE TABLE/VIEW/INDEX/SOURCE statement.
  2. Normalize the definition to one statement, or drop/recreate the relation.
  3. If produced by tooling, fix the tool to write a single statement.
Defensive patterns

Strategy: validation

Validate before calling

let n = Parser::parse_sql(definition).map_err(|e| anyhow!(e))?.len();
if n != 1 { bail!("expected exactly one statement, got {}", n); }

Prevention

When it happens

Trigger: alter_relation_rename when the stored definition parses into 0 or 2+ SQL statements (e.g. concatenated statements, semicolon-terminated extra text in the definition column).

Common situations: Manual meta store tampering, buggy definition serialization from an older version, pasting multi-statement SQL into a definition.

Related errors


AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11). Data as JSON: /api/errors/f401550b261d3dcf. Report an issue: GitHub.