{"record":{"id":"2bcd594b1377e0af","repo":"risingwavelabs/risingwave","slug":"failed-to-parse-relation-definition","errorCode":null,"errorMessage":"failed to parse relation definition","messagePattern":"failed to parse relation definition","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"src/meta/src/controller/rename.rs","lineNumber":38,"sourceCode":"    Array, CdcTableInfo, CreateSink, CreateSinkStatement, CreateSourceStatement,\n    CreateSubscriptionStatement, Distinct, Expr, Function, FunctionArg, FunctionArgExpr,\n    FunctionArgList, Ident, ObjectName, Query, SelectItem, SetExpr, Statement, TableAlias,\n    TableFactor, TableWithJoins, Window,\n};\nuse risingwave_sqlparser::parser::Parser;\n\n/// `alter_relation_rename` renames a relation to a new name in its `Create` statement, and returns\n/// the updated definition raw sql. Note that the `definition` must be a `Create` statement and the\n/// `new_name` must be a valid identifier, it should be validated before calling this function. To\n/// update all relations that depend on the renamed one, use `alter_relation_rename_refs`.\npub fn alter_relation_rename(definition: &str, new_name: &str) -> String {\n    // This happens when we try to rename a table that's created by `CREATE TABLE AS`. Remove it\n    // when we support `SHOW CREATE TABLE` for `CREATE TABLE AS`.\n    if definition.is_empty() {\n        tracing::warn!(\"found empty definition when renaming relation, ignored.\");\n        return definition.into();\n    }\n    let ast = Parser::parse_sql(definition).expect(\"failed to parse relation definition\");\n    let mut stmt =\n        Itertools::exactly_one(ast.into_iter()).expect(\"should contains only one statement\");\n\n    match &mut stmt {\n        Statement::CreateTable { name, .. }\n        | Statement::CreateView { name, .. }\n        | Statement::CreateIndex { name, .. }\n        | Statement::CreateSource {\n            stmt: CreateSourceStatement {\n                source_name: name, ..\n            },\n        }\n        | Statement::CreateSubscription {\n            stmt:\n                CreateSubscriptionStatement {\n                    subscription_name: name,\n                    ..\n                },","sourceCodeStart":20,"sourceCodeEnd":56,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/meta/src/controller/rename.rs#L20-L56","documentation":"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.","triggerScenarios":"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.","commonSituations":"Manual meta store edits, upgrade across parser grammar changes, partially written definition rows, or non-CREATE definitions stored for exotic relations.","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."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Before rename, ensure the stored definition parses\nlet ast = Parser::parse_sql(definition).map_err(|e| anyhow!(e))?;\nif ast.len() != 1 { bail!(\"definition must be a single statement\"); }","typeGuard":"fn is_renamable_definition(d: &str) -> bool {\n    !d.is_empty() && Parser::parse_sql(d).map(|a| a.len()) == Ok(1)\n}","tryCatchPattern":"// expect() panics; guard at the boundary\nstd::panic::catch_unwind(|| alter_relation_rename(def, from, to))","preventionTips":["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"],"tags":["panic","sql-parser","meta","rename"],"backgroundTag":"sql-query-failed","analyzedSha":"6469eb736d691e8e9b8a419a57edd6429ca77417","analyzedAt":"2026-09-11T21:06:21.487Z","contentChangedAt":"2026-09-11T21:06:21.487Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}