22// SPDX-FileCopyrightText: Copyright the Vortex contributors
33
44use vortex:: array:: ArrayRef ;
5+ use vortex:: array:: ExecutionCtx ;
56use vortex:: array:: IntoArray ;
67use vortex:: array:: arrays:: Constant ;
78use vortex:: array:: arrays:: ConstantArray ;
89use vortex:: array:: arrays:: Extension ;
10+ use vortex:: array:: arrays:: FixedSizeListArray ;
911use vortex:: array:: arrays:: PrimitiveArray ;
1012use vortex:: dtype:: DType ;
1113use vortex:: dtype:: NativePType ;
@@ -19,15 +21,15 @@ use vortex::error::vortex_err;
1921/// Extracts the list size from a tensor-like extension dtype.
2022///
2123/// The storage dtype must be a `FixedSizeList`.
22- pub fn extension_list_size ( ext : & ExtDTypeRef ) -> VortexResult < usize > {
24+ pub fn extension_list_size ( ext : & ExtDTypeRef ) -> VortexResult < u32 > {
2325 let DType :: FixedSizeList ( _, list_size, _) = ext. storage_dtype ( ) else {
2426 vortex_bail ! (
2527 "expected FixedSizeList storage dtype, got {}" ,
2628 ext. storage_dtype( )
2729 ) ;
2830 } ;
2931
30- Ok ( * list_size as usize )
32+ Ok ( * list_size)
3133}
3234
3335/// Extracts the float element [`PType`] from a tensor-like extension dtype.
@@ -91,13 +93,17 @@ impl FlatElements {
9193///
9294/// When the input is a [`ConstantArray`] (e.g., a literal query vector), only a single row is
9395/// materialized to avoid expanding it to the full column length.
94- pub fn extract_flat_elements ( storage : & ArrayRef , list_size : usize ) -> VortexResult < FlatElements > {
96+ pub fn extract_flat_elements (
97+ storage : & ArrayRef ,
98+ list_size : usize ,
99+ ctx : & mut ExecutionCtx ,
100+ ) -> VortexResult < FlatElements > {
95101 if let Some ( constant) = storage. as_opt :: < Constant > ( ) {
96102 // Rewrite the array as a length 1 array so when we canonicalize, we do not duplicate a huge
97103 // amount of data.
98104 let single = ConstantArray :: new ( constant. scalar ( ) . clone ( ) , 1 ) . into_array ( ) ;
99- let fsl = single. to_canonical ( ) ? . into_fixed_size_list ( ) ;
100- let elems = fsl. elements ( ) . to_canonical ( ) ? . into_primitive ( ) ;
105+ let fsl: FixedSizeListArray = single. execute ( ctx ) ? ;
106+ let elems: PrimitiveArray = fsl. elements ( ) . clone ( ) . execute ( ctx ) ? ;
101107 return Ok ( FlatElements {
102108 elems,
103109 stride : 0 ,
@@ -106,8 +112,8 @@ pub fn extract_flat_elements(storage: &ArrayRef, list_size: usize) -> VortexResu
106112 }
107113
108114 // Otherwise we have to fully expand all of the data.
109- let fsl = storage. to_canonical ( ) ? . into_fixed_size_list ( ) ;
110- let elems = fsl. elements ( ) . to_canonical ( ) ? . into_primitive ( ) ;
115+ let fsl: FixedSizeListArray = storage. clone ( ) . execute ( ctx ) ? ;
116+ let elems: PrimitiveArray = fsl. elements ( ) . clone ( ) . execute ( ctx ) ? ;
111117 Ok ( FlatElements {
112118 elems,
113119 stride : list_size,
@@ -118,6 +124,7 @@ pub fn extract_flat_elements(storage: &ArrayRef, list_size: usize) -> VortexResu
118124#[ cfg( test) ]
119125pub mod test_helpers {
120126 use vortex:: array:: ArrayRef ;
127+ use vortex:: array:: ExecutionCtx ;
121128 use vortex:: array:: IntoArray ;
122129 use vortex:: array:: arrays:: ConstantArray ;
123130 use vortex:: array:: arrays:: ExtensionArray ;
@@ -128,9 +135,13 @@ pub mod test_helpers {
128135 use vortex:: dtype:: Nullability ;
129136 use vortex:: dtype:: extension:: ExtDType ;
130137 use vortex:: error:: VortexResult ;
138+ use vortex:: error:: vortex_err;
131139 use vortex:: extension:: EmptyMetadata ;
132140 use vortex:: scalar:: Scalar ;
133141
142+ use super :: extension_list_size;
143+ use super :: extension_storage;
144+ use super :: extract_flat_elements;
134145 use crate :: fixed_shape:: FixedShapeTensor ;
135146 use crate :: fixed_shape:: FixedShapeTensorMetadata ;
136147 use crate :: vector:: Vector ;
@@ -210,6 +221,26 @@ pub mod test_helpers {
210221 Ok ( ExtensionArray :: new ( ext_dtype, storage) . into_array ( ) )
211222 }
212223
224+ #[ expect( dead_code, reason = "TODO(connor): Use this!" ) ]
225+ /// Extracts the f64 rows from a [`Vector`] extension array.
226+ ///
227+ /// Returns a `Vec<Vec<f64>>` where each inner vec is one vector's elements.
228+ pub fn extract_vector_rows (
229+ array : & ArrayRef ,
230+ ctx : & mut ExecutionCtx ,
231+ ) -> VortexResult < Vec < Vec < f64 > > > {
232+ let ext = array
233+ . dtype ( )
234+ . as_extension_opt ( )
235+ . ok_or_else ( || vortex_err ! ( "expected Vector extension dtype, got {}" , array. dtype( ) ) ) ?;
236+ let list_size = extension_list_size ( ext) ? as usize ;
237+ let storage = extension_storage ( array) ?;
238+ let flat = extract_flat_elements ( & storage, list_size, ctx) ?;
239+ Ok ( ( 0 ..array. len ( ) )
240+ . map ( |i| flat. row :: < f64 > ( i) . to_vec ( ) )
241+ . collect ( ) )
242+ }
243+
213244 /// Asserts that each element in `actual` is within `1e-10` of the corresponding `expected`
214245 /// value, with support for NaN (NaN == NaN is considered equal).
215246 #[ track_caller]
0 commit comments