@@ -18,7 +18,6 @@ use vortex_error::vortex_err;
1818use crate :: ArrayRef ;
1919use crate :: ArraySlots ;
2020use crate :: ExecutionCtx ;
21- use crate :: VortexSessionExecute ;
2221use crate :: aggregate_fn:: NumericalAggregateOpts ;
2322use crate :: aggregate_fn:: fns:: min_max:: min_max;
2423use crate :: array:: Array ;
@@ -33,7 +32,6 @@ use crate::buffer::BufferHandle;
3332use crate :: dtype:: DType ;
3433use crate :: dtype:: Nullability ;
3534use crate :: dtype:: OffsetBuilderPType ;
36- use crate :: legacy_session;
3735use crate :: match_each_integer_ptype;
3836use crate :: validity:: Validity ;
3937
@@ -102,8 +100,14 @@ impl VarBinData {
102100 ///
103101 /// Panics if the provided components do not satisfy the invariants documented
104102 /// in `VarBinArray::new_unchecked`.
105- pub fn build ( offsets : ArrayRef , bytes : ByteBuffer , dtype : DType , validity : Validity ) -> Self {
106- Self :: try_build ( offsets, bytes, dtype, validity) . vortex_expect ( "VarBinArray new" )
103+ pub fn build (
104+ offsets : ArrayRef ,
105+ bytes : ByteBuffer ,
106+ dtype : DType ,
107+ validity : Validity ,
108+ ctx : & mut ExecutionCtx ,
109+ ) -> Self {
110+ Self :: try_build ( offsets, bytes, dtype, validity, ctx) . vortex_expect ( "VarBinArray new" )
107111 }
108112
109113 /// Creates a new `VarBinArray`.
@@ -117,8 +121,10 @@ impl VarBinData {
117121 bytes : BufferHandle ,
118122 dtype : DType ,
119123 validity : Validity ,
124+ ctx : & mut ExecutionCtx ,
120125 ) -> Self {
121- Self :: try_build_from_handle ( offset, bytes, dtype, validity) . vortex_expect ( "VarBinArray new" )
126+ Self :: try_build_from_handle ( offset, bytes, dtype, validity, ctx)
127+ . vortex_expect ( "VarBinArray new" )
122128 }
123129
124130 pub ( crate ) fn make_slots ( offsets : ArrayRef , validity : & Validity , len : usize ) -> ArraySlots {
@@ -142,9 +148,10 @@ impl VarBinData {
142148 bytes : ByteBuffer ,
143149 dtype : DType ,
144150 validity : Validity ,
151+ ctx : & mut ExecutionCtx ,
145152 ) -> VortexResult < Self > {
146153 let bytes = BufferHandle :: new_host ( bytes) ;
147- Self :: validate ( & offsets, & bytes, & dtype, & validity) ?;
154+ Self :: validate ( & offsets, & bytes, & dtype, & validity, ctx ) ?;
148155
149156 // SAFETY: validate ensures all invariants are met.
150157 Ok ( unsafe { Self :: new_unchecked_from_handle ( bytes) } )
@@ -164,8 +171,9 @@ impl VarBinData {
164171 bytes : BufferHandle ,
165172 dtype : DType ,
166173 validity : Validity ,
174+ ctx : & mut ExecutionCtx ,
167175 ) -> VortexResult < Self > {
168- Self :: validate ( & offsets, & bytes, & dtype, & validity) ?;
176+ Self :: validate ( & offsets, & bytes, & dtype, & validity, ctx ) ?;
169177
170178 // SAFETY: validate ensures all invariants are met.
171179 Ok ( unsafe { Self :: new_unchecked_from_handle ( bytes) } )
@@ -218,12 +226,12 @@ impl VarBinData {
218226 /// Validates the components that would be used to create a `VarBinArray`.
219227 ///
220228 /// This function checks all the invariants required by `VarBinArray::new_unchecked`.
221- #[ allow( clippy:: disallowed_methods) ]
222229 pub fn validate (
223230 offsets : & ArrayRef ,
224231 bytes : & BufferHandle ,
225232 dtype : & DType ,
226233 validity : & Validity ,
234+ ctx : & mut ExecutionCtx ,
227235 ) -> VortexResult < ( ) > {
228236 // Check offsets are non-nullable integer
229237 vortex_ensure ! (
@@ -267,10 +275,9 @@ impl VarBinData {
267275 && matches ! ( dtype, DType :: Utf8 ( _) )
268276 && let Some ( bytes) = bytes. as_host_opt ( )
269277 {
270- Self :: validate_utf8 ( offsets, bytes. as_ref ( ) , validity) ?;
278+ Self :: validate_utf8 ( offsets, bytes. as_ref ( ) , validity, ctx ) ?;
271279 } else if offsets. is_host ( ) {
272- let mut ctx = legacy_session ( ) . create_execution_ctx ( ) ;
273- Self :: validate_offsets ( offsets, bytes. len ( ) , & mut ctx) ?;
280+ Self :: validate_offsets ( offsets, bytes. len ( ) , ctx) ?;
274281 }
275282
276283 Ok ( ( ) )
@@ -328,8 +335,12 @@ impl VarBinData {
328335 }
329336
330337 /// Validates that every non-null value is valid UTF-8.
331- #[ allow( clippy:: disallowed_methods) ]
332- fn validate_utf8 ( offsets : & ArrayRef , bytes : & [ u8 ] , validity : & Validity ) -> VortexResult < ( ) > {
338+ fn validate_utf8 (
339+ offsets : & ArrayRef ,
340+ bytes : & [ u8 ] ,
341+ validity : & Validity ,
342+ ctx : & mut ExecutionCtx ,
343+ ) -> VortexResult < ( ) > {
333344 let validate_at = |i : usize , start : usize , end : usize | -> VortexResult < ( ) > {
334345 let string_bytes = bytes. get ( start..end) . ok_or_else ( || {
335346 vortex_err ! (
@@ -346,16 +357,15 @@ impl VarBinData {
346357 Ok ( ( ) )
347358 } ;
348359
349- let mut ctx = legacy_session ( ) . create_execution_ctx ( ) ;
350360 // TODO(joe): update the created VarBin with this decompressed Array.
351- let primitive_offsets = offsets. clone ( ) . execute :: < PrimitiveArray > ( & mut ctx) ?;
361+ let primitive_offsets = offsets. clone ( ) . execute :: < PrimitiveArray > ( ctx) ?;
352362
353363 // Array-backed validity is the only variant that needs an execution context: execute it into
354364 // a mask once. The constant variants resolve null-ness without one. Resolving this before
355365 // the per-type dispatch keeps the dtype loop simple.
356366 let mask = match validity {
357367 Validity :: Array ( _) => {
358- Some ( validity. execute_mask ( primitive_offsets. len ( ) . saturating_sub ( 1 ) , & mut ctx) ?)
368+ Some ( validity. execute_mask ( primitive_offsets. len ( ) . saturating_sub ( 1 ) , ctx) ?)
359369 }
360370 _ => None ,
361371 } ;
@@ -378,7 +388,7 @@ impl VarBinData {
378388
379389 // The fast path proves the offsets are valid. The per-string check below skips null
380390 // rows, so it cannot find bad offsets at those rows.
381- Self :: validate_offsets( offsets, bytes. len( ) , & mut ctx) ?;
391+ Self :: validate_offsets( offsets, bytes. len( ) , ctx) ?;
382392
383393 // Invalid bytes at a null row fail the check above, so check valid strings one by one.
384394 for ( i, ( start, end) ) in offsets_slice
@@ -438,8 +448,7 @@ pub trait VarBinArrayExt: VarBinArraySlotsExt {
438448 )
439449 }
440450
441- #[ allow( clippy:: disallowed_methods) ]
442- fn offset_at ( & self , index : usize ) -> usize {
451+ fn offset_at ( & self , index : usize , ctx : & mut ExecutionCtx ) -> usize {
443452 assert ! (
444453 index <= self . len( ) ,
445454 "Index {index} out of bounds 0..={}" ,
@@ -448,21 +457,21 @@ pub trait VarBinArrayExt: VarBinArraySlotsExt {
448457
449458 ( & self
450459 . offsets ( )
451- . execute_scalar ( index, & mut legacy_session ( ) . create_execution_ctx ( ) )
460+ . execute_scalar ( index, ctx )
452461 . vortex_expect ( "offsets must support execute_scalar" ) )
453462 . try_into ( )
454463 . vortex_expect ( "Failed to convert offset to usize" )
455464 }
456465
457- fn bytes_at ( & self , index : usize ) -> ByteBuffer {
458- let start = self . offset_at ( index) ;
459- let end = self . offset_at ( index + 1 ) ;
466+ fn bytes_at ( & self , index : usize , ctx : & mut ExecutionCtx ) -> ByteBuffer {
467+ let start = self . offset_at ( index, ctx ) ;
468+ let end = self . offset_at ( index + 1 , ctx ) ;
460469 self . bytes ( ) . slice ( start..end)
461470 }
462471
463- fn sliced_bytes ( & self ) -> ByteBuffer {
464- let first_offset: usize = self . offset_at ( 0 ) ;
465- let last_offset = self . offset_at ( self . len ( ) ) ;
472+ fn sliced_bytes ( & self , ctx : & mut ExecutionCtx ) -> ByteBuffer {
473+ let first_offset: usize = self . offset_at ( 0 , ctx ) ;
474+ let last_offset = self . offset_at ( self . len ( ) , ctx ) ;
466475 self . bytes ( ) . slice ( first_offset..last_offset)
467476 }
468477}
@@ -567,7 +576,13 @@ impl Array<VarBin> {
567576
568577impl Array < VarBin > {
569578 /// Creates a new `VarBinArray`.
570- pub fn new ( offsets : ArrayRef , bytes : ByteBuffer , dtype : DType , validity : Validity ) -> Self {
579+ pub fn new (
580+ offsets : ArrayRef ,
581+ bytes : ByteBuffer ,
582+ dtype : DType ,
583+ validity : Validity ,
584+ ctx : & mut ExecutionCtx ,
585+ ) -> Self {
571586 let len = offsets. len ( ) . saturating_sub ( 1 ) ;
572587 let slots = VarBinData :: make_slots ( offsets, & validity, len) ;
573588 let data = VarBinData :: build (
@@ -578,6 +593,7 @@ impl Array<VarBin> {
578593 bytes,
579594 dtype. clone ( ) ,
580595 validity,
596+ ctx,
581597 ) ;
582598 unsafe { Array :: from_parts_unchecked ( ArrayParts :: new ( VarBin , dtype, len, data, slots) ) }
583599 }
@@ -616,16 +632,18 @@ impl Array<VarBin> {
616632 unsafe { Array :: from_parts_unchecked ( ArrayParts :: new ( VarBin , dtype, len, data, slots) ) }
617633 }
618634
619- /// Constructs a new `VarBinArray`.
635+ /// Constructs a new `VarBinArray`, using `ctx` to validate the offsets and, for UTF-8 arrays,
636+ /// the string data.
620637 pub fn try_new (
621638 offsets : ArrayRef ,
622639 bytes : ByteBuffer ,
623640 dtype : DType ,
624641 validity : Validity ,
642+ ctx : & mut ExecutionCtx ,
625643 ) -> VortexResult < Self > {
626644 let len = offsets. len ( ) - 1 ;
627645 let bytes = BufferHandle :: new_host ( bytes) ;
628- VarBinData :: validate ( & offsets, & bytes, & dtype, & validity) ?;
646+ VarBinData :: validate ( & offsets, & bytes, & dtype, & validity, ctx ) ?;
629647 let slots = VarBinData :: make_slots ( offsets, & validity, len) ;
630648 // SAFETY: validate ensures all invariants are met.
631649 let data = unsafe { VarBinData :: new_unchecked_from_handle ( bytes) } ;
0 commit comments