@@ -39,14 +39,17 @@ pub(super) struct ToArrowCanonical;
3939impl Kernel for ToArrowCanonical {
4040 #[ allow( clippy:: cognitive_complexity) ]
4141 fn invoke ( & self , args : & InvocationArgs ) -> VortexResult < Option < Output > > {
42- let ToArrowArgs { array, arrow_type } = ToArrowArgs :: try_from ( args) ?;
42+ let ToArrowArgs {
43+ array,
44+ arrow_type : arrow_type_opt,
45+ } = ToArrowArgs :: try_from ( args) ?;
4346 if !array. is_canonical ( ) {
4447 // Not handled by this kernel
4548 return Ok ( None ) ;
4649 }
4750
4851 // Figure out the target Arrow type, or use the canonical type
49- let arrow_type = arrow_type
52+ let arrow_type = arrow_type_opt
5053 . cloned ( )
5154 . map ( Ok )
5255 . unwrap_or_else ( || array. dtype ( ) . to_arrow_dtype ( ) ) ?;
@@ -136,11 +139,13 @@ impl Kernel for ToArrowCanonical {
136139 to_arrow_decimal256 ( array)
137140 }
138141 ( Canonical :: Struct ( array) , DataType :: Struct ( fields) ) => {
139- to_arrow_struct ( array, fields. as_ref ( ) )
142+ to_arrow_struct ( array, fields. as_ref ( ) , arrow_type_opt. is_none ( ) )
143+ }
144+ ( Canonical :: List ( array) , DataType :: List ( field) ) => {
145+ to_arrow_list :: < i32 > ( array, field, arrow_type_opt. is_none ( ) )
140146 }
141- ( Canonical :: List ( array) , DataType :: List ( field) ) => to_arrow_list :: < i32 > ( array, field) ,
142147 ( Canonical :: List ( array) , DataType :: LargeList ( field) ) => {
143- to_arrow_list :: < i64 > ( array, field)
148+ to_arrow_list :: < i64 > ( array, field, arrow_type_opt . is_none ( ) )
144149 }
145150 ( Canonical :: VarBinView ( array) , DataType :: BinaryView ) if array. dtype ( ) . is_binary ( ) => {
146151 to_arrow_varbinview :: < BinaryViewType > ( array)
@@ -277,7 +282,11 @@ fn to_arrow_decimal256(array: DecimalArray) -> VortexResult<ArrowArrayRef> {
277282 ) )
278283}
279284
280- fn to_arrow_struct ( array : StructArray , fields : & [ FieldRef ] ) -> VortexResult < ArrowArrayRef > {
285+ fn to_arrow_struct (
286+ array : StructArray ,
287+ fields : & [ FieldRef ] ,
288+ to_preferred : bool ,
289+ ) -> VortexResult < ArrowArrayRef > {
281290 if array. fields ( ) . len ( ) != fields. len ( ) {
282291 vortex_bail ! (
283292 "StructArray has {} fields, but target Arrow type has {} fields" ,
@@ -301,9 +310,12 @@ fn to_arrow_struct(array: StructArray, fields: &[FieldRef]) -> VortexResult<Arro
301310 ) ;
302311 }
303312
304- arr. clone ( )
305- . into_arrow ( field. data_type ( ) )
306- . map_err ( |err| err. with_context ( format ! ( "Failed to canonicalize field {field}" ) ) )
313+ let result = if to_preferred {
314+ arr. clone ( ) . into_arrow_preferred ( )
315+ } else {
316+ arr. clone ( ) . into_arrow ( field. data_type ( ) )
317+ } ;
318+ result. map_err ( |err| err. with_context ( format ! ( "Failed to canonicalize field {field}" ) ) )
307319 } )
308320 . collect :: < VortexResult < Vec < _ > > > ( ) ?;
309321
@@ -341,14 +353,19 @@ fn to_arrow_struct(array: StructArray, fields: &[FieldRef]) -> VortexResult<Arro
341353fn to_arrow_list < O : NativePType + OffsetSizeTrait > (
342354 array : ListArray ,
343355 element : & FieldRef ,
356+ to_preferred : bool ,
344357) -> VortexResult < ArrowArrayRef > {
345358 // First we cast the offsets into the correct width.
346359 let offsets_dtype = DType :: Primitive ( O :: PTYPE , array. dtype ( ) . nullability ( ) ) ;
347360 let arrow_offsets = cast ( array. offsets ( ) , & offsets_dtype)
348361 . map_err ( |err| err. with_context ( format ! ( "Failed to cast offsets to {offsets_dtype}" ) ) ) ?
349362 . to_primitive ( ) ?;
350363
351- let values = array. elements ( ) . clone ( ) . into_arrow ( element. data_type ( ) ) ?;
364+ let values = if to_preferred {
365+ array. elements ( ) . clone ( ) . into_arrow_preferred ( ) ?
366+ } else {
367+ array. elements ( ) . clone ( ) . into_arrow ( element. data_type ( ) ) ?
368+ } ;
352369 let nulls = array. validity_mask ( ) ?. to_null_buffer ( ) ;
353370
354371 Ok ( Arc :: new ( GenericListArray :: new (
0 commit comments