{"record":{"id":"a76069ec54b211a3","repo":"pola-rs/polars","slug":"not-implemented-a76069","errorCode":null,"errorMessage":"not implemented","messagePattern":"not implemented","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/polars-arrow/src/compute/concatenate.rs","lineNumber":108,"sourceCode":"        Null => Ok(Box::new(concatenate_null(arrays))),\n        Boolean => Ok(Box::new(concatenate_bool(arrays))),\n        Primitive(ptype) => {\n            with_match_primitive_type_full!(ptype, |$T| {\n                Ok(Box::new(concatenate_primitive::<$T, _>(arrays)))\n            })\n        },\n        Binary => Ok(Box::new(concatenate_binary::<i32, _>(arrays)?)),\n        LargeBinary => Ok(Box::new(concatenate_binary::<i64, _>(arrays)?)),\n        Utf8 => Ok(Box::new(concatenate_utf8::<i32, _>(arrays)?)),\n        LargeUtf8 => Ok(Box::new(concatenate_utf8::<i64, _>(arrays)?)),\n        BinaryView => Ok(Box::new(concatenate_view::<[u8], _>(arrays))),\n        Utf8View => Ok(Box::new(concatenate_view::<str, _>(arrays))),\n        List => Ok(Box::new(concatenate_list::<i32, _>(arrays)?)),\n        LargeList => Ok(Box::new(concatenate_list::<i64, _>(arrays)?)),\n        FixedSizeBinary => Ok(Box::new(concatenate_fixed_size_binary(arrays)?)),\n        FixedSizeList => Ok(Box::new(concatenate_fixed_size_list(arrays)?)),\n        Struct => Ok(Box::new(concatenate_struct(arrays)?)),\n        Union => unimplemented!(),\n        Map => unimplemented!(),\n        Dictionary(_) => unimplemented!(),\n    }\n}\n\nfn concatenate_null<A: AsRef<dyn Array>>(arrays: &[A]) -> NullArray {\n    let dtype = arrays[0].as_ref().dtype().clone();\n    let total_len = arrays.iter().map(|arr| arr.as_ref().len()).sum();\n    NullArray::new(dtype, total_len)\n}\n\nfn concatenate_bool<A: AsRef<dyn Array>>(arrays: &[A]) -> BooleanArray {\n    let dtype = arrays[0].as_ref().dtype().clone();\n    let (total_len, null_count) = len_null_count(arrays);\n    let validity = concatenate_validities_with_len_null_count(arrays, total_len, null_count);\n\n    let mut bitmap = BitmapBuilder::with_capacity(total_len);\n    for arr in arrays {","sourceCodeStart":90,"sourceCodeEnd":126,"githubUrl":"https://github.com/pola-rs/polars/blob/df599052daf96e7a9cc30a3b0c6bd25d6947e3c0/crates/polars-arrow/src/compute/concatenate.rs#L90-L126","documentation":"polars-arrow's concatenate kernel (compute::concatenate::concatenate / concatenate_unchecked) dispatches on the array's physical type, and every supported type has a dedicated routine. The Union arm is a bare unimplemented!() (crates/polars-arrow/src/compute/concatenate.rs:108), so concatenating union arrays panics with 'not implemented' instead of returning a PolarsResult error. Empty input and a single non-empty array return early, so the panic needs at least two non-empty union arrays.","triggerScenarios":"Calling concatenate(&[&a, &b]) or concatenate_unchecked with two or more non-empty arrays whose dtype is ArrowDataType::Union(_) — e.g. polars vstack/diag_concat/rechunk over batches containing a union column.","commonSituations":"Interop with engines that emit union columns (pyarrow, DataFusion, Spark-on-Arrow); reading Arrow IPC/Feather files with unions then concatenating record batches; tests that hand-build union arrays.","solutions":["Project away or drop union columns before concatenating","Cast the union column to a struct or string representation first, then concatenate","Branch on dtype().to_physical_type() and return a PolarsResult error for Union instead of letting the panic escape","Implement concatenate_union upstream or fall back to the arrow-rs concat kernel, which supports unions"],"exampleFix":"// before\nlet out = concatenate(&[&a, &b])?; // panics: Union => unimplemented!()\n\n// after\nuse polars_arrow::datatypes::PhysicalType;\nif a.dtype().to_physical_type() == PhysicalType::Union {\n    polars_bail!(InvalidOperation: \"concatenate of union arrays is not supported\");\n}\nlet out = concatenate(&[&a, &b])?;","handlingStrategy":"type-guard","validationCode":"use polars_arrow::datatypes::PhysicalType;\nif arrays.iter().any(|a| a.dtype().to_physical_type() == PhysicalType::Union) {\n    polars_bail!(InvalidOperation: \"union columns cannot be concatenated\");\n}","typeGuard":"fn is_concatenable(dtype: &ArrowDataType) -> bool {\n    !matches!(\n        dtype.to_physical_type(),\n        PhysicalType::Union | PhysicalType::Map | PhysicalType::Dictionary(_)\n    )\n}","tryCatchPattern":"let res = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| concatenate(&arrays)));\nlet out = match res {\n    Ok(v) => v?,\n    Err(_) => polars_bail!(ComputeError: \"concatenate panicked: unsupported dtype (Union/Map/Dictionary)\"),\n};","preventionTips":["Validate column dtypes right after IPC/FFI/Parquet reads and before vstack or concat","Keep a shared PhysicalType support-matrix check at pipeline entry points that concatenate foreign Arrow data","Wrap panicking kernels with catch_unwind only at batch boundaries, and convert to PolarsResult errors"],"tags":["rust","polars","arrow","concatenate","union","panic"],"backgroundTag":null,"analyzedSha":"df599052daf96e7a9cc30a3b0c6bd25d6947e3c0","analyzedAt":"2026-08-16T12:10:03.978Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}