@@ -268,6 +268,49 @@ pub fn cast_impl(
268268
269269 Arc :: new ( builder. finish ( ) )
270270 }
271+ // array to string (spark compatible)
272+ ( & DataType :: List ( _) , & DataType :: Utf8 ) => {
273+ let list_array = as_list_array ( array) ;
274+ let values = list_array. values ( ) ;
275+ let casted_values = cast_impl ( values, & DataType :: Utf8 , match_struct_fields) ?;
276+ let string_values = as_string_array ( & casted_values) ;
277+
278+ let mut builder = StringBuilder :: new ( ) ;
279+
280+ for row_idx in 0 ..list_array. len ( ) {
281+ if list_array. is_null ( row_idx) {
282+ builder. append_null ( ) ;
283+ } else {
284+ let mut row_str = String :: from ( "[" ) ;
285+ let start = list_array. value_offsets ( ) [ row_idx] as usize ;
286+ let end = list_array. value_offsets ( ) [ row_idx + 1 ] as usize ;
287+ let num_elements = end - start;
288+
289+ if num_elements > 0 {
290+ if values. is_null ( start) {
291+ row_str. push_str ( "null" ) ;
292+ } else {
293+ row_str. push_str ( string_values. value ( start) ) ;
294+ }
295+
296+ for i in 1 ..num_elements {
297+ row_str. push ( ',' ) ;
298+ if values. is_null ( start + i) {
299+ row_str. push_str ( " null" ) ;
300+ } else {
301+ row_str. push ( ' ' ) ;
302+ row_str. push_str ( string_values. value ( start + i) ) ;
303+ }
304+ }
305+ }
306+
307+ row_str. push ( ']' ) ;
308+ builder. append_value ( & row_str) ;
309+ }
310+ }
311+
312+ Arc :: new ( builder. finish ( ) )
313+ }
271314 _ => {
272315 // default cast
273316 arrow:: compute:: kernels:: cast:: cast ( array, cast_type) ?
@@ -474,6 +517,7 @@ fn to_date(s: &str) -> Option<i32> {
474517
475518#[ cfg( test) ]
476519mod test {
520+ use arrow:: buffer:: OffsetBuffer ;
477521 use datafusion:: common:: cast:: { as_decimal128_array, as_float64_array, as_int32_array} ;
478522
479523 use super :: * ;
@@ -795,4 +839,125 @@ mod test {
795839 & StringArray :: from_iter( vec![ Some ( "{100, {x, true}}" ) , Some ( "{200, {y, null}}" ) , ] )
796840 ) ;
797841 }
842+
843+ #[ test]
844+ fn test_array_to_string ( ) {
845+ // Create a list array with int32 elements
846+ let values = Int32Array :: from ( vec ! [
847+ Some ( 1 ) ,
848+ Some ( 2 ) ,
849+ Some ( 3 ) ,
850+ None ,
851+ Some ( 5 ) ,
852+ Some ( 6 ) ,
853+ None ,
854+ None ,
855+ ] ) ;
856+ let offsets = OffsetBuffer :: new ( vec ! [ 0 , 3 , 5 , 8 ] . into ( ) ) ;
857+ let list_array: ArrayRef = Arc :: new ( ListArray :: new (
858+ Arc :: new ( Field :: new ( "item" , DataType :: Int32 , true ) ) ,
859+ offsets,
860+ Arc :: new ( values) ,
861+ None ,
862+ ) ) ;
863+
864+ let casted = cast ( & list_array, & DataType :: Utf8 ) . unwrap ( ) ;
865+ assert_eq ! (
866+ as_string_array( & casted) ,
867+ & StringArray :: from_iter( vec![
868+ Some ( "[1, 2, 3]" ) ,
869+ Some ( "[null, 5]" ) ,
870+ Some ( "[6, null, null]" ) ,
871+ ] )
872+ ) ;
873+ }
874+
875+ #[ test]
876+ fn test_array_to_string_with_null_array ( ) {
877+ // Create a list array where some rows are entirely null
878+ let values = Int32Array :: from ( vec ! [ Some ( 1 ) , Some ( 2 ) , Some ( 3 ) , Some ( 4 ) ] ) ;
879+ let offsets = OffsetBuffer :: new ( vec ! [ 0 , 2 , 2 , 4 ] . into ( ) ) ;
880+ let nulls = arrow:: buffer:: NullBuffer :: from ( vec ! [ true , false , true ] ) ;
881+ let list_array: ArrayRef = Arc :: new ( ListArray :: new (
882+ Arc :: new ( Field :: new ( "item" , DataType :: Int32 , true ) ) ,
883+ offsets,
884+ Arc :: new ( values) ,
885+ Some ( nulls) ,
886+ ) ) ;
887+
888+ let casted = cast ( & list_array, & DataType :: Utf8 ) . unwrap ( ) ;
889+ assert_eq ! (
890+ as_string_array( & casted) ,
891+ & StringArray :: from_iter( vec![ Some ( "[1, 2]" ) , None , Some ( "[3, 4]" ) , ] )
892+ ) ;
893+ }
894+
895+ #[ test]
896+ fn test_empty_array_to_string ( ) {
897+ // Create a list array with empty arrays
898+ let values = Int32Array :: from ( vec ! [ ] as Vec < Option < i32 > > ) ;
899+ let offsets = OffsetBuffer :: new ( vec ! [ 0 , 0 , 0 ] . into ( ) ) ;
900+ let list_array: ArrayRef = Arc :: new ( ListArray :: new (
901+ Arc :: new ( Field :: new ( "item" , DataType :: Int32 , true ) ) ,
902+ offsets,
903+ Arc :: new ( values) ,
904+ None ,
905+ ) ) ;
906+
907+ let casted = cast ( & list_array, & DataType :: Utf8 ) . unwrap ( ) ;
908+ assert_eq ! (
909+ as_string_array( & casted) ,
910+ & StringArray :: from_iter( vec![ Some ( "[]" ) , Some ( "[]" ) ] )
911+ ) ;
912+ }
913+
914+ #[ test]
915+ fn test_nested_array_to_string ( ) {
916+ // Create a nested array: array<array<int>>
917+ let inner_values = Int32Array :: from ( vec ! [ Some ( 1 ) , Some ( 2 ) , Some ( 3 ) , Some ( 4 ) ] ) ;
918+ let inner_offsets = OffsetBuffer :: new ( vec ! [ 0 , 2 , 4 ] . into ( ) ) ;
919+ let inner_list = ListArray :: new (
920+ Arc :: new ( Field :: new ( "item" , DataType :: Int32 , true ) ) ,
921+ inner_offsets,
922+ Arc :: new ( inner_values) ,
923+ None ,
924+ ) ;
925+
926+ let outer_offsets = OffsetBuffer :: new ( vec ! [ 0 , 1 , 2 ] . into ( ) ) ;
927+ let outer_list: ArrayRef = Arc :: new ( ListArray :: new (
928+ Arc :: new ( Field :: new (
929+ "item" ,
930+ DataType :: List ( Arc :: new ( Field :: new ( "item" , DataType :: Int32 , true ) ) ) ,
931+ true ,
932+ ) ) ,
933+ outer_offsets,
934+ Arc :: new ( inner_list) ,
935+ None ,
936+ ) ) ;
937+
938+ let casted = cast ( & outer_list, & DataType :: Utf8 ) . unwrap ( ) ;
939+ assert_eq ! (
940+ as_string_array( & casted) ,
941+ & StringArray :: from_iter( vec![ Some ( "[[1, 2]]" ) , Some ( "[[3, 4]]" ) , ] )
942+ ) ;
943+ }
944+
945+ #[ test]
946+ fn test_array_of_strings_to_string ( ) {
947+ // Create a list array with string elements
948+ let values = StringArray :: from ( vec ! [ Some ( "a" ) , Some ( "b" ) , None , Some ( "d" ) ] ) ;
949+ let offsets = OffsetBuffer :: new ( vec ! [ 0 , 2 , 4 ] . into ( ) ) ;
950+ let list_array: ArrayRef = Arc :: new ( ListArray :: new (
951+ Arc :: new ( Field :: new ( "item" , DataType :: Utf8 , true ) ) ,
952+ offsets,
953+ Arc :: new ( values) ,
954+ None ,
955+ ) ) ;
956+
957+ let casted = cast ( & list_array, & DataType :: Utf8 ) . unwrap ( ) ;
958+ assert_eq ! (
959+ as_string_array( & casted) ,
960+ & StringArray :: from_iter( vec![ Some ( "[a, b]" ) , Some ( "[null, d]" ) , ] )
961+ ) ;
962+ }
798963}
0 commit comments