@@ -11,6 +11,7 @@ use vortex_error::VortexResult;
1111use vortex_error:: vortex_ensure;
1212use vortex_session:: VortexSession ;
1313
14+ use crate :: Array ;
1415use crate :: ArrayRef ;
1516use crate :: arrays:: StructVTable ;
1617use crate :: arrow:: ArrowArrayExecutor ;
@@ -25,36 +26,40 @@ pub(super) fn to_arrow_struct(
2526 let validity = array. validity_mask ( ) ;
2627
2728 let mut field_arrays = Vec :: with_capacity ( fields. len ( ) ) ;
28- if let Some ( array) = array. as_opt :: < StructVTable > ( ) {
29- // If the array is already a struct type, then we can convert each field.
30- for ( field, child) in fields. iter ( ) . zip_eq ( array. fields ( ) . iter ( ) ) {
31- let field_array = child. execute_arrow ( field. data_type ( ) , session) ?;
32- vortex_ensure ! (
33- field. is_nullable( ) || field_array. null_count( ) == 0 ,
34- "Cannot convert field '{}' to non-nullable Arrow field because it contains nulls" ,
35- field. name( )
36- ) ;
37- field_arrays. push ( field_array) ;
29+
30+ match array. try_into :: < StructVTable > ( ) {
31+ Ok ( array) => {
32+ // If the array is already a struct type, then we can convert each field.
33+ for ( field, child) in fields. iter ( ) . zip_eq ( array. into_fields ( ) . into_iter ( ) ) {
34+ let field_array = child. execute_arrow ( field. data_type ( ) , session) ?;
35+ vortex_ensure ! (
36+ field. is_nullable( ) || field_array. null_count( ) == 0 ,
37+ "Cannot convert field '{}' to non-nullable Arrow field because it contains nulls" ,
38+ field. name( )
39+ ) ;
40+ field_arrays. push ( field_array) ;
41+ }
3842 }
39- } else {
40- // Otherwise, we have some options:
41- // 1. Use get_item expression to extract each field? This is a bit sad because get_item
42- // will perform the validity masking again.
43- // 2. Execute a full struct vector. But this may do unnecessary work on fields that may
44- // have a more direct conversion to the desired Arrow field type.
45- // 3. Something else?
46- //
47- // For now, we go with option 1. Although we really ought to figure out CSE for this.
48- for field in fields. iter ( ) {
49- let field_array = array
50- . get_item ( field. name ( ) . as_str ( ) ) ?
51- . execute_arrow ( field. data_type ( ) , session) ?;
52- vortex_ensure ! (
53- field. is_nullable( ) || field_array. null_count( ) == 0 ,
54- "Cannot convert field '{}' to non-nullable Arrow field because it contains nulls" ,
55- field. name( )
56- ) ;
57- field_arrays. push ( field_array) ;
43+ Err ( array) => {
44+ // Otherwise, we have some options:
45+ // 1. Use get_item expression to extract each field? This is a bit sad because get_item
46+ // will perform the validity masking again.
47+ // 2. Execute a full struct vector. But this may do unnecessary work on fields that may
48+ // have a more direct conversion to the desired Arrow field type.
49+ // 3. Something else?
50+ //
51+ // For now, we go with option 1. Although we really ought to figure out CSE for this.
52+ for field in fields. iter ( ) {
53+ let field_array = array
54+ . get_item ( field. name ( ) . as_str ( ) ) ?
55+ . execute_arrow ( field. data_type ( ) , session) ?;
56+ vortex_ensure ! (
57+ field. is_nullable( ) || field_array. null_count( ) == 0 ,
58+ "Cannot convert field '{}' to non-nullable Arrow field because it contains nulls" ,
59+ field. name( )
60+ ) ;
61+ field_arrays. push ( field_array) ;
62+ }
5863 }
5964 }
6065
0 commit comments