@@ -21,6 +21,7 @@ use crate::arrays::VarBin;
2121use crate :: arrays:: VarBinArray ;
2222use crate :: arrays:: dict:: TakeExecute ;
2323use crate :: arrays:: piecewise_sequence:: UnitMultiplierLengths ;
24+ use crate :: arrays:: piecewise_sequence:: copy_slice_to_spare;
2425use crate :: arrays:: piecewise_sequence:: execute_unit_multiplier_index_arrays;
2526use crate :: arrays:: primitive:: PrimitiveArrayExt ;
2627use crate :: arrays:: varbin:: VarBinArrayExt ;
@@ -467,6 +468,7 @@ where
467468 }
468469
469470 let mut new_data = ByteBufferMut :: with_capacity ( output_bytes) ;
471+ let mut cursor = 0usize ;
470472 for & start in starts {
471473 let start = start. as_ ( ) ;
472474 if length == 0 {
@@ -476,8 +478,20 @@ where
476478 let offset_range = & offsets[ start..] [ ..=length] ;
477479 let byte_start = offset_range[ 0 ] . as_ ( ) ;
478480 let byte_end = offset_range[ length] . as_ ( ) ;
479- new_data. extend_from_slice ( & data[ byte_start..] [ ..byte_end - byte_start] ) ;
481+ cursor = copy_slice_to_spare (
482+ & mut new_data,
483+ cursor,
484+ & data[ byte_start..] [ ..byte_end - byte_start] ,
485+ output_bytes,
486+ ) ?;
480487 }
488+ vortex_ensure ! (
489+ cursor == output_bytes,
490+ "VarBin byte copy length {cursor} does not match computed byte length {output_bytes}"
491+ ) ;
492+ // SAFETY: `copy_slice_to_spare` checked every write against `output_bytes`, and `cursor ==
493+ // output_bytes` proves all bytes were initialized.
494+ unsafe { new_data. set_len ( output_bytes) } ;
481495
482496 let offsets = PrimitiveArray :: new ( new_offsets. freeze ( ) , Validity :: NonNullable )
483497 . reinterpret_cast ( out_offset_ptype)
@@ -544,6 +558,7 @@ where
544558 ) ;
545559
546560 let mut new_data = ByteBufferMut :: with_capacity ( output_bytes) ;
561+ let mut cursor = 0usize ;
547562 for ( & start, & length) in starts. iter ( ) . zip_eq ( lengths) {
548563 let start = start. as_ ( ) ;
549564 let length = length. as_ ( ) ;
@@ -554,8 +569,20 @@ where
554569 let offset_range = & offsets[ start..] [ ..=length] ;
555570 let byte_start = offset_range[ 0 ] . as_ ( ) ;
556571 let byte_end = offset_range[ length] . as_ ( ) ;
557- new_data. extend_from_slice ( & data[ byte_start..] [ ..byte_end - byte_start] ) ;
572+ cursor = copy_slice_to_spare (
573+ & mut new_data,
574+ cursor,
575+ & data[ byte_start..] [ ..byte_end - byte_start] ,
576+ output_bytes,
577+ ) ?;
558578 }
579+ vortex_ensure ! (
580+ cursor == output_bytes,
581+ "VarBin byte copy length {cursor} does not match computed byte length {output_bytes}"
582+ ) ;
583+ // SAFETY: `copy_slice_to_spare` checked every write against `output_bytes`, and `cursor ==
584+ // output_bytes` proves all bytes were initialized.
585+ unsafe { new_data. set_len ( output_bytes) } ;
559586
560587 let offsets = PrimitiveArray :: new ( new_offsets. freeze ( ) , Validity :: NonNullable )
561588 . reinterpret_cast ( out_offset_ptype)
0 commit comments