@@ -139,7 +139,7 @@ impl ScalarFnVTable for Zip {
139139 return mask. into_array ( ) . zip ( if_true, if_false) ;
140140 }
141141
142- zip_impl ( & if_true, & if_false, & mask)
142+ zip_impl ( & if_true, & if_false, & mask, ctx )
143143 }
144144
145145 fn simplify (
@@ -176,6 +176,7 @@ pub(crate) fn zip_impl(
176176 if_true : & ArrayRef ,
177177 if_false : & ArrayRef ,
178178 mask : & Mask ,
179+ ctx : & mut ExecutionCtx ,
179180) -> VortexResult < ArrayRef > {
180181 assert_eq ! (
181182 if_true. len( ) ,
@@ -195,12 +196,18 @@ pub(crate) fn zip_impl(
195196 return if_false. cast ( return_type) ;
196197 }
197198
199+ // `append_to_builder` requires exact dtype equality, so normalize branch
200+ // nullability to the output dtype before appending slices into the builder.
201+ let if_true = if_true. cast ( return_type. clone ( ) ) ?;
202+ let if_false = if_false. cast ( return_type. clone ( ) ) ?;
203+
198204 zip_impl_with_builder (
199- if_true,
200- if_false,
205+ & if_true,
206+ & if_false,
201207 mask. values ( )
202208 . vortex_expect ( "zip_impl_with_builder: mask is not all-true or all-false" ) ,
203209 builder_with_capacity ( & return_type, if_true. len ( ) ) ,
210+ ctx,
204211 )
205212}
206213
@@ -209,13 +216,22 @@ fn zip_impl_with_builder(
209216 if_false : & ArrayRef ,
210217 mask : & MaskValues ,
211218 mut builder : Box < dyn ArrayBuilder > ,
219+ ctx : & mut ExecutionCtx ,
212220) -> VortexResult < ArrayRef > {
213221 for ( start, end) in mask. slices ( ) {
214- builder. extend_from_array ( & if_false. slice ( builder. len ( ) ..* start) ?) ;
215- builder. extend_from_array ( & if_true. slice ( * start..* end) ?) ;
222+ if builder. len ( ) < * start {
223+ if_false
224+ . slice ( builder. len ( ) ..* start) ?
225+ . append_to_builder ( builder. as_mut ( ) , ctx) ?;
226+ }
227+ if_true
228+ . slice ( * start..* end) ?
229+ . append_to_builder ( builder. as_mut ( ) , ctx) ?;
216230 }
217231 if builder. len ( ) < if_false. len ( ) {
218- builder. extend_from_array ( & if_false. slice ( builder. len ( ) ..if_false. len ( ) ) ?) ;
232+ if_false
233+ . slice ( builder. len ( ) ..if_false. len ( ) ) ?
234+ . append_to_builder ( builder. as_mut ( ) , ctx) ?;
219235 }
220236 Ok ( builder. finish ( ) )
221237}
@@ -319,7 +335,8 @@ mod tests {
319335 let if_false =
320336 PrimitiveArray :: from_option_iter ( [ Some ( 1 ) , Some ( 2 ) , Some ( 3 ) , None ] ) . into_array ( ) ;
321337
322- let result = zip_impl ( & if_true, & if_false, & mask) ?;
338+ let mut ctx = LEGACY_SESSION . create_execution_ctx ( ) ;
339+ let result = zip_impl ( & if_true, & if_false, & mask, & mut ctx) ?;
323340 assert_arrays_eq ! (
324341 result,
325342 PrimitiveArray :: from_option_iter( [ Some ( 10i32 ) , Some ( 20 ) , Some ( 30 ) , Some ( 40 ) ] )
@@ -336,7 +353,8 @@ mod tests {
336353 PrimitiveArray :: from_option_iter ( [ Some ( 10 ) , Some ( 20 ) , Some ( 30 ) , None ] ) . into_array ( ) ;
337354 let if_false = buffer ! [ 1i32 , 2 , 3 , 4 ] . into_array ( ) ;
338355
339- let result = zip_impl ( & if_true, & if_false, & mask) ?;
356+ let mut ctx = LEGACY_SESSION . create_execution_ctx ( ) ;
357+ let result = zip_impl ( & if_true, & if_false, & mask, & mut ctx) ?;
340358 assert_arrays_eq ! (
341359 result,
342360 PrimitiveArray :: from_option_iter( [ Some ( 1i32 ) , Some ( 2 ) , Some ( 3 ) , Some ( 4 ) ] ) . into_array( )
0 commit comments