@@ -6,15 +6,20 @@ use std::sync::Arc;
66use arrow_array:: ArrayRef as ArrowArrayRef ;
77use arrow_array:: StructArray ;
88use arrow_buffer:: NullBuffer ;
9+ use arrow_schema:: DataType ;
910use arrow_schema:: Fields ;
10- use itertools:: Itertools ;
11+ use vortex_compute:: arrow:: IntoArrow ;
12+ use vortex_dtype:: DType ;
13+ use vortex_dtype:: StructFields ;
14+ use vortex_dtype:: arrow:: FromArrowType ;
15+ use vortex_error:: VortexError ;
1116use vortex_error:: VortexResult ;
12- use vortex_error:: vortex_bail;
1317use vortex_error:: vortex_ensure;
1418use vortex_session:: VortexSession ;
1519
1620use crate :: Array ;
1721use crate :: ArrayRef ;
22+ use crate :: VectorExecutor ;
1823use crate :: arrays:: ScalarFnVTable ;
1924use crate :: arrays:: StructVTable ;
2025use crate :: arrow:: ArrowArrayExecutor ;
@@ -52,28 +57,19 @@ pub(super) fn to_arrow_struct(
5257 ) ;
5358 }
5459
55- // Otherwise, we have some options:
56- // 1. Use get_item expression to extract each field? This is a bit sad because get_item
57- // will perform the validity masking again.
58- // 2. Execute a full struct vector. But this may do unnecessary work on fields that may
59- // have a more direct conversion to the desired Arrow field type.
60- // 3. Something else?
61- //
62- // For now, we go with option 1. Although we really ought to figure out CSE for this.
63- let field_arrays = fields
64- . iter ( )
65- . map ( |f| array. get_item ( f. name ( ) . as_str ( ) ) )
66- . try_collect ( ) ?;
60+ // Otherwise, we fall back to executing the full struct vector.
61+ // First we apply a cast to ensure we push down casting where possible into the struct fields.
62+ let vx_fields = StructFields :: from_arrow ( fields) ;
63+ let array = array. cast ( DType :: Struct (
64+ vx_fields,
65+ vortex_dtype:: Nullability :: Nullable ,
66+ ) ) ?;
6767
68- if !array. all_valid ( ) {
69- // TODO(ngates): we should grab the nullability using the is_not_null expression.
70- vortex_bail ! (
71- "Cannot convert nullable Struct array with nulls to Arrow\n {}" ,
72- array. display_tree( )
73- ) ;
74- }
68+ let struct_array = array. execute_vector ( session) ?. into_struct ( ) . into_arrow ( ) ?;
7569
76- create_from_fields ( fields, field_arrays, None , len, session)
70+ // Finally, we cast to Arrow to ensure any types not representable by Vortex (e.g. Dictionary)
71+ // are properly converted.
72+ arrow_cast:: cast ( & struct_array, & DataType :: Struct ( fields. clone ( ) ) ) . map_err ( VortexError :: from)
7773}
7874
7975fn create_from_fields (
0 commit comments