@@ -294,6 +294,7 @@ pub(crate) fn cast_array(
294294 } ;
295295
296296 let cast_result = match ( & from_type, to_type) {
297+ ( Null , _) => Ok ( cast_with_options ( & array, to_type, & native_cast_options) ?) ,
297298 ( Utf8 , Boolean ) => spark_cast_utf8_to_boolean :: < i32 > ( & array, eval_mode) ,
298299 ( LargeUtf8 , Boolean ) => spark_cast_utf8_to_boolean :: < i64 > ( & array, eval_mode) ,
299300 ( Utf8 , Timestamp ( _, _) ) => {
@@ -366,8 +367,22 @@ pub(crate) fn cast_array(
366367 cast_options,
367368 ) ?) ,
368369 ( List ( _) , Utf8 ) => Ok ( cast_array_to_string ( array. as_list ( ) , cast_options) ?) ,
369- ( List ( _) , List ( _) ) if can_cast_types ( & from_type, to_type) => {
370- Ok ( cast_with_options ( & array, to_type, & CAST_OPTIONS ) ?)
370+ ( List ( from) , List ( to) )
371+ if can_cast_types ( & from_type, to_type)
372+ || ( matches ! ( from. data_type( ) , Decimal128 ( _, _) )
373+ && matches ! ( to. data_type( ) , Boolean ) ) =>
374+ {
375+ let list_array = array. as_list :: < i32 > ( ) ;
376+ Ok ( Arc :: new ( ListArray :: new (
377+ Arc :: clone ( to) ,
378+ list_array. offsets ( ) . clone ( ) ,
379+ cast_array (
380+ Arc :: clone ( list_array. values ( ) ) ,
381+ to. data_type ( ) ,
382+ cast_options,
383+ ) ?,
384+ list_array. nulls ( ) . cloned ( ) ,
385+ ) ) as ArrayRef )
371386 }
372387 ( Map ( _, _) , Map ( _, _) ) => Ok ( cast_map_to_map ( & array, & from_type, to_type, cast_options) ?) ,
373388 ( UInt8 | UInt16 | UInt32 | UInt64 , Int8 | Int16 | Int32 | Int64 )
@@ -803,7 +818,8 @@ fn cast_binary_formatter(value: &[u8]) -> String {
803818#[ cfg( test) ]
804819mod tests {
805820 use super :: * ;
806- use arrow:: array:: StringArray ;
821+ use arrow:: array:: { BooleanArray , Decimal128Array , ListArray , StringArray } ;
822+ use arrow:: buffer:: OffsetBuffer ;
807823 use arrow:: datatypes:: TimestampMicrosecondType ;
808824 use arrow:: datatypes:: { Field , Fields } ;
809825 #[ test]
@@ -955,8 +971,6 @@ mod tests {
955971
956972 #[ test]
957973 fn test_cast_i32_array_to_string ( ) {
958- use arrow:: array:: ListArray ;
959- use arrow:: buffer:: OffsetBuffer ;
960974 let values_array = Int32Array :: from ( vec ! [ Some ( 1 ) , Some ( 2 ) , Some ( 3 ) , Some ( 1 ) , None , None ] ) ;
961975 let offsets_buffer = OffsetBuffer :: < i32 > :: new ( vec ! [ 0 , 3 , 5 , 6 , 6 ] . into ( ) ) ;
962976 let item_field = Arc :: new ( Field :: new ( "item" , DataType :: Int32 , true ) ) ;
@@ -977,4 +991,42 @@ mod tests {
977991 assert_eq ! ( r#"[null]"# , string_array. value( 2 ) ) ;
978992 assert_eq ! ( r#"[]"# , string_array. value( 3 ) ) ;
979993 }
994+
995+ #[ test]
996+ fn test_cast_decimal_array_to_boolean_array ( ) {
997+ let values_array =
998+ Decimal128Array :: from ( vec ! [ Some ( 0 ) , Some ( 100 ) , None , Some ( -100 ) , Some ( 0 ) ] )
999+ . with_precision_and_scale ( 10 , 2 )
1000+ . unwrap ( ) ;
1001+ let offsets_buffer = OffsetBuffer :: < i32 > :: new ( vec ! [ 0 , 2 , 3 , 5 ] . into ( ) ) ;
1002+ let item_field = Arc :: new ( Field :: new ( "item" , DataType :: Decimal128 ( 10 , 2 ) , true ) ) ;
1003+ let list_array = Arc :: new ( ListArray :: new (
1004+ item_field,
1005+ offsets_buffer,
1006+ Arc :: new ( values_array) ,
1007+ Some ( vec ! [ true , false , true ] . into ( ) ) ,
1008+ ) ) ;
1009+
1010+ let casted_array = cast_array (
1011+ list_array,
1012+ & DataType :: List ( Arc :: new ( Field :: new ( "item" , DataType :: Boolean , true ) ) ) ,
1013+ & SparkCastOptions :: new ( EvalMode :: Legacy , "UTC" , false ) ,
1014+ )
1015+ . unwrap ( ) ;
1016+ let casted_list = casted_array. as_list :: < i32 > ( ) ;
1017+
1018+ assert_eq ! ( 3 , casted_list. len( ) ) ;
1019+ assert ! ( !casted_list. is_null( 0 ) ) ;
1020+ assert ! ( casted_list. is_null( 1 ) ) ;
1021+ assert ! ( !casted_list. is_null( 2 ) ) ;
1022+
1023+ let values = casted_list
1024+ . values ( )
1025+ . as_any ( )
1026+ . downcast_ref :: < BooleanArray > ( )
1027+ . expect ( "Casted list values should be a BooleanArray" ) ;
1028+ let expected =
1029+ BooleanArray :: from ( vec ! [ Some ( false ) , Some ( true ) , None , Some ( true ) , Some ( false ) ] ) ;
1030+ assert_eq ! ( & expected, values) ;
1031+ }
9801032}
0 commit comments