@@ -10,6 +10,7 @@ use arrow::legacy::kernels::concatenate::concatenate_owned_unchecked;
10
10
) ) ]
11
11
use arrow:: temporal_conversions:: * ;
12
12
use polars_error:: feature_gated;
13
+ use polars_utils:: itertools:: Itertools ;
13
14
14
15
use crate :: chunked_array:: cast:: { cast_chunks, CastOptions } ;
15
16
#[ cfg( feature = "object" ) ]
@@ -575,39 +576,53 @@ unsafe fn to_physical_and_dtype(
575
576
} ,
576
577
ArrowDataType :: Struct ( _fields) => {
577
578
feature_gated ! ( "dtype-struct" , {
578
- debug_assert_eq!( arrays. len( ) , 1 ) ;
579
- let arr = arrays[ 0 ] . clone( ) ;
580
- let arr = arr. as_any( ) . downcast_ref:: <StructArray >( ) . unwrap( ) ;
581
- let ( values, dtypes) : ( Vec <_>, Vec <_>) = arr
582
- . values( )
579
+ let mut pl_fields = None ;
580
+ let arrays = arrays
583
581
. iter( )
584
- . zip( _fields. iter( ) )
585
- . map( |( value, field) | {
586
- let mut out =
587
- to_physical_and_dtype( vec![ value. clone( ) ] , Some ( & field. metadata) ) ;
588
- ( out. 0 . pop( ) . unwrap( ) , out. 1 )
582
+ . map( |arr| {
583
+ let arr = arr. as_any( ) . downcast_ref:: <StructArray >( ) . unwrap( ) ;
584
+ let ( values, dtypes) : ( Vec <_>, Vec <_>) = arr
585
+ . values( )
586
+ . iter( )
587
+ . zip( _fields. iter( ) )
588
+ . map( |( value, field) | {
589
+ let mut out = to_physical_and_dtype(
590
+ vec![ value. clone( ) ] ,
591
+ Some ( & field. metadata) ,
592
+ ) ;
593
+ ( out. 0 . pop( ) . unwrap( ) , out. 1 )
594
+ } )
595
+ . unzip( ) ;
596
+
597
+ let arrow_fields = values
598
+ . iter( )
599
+ . zip( _fields. iter( ) )
600
+ . map( |( arr, field) | {
601
+ ArrowField :: new( field. name. clone( ) , arr. dtype( ) . clone( ) , true )
602
+ } )
603
+ . collect( ) ;
604
+ let arrow_array = Box :: new( StructArray :: new(
605
+ ArrowDataType :: Struct ( arrow_fields) ,
606
+ arr. len( ) ,
607
+ values,
608
+ arr. validity( ) . cloned( ) ,
609
+ ) ) as ArrayRef ;
610
+
611
+ if pl_fields. is_none( ) {
612
+ pl_fields = Some (
613
+ _fields
614
+ . iter( )
615
+ . zip( dtypes)
616
+ . map( |( field, dtype) | Field :: new( field. name. clone( ) , dtype) )
617
+ . collect_vec( ) ,
618
+ )
619
+ }
620
+
621
+ arrow_array
589
622
} )
590
- . unzip ( ) ;
623
+ . collect_vec ( ) ;
591
624
592
- let arrow_fields = values
593
- . iter( )
594
- . zip( _fields. iter( ) )
595
- . map( |( arr, field) | {
596
- ArrowField :: new( field. name. clone( ) , arr. dtype( ) . clone( ) , true )
597
- } )
598
- . collect( ) ;
599
- let arrow_array = Box :: new( StructArray :: new(
600
- ArrowDataType :: Struct ( arrow_fields) ,
601
- arr. len( ) ,
602
- values,
603
- arr. validity( ) . cloned( ) ,
604
- ) ) as ArrayRef ;
605
- let polars_fields = _fields
606
- . iter( )
607
- . zip( dtypes)
608
- . map( |( field, dtype) | Field :: new( field. name. clone( ) , dtype) )
609
- . collect( ) ;
610
- ( vec![ arrow_array] , DataType :: Struct ( polars_fields) )
625
+ ( arrays, DataType :: Struct ( pl_fields. unwrap( ) ) )
611
626
} )
612
627
} ,
613
628
// Use Series architecture to convert nested logical types to physical.
0 commit comments