risingwavelabs/risingwave · critical
failed to parse relation definition
Error message
failed to parse relation definition
What it means
During ALTER ... RENAME, the stored relation definition SQL is re-parsed; if parsing fails the code panics via .expect("failed to parse relation definition"). Empty definitions are special-cased earlier (CTAS tables), so reaching the expect means the stored definition is non-empty but unparseable.
Source
Thrown at src/meta/src/controller/rename.rs:38
Array, CdcTableInfo, CreateSink, CreateSinkStatement, CreateSourceStatement,
CreateSubscriptionStatement, Distinct, Expr, Function, FunctionArg, FunctionArgExpr,
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,
..
},View on GitHub (pinned to 6469eb736d)
Solutions
- Inspect the relation's stored definition in the meta store and fix or restore it.
- If the definition is invalid and the relation is droppable, drop and re-create the relation with a valid definition.
- Report the unparseable definition text upstream — it indicates a parser-version compatibility bug.
Defensive patterns
Strategy: validation
Validate before calling
// Before rename, ensure the stored definition parses
let ast = Parser::parse_sql(definition).map_err(|e| anyhow!(e))?;
if ast.len() != 1 { bail!("definition must be a single statement"); } Type guard
fn is_renamable_definition(d: &str) -> bool {
!d.is_empty() && Parser::parse_sql(d).map(|a| a.len()) == Ok(1)
} Try / catch
// expect() panics; guard at the boundary std::panic::catch_unwind(|| alter_relation_rename(def, from, to))
Prevention
- Never hand-edit the meta store definition column
- Test renames after version upgrades on a staging catalog
- Guard against empty CTAS definitions (already special-cased upstream)
- Fuzz parser compatibility when bumping risingwave_sqlparser
When it happens
Trigger: alter_relation_rename on a relation whose persisted `definition` column is corrupted, truncated, or was written by an older/incompatible parser version that the current risingwave_sqlparser cannot parse.
Common situations: Manual meta store edits, upgrade across parser grammar changes, partially written definition rows, or non-CREATE definitions stored for exotic relations.
Understand the failure class
Background: "query failed", "%w: SQL error" — wrapped database query errors in Go libraries explained — this error's family across 3 libraries.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- should contains only one statement
- Some streaming jobs already exist in meta, please start with
- invalid parallelism
- Failed to retrieve fragment description: fragment {} (job_id
- job fragments should exist for streaming job
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/2bcd594b1377e0af.
Report an issue: GitHub.