From 9692a3929709feaf2a81a59f3d8b5ce11aeaccae Mon Sep 17 00:00:00 2001 From: liukun4515 Date: Wed, 22 Jun 2022 20:36:46 +0800 Subject: [PATCH] support NULL type values to decimal --- arrow/src/compute/kernels/cast.rs | 36 +++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/arrow/src/compute/kernels/cast.rs b/arrow/src/compute/kernels/cast.rs index fa92179b747..b7f02aad504 100644 --- a/arrow/src/compute/kernels/cast.rs +++ b/arrow/src/compute/kernels/cast.rs @@ -72,9 +72,9 @@ pub fn can_cast_types(from_type: &DataType, to_type: &DataType) -> bool { // cast one decimal type to another decimal type (Decimal(_, _), Decimal(_, _)) => true, // signed numeric to decimal - (Int8 | Int16 | Int32 | Int64 | Float32 | Float64, Decimal(_, _)) | + (Null|Int8 | Int16 | Int32 | Int64 | Float32 | Float64, Decimal(_, _)) | // decimal to signed numeric - (Decimal(_, _), Int8 | Int16 | Int32 | Int64 | Float32 | Float64) + (Decimal(_, _), Null| Int8 | Int16 | Int32 | Int64 | Float32 | Float64) | ( Null, Boolean @@ -426,7 +426,7 @@ pub fn cast_with_options( } match (from_type, to_type) { (Decimal(_, s1), Decimal(p2, s2)) => cast_decimal_to_decimal(array, s1, p2, s2), - (Decimal(_, scale), _) => { + (Decimal(_, scale), Int8 | Int16 | Int32 | Int64 | Float32 | Float64) => { // cast decimal to other type match to_type { Int8 => { @@ -447,13 +447,14 @@ pub fn cast_with_options( Float64 => { cast_decimal_to_float!(array, scale, Float64Builder, f64) } + Null => Ok(new_null_array(to_type, array.len())), _ => Err(ArrowError::CastError(format!( "Casting from {:?} to {:?} not supported", from_type, to_type ))), } } - (_, Decimal(precision, scale)) => { + (Int8 | Int16 | Int32 | Int64 | Float32 | Float64, Decimal(precision, scale)) => { // cast data to decimal match from_type { // TODO now just support signed numeric to decimal, support decimal to numeric later @@ -475,6 +476,7 @@ pub fn cast_with_options( Float64 => { cast_floating_point_to_decimal!(array, Float64Array, precision, scale) } + Null => Ok(new_null_array(to_type, array.len())), _ => Err(ArrowError::CastError(format!( "Casting from {:?} to {:?} not supported", from_type, to_type @@ -511,7 +513,8 @@ pub fn cast_with_options( | FixedSizeList(_, _) | Struct(_) | Map(_, _) - | Dictionary(_, _), + | Dictionary(_, _) + | Decimal(_, _), ) | ( Boolean @@ -542,7 +545,8 @@ pub fn cast_with_options( | FixedSizeList(_, _) | Struct(_) | Map(_, _) - | Dictionary(_, _), + | Dictionary(_, _) + | Decimal(_, _), Null, ) => Ok(new_null_array(to_type, array.len())), (Struct(_), _) => Err(ArrowError::CastError( @@ -4312,6 +4316,26 @@ mod tests { assert_eq!(array_to_strings(&cast_array), expected); } + #[test] + fn test_cast_null_array_to_from_decimal_array() { + let data_type = DataType::Decimal(12, 4); + let array = new_null_array(&DataType::Null, 4); + assert_eq!(array.data_type(), &DataType::Null); + let cast_array = cast(&array, &data_type).expect("cast failed"); + assert_eq!(cast_array.data_type(), &data_type); + for i in 0..4 { + assert!(cast_array.is_null(i)); + } + + let array = new_null_array(&data_type, 4); + assert_eq!(array.data_type(), &data_type); + let cast_array = cast(&array, &DataType::Null).expect("cast failed"); + assert_eq!(cast_array.data_type(), &DataType::Null); + for i in 0..4 { + assert!(cast_array.is_null(i)); + } + } + #[test] fn test_cast_null_array_from_and_to_primitive_array() { macro_rules! typed_test {