{"record":{"id":"ddabd7e37ffae30f","repo":"databendlabs/databend","slug":"column-view-type-mismatch","errorCode":null,"errorMessage":"column view type mismatch","messagePattern":"column view type mismatch","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/query/expression/src/block_vec.rs","lineNumber":448,"sourceCode":"            data: data as _,\n        })\n    }\n\n    fn push_typed<T: AccessType>(storage: &mut ColumnStorage, entry: BlockEntry) -> Result<()> {\n        let views = storage\n            .data\n            .downcast_mut::<Vec<ColumnView<T>>>()\n            .expect(\"column view storage type mismatch\");\n        views.push(entry.downcast::<T>()?);\n        Ok(())\n    }\n\n    fn replace_typed<T: AccessType>(storage: &mut ColumnStorage, index: usize, entry: BlockEntry) {\n        let views = storage\n            .data\n            .downcast_mut::<Vec<ColumnView<T>>>()\n            .expect(\"column view storage type mismatch\");\n        let view = entry.downcast::<T>().expect(\"column view type mismatch\");\n        views[index] = view;\n    }\n\n    fn handler_for(data_type: &DataType) -> TypeHandler {\n        match data_type {\n            DataType::Nullable(inner) => Self::handler_for_nullable(inner),\n            _ => Self::handler_for_non_nullable(data_type),\n        }\n    }\n\n    fn handler_for_non_nullable(data_type: &DataType) -> TypeHandler {\n        match data_type {\n            DataType::Null => TypeHandler::typed::<NullType>(false),\n            DataType::EmptyArray => TypeHandler::typed::<EmptyArrayType>(false),\n            DataType::EmptyMap => TypeHandler::typed::<EmptyMapType>(false),\n            DataType::Boolean => TypeHandler::boolean(),\n            DataType::Binary => TypeHandler::binary::<BinaryType>(),\n            DataType::String => TypeHandler::string(),","sourceCodeStart":430,"sourceCodeEnd":466,"githubUrl":"https://github.com/databendlabs/databend/blob/288d84d76e20a2f8f7173bda9691eb6ece301aa9/src/query/expression/src/block_vec.rs#L430-L466","documentation":"After the storage downcast succeeds, replace_typed downcasts the incoming BlockEntry to the handler's concrete ColumnView<T> and panics with this message if the entry's actual payload type differs from T. The storage and handler agreed, but the entry itself is the wrong type.","triggerScenarios":"replace_typed receiving a BlockEntry built for a different value type than the TypeHandler's T — e.g. replacing a view computed with another scalar type after implicit conversion didn't happen.","commonSituations":"Constant replacement / fold-to-constant optimizations producing entries of a literal type (e.g. i64) into a column of another type (e.g. f64); cast elision bugs.","solutions":["Cast or rebuild the entry as ColumnView<T> for the exact handler type before replacing.","Ensure constant folding preserves the column's data type (apply a cast on the folded constant).","Compare entry's type_id against T before calling replace_typed and take a conversion path instead.","File a bug reproducing the query; indicates a missed cast in a rewrite rule."],"exampleFix":null,"handlingStrategy":"type-guard","validationCode":"if !entry.downcast::<T>().is_ok_guard() /* i.e. downcast fails */ {\n    entry = entry.cast_to::<T>()?;\n}","typeGuard":"fn entry_is<T: AccessType>(entry: &BlockEntry) -> bool {\n    entry.data_type() == &T::data_type()\n}","tryCatchPattern":null,"preventionTips":["Insert explicit casts after constant folding so folded values keep the column type","Check entry data type before replace and convert otherwise","Add rewrite-rule tests asserting output data types"],"tags":["rust","panic","downcast","type-mismatch"],"backgroundTag":"type-mismatch","analyzedSha":"288d84d76e20a2f8f7173bda9691eb6ece301aa9","analyzedAt":"2026-09-11T11:29:36.208Z","contentChangedAt":"2026-09-11T11:29:36.208Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}