diff --git a/arrow-cast/src/cast/mod.rs b/arrow-cast/src/cast/mod.rs index a5f5fddb8583..b317dabd5dda 100644 --- a/arrow-cast/src/cast/mod.rs +++ b/arrow-cast/src/cast/mod.rs @@ -213,7 +213,7 @@ pub fn can_cast_types(from_type: &DataType, to_type: &DataType) -> bool { (Binary, LargeBinary | Utf8 | LargeUtf8 | FixedSizeBinary(_) | BinaryView | Utf8View ) => true, (LargeBinary, Binary | Utf8 | LargeUtf8 | FixedSizeBinary(_) | BinaryView | Utf8View ) => true, - (FixedSizeBinary(_), Binary | LargeBinary) => true, + (FixedSizeBinary(_), Binary | LargeBinary | BinaryView) => true, ( Utf8 | LargeUtf8 | Utf8View, Binary @@ -1192,6 +1192,7 @@ pub fn cast_with_options( (FixedSizeBinary(size), _) => match to_type { Binary => cast_fixed_size_binary_to_binary::(array, *size), LargeBinary => cast_fixed_size_binary_to_binary::(array, *size), + BinaryView => cast_fixed_size_binary_to_binary_view(array, *size), _ => Err(ArrowError::CastError(format!( "Casting from {from_type:?} to {to_type:?} not supported", ))), @@ -2327,6 +2328,27 @@ fn cast_fixed_size_binary_to_binary( Ok(Arc::new(builder.finish())) } +fn cast_fixed_size_binary_to_binary_view( + array: &dyn Array, + _byte_width: i32, +) -> Result { + let array = array + .as_any() + .downcast_ref::() + .unwrap(); + + let mut builder = BinaryViewBuilder::with_capacity(array.len()); + for i in 0..array.len() { + if array.is_null(i) { + builder.append_null(); + } else { + builder.append_value(array.value(i)); + } + } + + Ok(Arc::new(builder.finish())) +} + /// Helper function to cast from one `ByteArrayType` to another and vice versa. /// If the target one (e.g., `LargeUtf8`) is too large for the source array it will return an Error. fn cast_byte_container(array: &dyn Array) -> Result @@ -4847,6 +4869,12 @@ mod tests { assert_eq!(bytes_1, down_cast.value(0)); assert_eq!(bytes_2, down_cast.value(1)); assert!(down_cast.is_null(2)); + + let array_ref = cast(&a1, &DataType::BinaryView).unwrap(); + let down_cast = array_ref.as_binary_view(); + assert_eq!(bytes_1, down_cast.value(0)); + assert_eq!(bytes_2, down_cast.value(1)); + assert!(down_cast.is_null(2)); } #[test]