{"record":{"id":"862f4d3591919b71","repo":"risingwavelabs/risingwave","slug":"column-cannot-be-altered-only-types-containi","errorCode":null,"errorMessage":"column \"{}\" cannot be altered; only types containing struct can be altered","messagePattern":"column \"(.+?)\" cannot be altered; only types containing struct can be altered","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/frontend/src/handler/create_table/col_id_gen.rs","lineNumber":173,"sourceCode":"    pub fn generate(&mut self, col: &mut ColumnCatalog) -> Result<()> {\n        let mut path = vec![Segment::Field(col.name().to_owned())];\n\n        if let Some((original_column_id, original_data_type)) = self.existing.get(&path) {\n            if original_data_type == col.data_type() {\n                col.column_desc.column_id = *original_column_id;\n                // Equality above ignores nested field IDs. We need to clone them below.\n                col.column_desc.data_type = original_data_type.clone();\n                return Ok(());\n            } else {\n                // Check if the column can be altered.\n                match original_data_type.can_alter() {\n                    Some(true) => { /* pass */ }\n                    Some(false) => bail!(\n                        \"column \\\"{}\\\" was persisted with legacy encoding thus cannot be altered, \\\n                         consider dropping and readding the column\",\n                        col.name()\n                    ),\n                    None => bail!(\n                        \"column \\\"{}\\\" cannot be altered; only types containing struct can be altered\",\n                        col.name()\n                    ),\n                }\n            }\n        }\n\n        fn handle(\n            this: &mut ColumnIdGenerator,\n            path: &mut Path,\n            data_type: DataType,\n        ) -> Result<(ColumnId, DataType)> {\n            macro_rules! with_segment {\n                ($segment:expr, $block:block) => {{\n                    path.push($segment);\n                    let ret = $block;\n                    path.pop();\n                    ret","sourceCodeStart":155,"sourceCodeEnd":191,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/frontend/src/handler/create_table/col_id_gen.rs#L155-L191","documentation":"`ColIdGenerator::generate` rejects altering a column whose data type returns `None` from `can_alter()`: only types containing struct are supported for in-place type alteration. Altering e.g. an INT to VARCHAR (or any non-struct-containing change) is not implemented and is explicitly rejected.","triggerScenarios":"`ALTER TABLE ... ALTER COLUMN c TYPE <new_type>` where the original or new type contains no struct — e.g. changing an `int` column to `varchar`, or `varchar` to `int`.","commonSituations":"Users expecting general type-change support like in OLTP databases; migration scripts generated for Postgres applied to RisingWave.","solutions":["Drop and re-add the column with the new type, backfilling data explicitly (with casts) if needed.","Create a new column, copy casted values, drop the old one, then rename.","Check RisingWave docs for the supported ALTER COLUMN TYPE matrix (struct-containing types only)."],"exampleFix":"-- before (unsupported)\nALTER TABLE t ALTER COLUMN qty TYPE bigint;\n-- after\nALTER TABLE t ADD COLUMN qty_big bigint;\nUPDATE t SET qty_big = qty::bigint;\nALTER TABLE t DROP COLUMN qty;\nALTER TABLE t RENAME COLUMN qty_big TO qty;","handlingStrategy":"validation","validationCode":"if original.can_alter().is_none() {\n    // plan drop+readd instead of ALTER COLUMN TYPE\n    return Err(format!(\"column '{}' type change not supported; use drop+readd\", col.name()));\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Only attempt ALTER COLUMN TYPE when original or new type contains struct","Generate migrations that use add/copy/drop/rename for primitive type changes","Consult supported-type matrix in docs"],"tags":["rust","schema","alter-table","unsupported"],"backgroundTag":"unsupported-operation","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"}