11mod data_chunk_adaptor;
22
3- use duckdb:: core:: DataChunkHandle ;
3+ use arrow_array:: ArrayRef as ArrowArrayRef ;
4+ use duckdb:: core:: { DataChunkHandle , SelectionVector } ;
45use duckdb:: vtab:: arrow:: {
56 WritableVector , flat_vector_to_arrow_array, write_arrow_array_to_vector,
67} ;
78use vortex_array:: arrays:: StructArray ;
89use vortex_array:: arrow:: { FromArrowArray , IntoArrowArray } ;
10+ use vortex_array:: compute:: try_cast;
911use vortex_array:: validity:: Validity ;
10- use vortex_array:: { Array , ArrayRef } ;
11- use vortex_error:: { VortexResult , vortex_err} ;
12+ use vortex_array:: vtable:: EncodingVTable ;
13+ use vortex_array:: { Array , ArrayRef , ArrayStatistics , ToCanonical } ;
14+ use vortex_dict:: { DictArray , DictEncoding } ;
15+ use vortex_dtype:: DType ;
16+ use vortex_dtype:: Nullability :: NonNullable ;
17+ use vortex_dtype:: PType :: U32 ;
18+ use vortex_error:: { VortexExpect , VortexResult , vortex_err} ;
1219
1320use crate :: convert:: array:: data_chunk_adaptor:: {
1421 DataChunkHandleSlice , NamedDataChunk , SizedFlatVector ,
1522} ;
23+ use crate :: convert:: scalar:: ToDuckDBScalar ;
1624
1725pub trait ToDuckDB {
1826 fn to_duckdb ( & self , chunk : & mut dyn WritableVector ) -> VortexResult < ( ) > ;
1927}
2028
29+ pub fn to_duckdb ( array : ArrayRef , chunk : & mut dyn WritableVector ) -> VortexResult < ( ) > {
30+ if let Some ( constant) = array. as_constant ( ) {
31+ let value = constant. to_duckdb_scalar ( ) ;
32+ chunk. flat_vector ( ) . assign_to_constant ( & value) ;
33+ Ok ( ( ) )
34+ } else if array. is_encoding ( DictEncoding . id ( ) ) {
35+ array
36+ . as_any ( )
37+ . downcast_ref :: < DictArray > ( )
38+ . vortex_expect ( "dict id checked" )
39+ . to_duckdb ( chunk)
40+ } else {
41+ array. into_arrow_preferred ( ) ?. to_duckdb ( chunk)
42+ }
43+ }
44+
45+ impl ToDuckDB for DictArray {
46+ fn to_duckdb ( & self , chunk : & mut dyn WritableVector ) -> VortexResult < ( ) > {
47+ to_duckdb ( self . values ( ) . clone ( ) , chunk) ?;
48+ let indices =
49+ try_cast ( self . codes ( ) , & DType :: Primitive ( U32 , NonNullable ) ) ?. to_primitive ( ) ?;
50+ let indices = indices. as_slice :: < u32 > ( ) ;
51+ let sel = SelectionVector :: new_copy ( indices) ;
52+ chunk. flat_vector ( ) . slice ( sel) ;
53+ Ok ( ( ) )
54+ }
55+ }
56+
2157pub fn to_duckdb_chunk (
2258 struct_array : & StructArray ,
2359 chunk : & mut DataChunkHandle ,
24- ) -> VortexResult < Vec < bool > > {
25- let mut nullable = vec ! [ false ; struct_array. len( ) ] ;
60+ ) -> VortexResult < ( ) > {
61+ chunk . set_len ( struct_array. len ( ) ) ;
2662 for ( idx, field) in struct_array. fields ( ) . iter ( ) . enumerate ( ) {
27- field. to_duckdb ( & mut DataChunkHandleSlice :: new ( chunk, idx) ) ?;
28- nullable[ idx] = field. dtype ( ) . is_nullable ( ) ;
63+ to_duckdb ( field. clone ( ) , & mut DataChunkHandleSlice :: new ( chunk, idx) ) ?;
2964 }
30- chunk. set_len ( struct_array. len ( ) ) ;
31- Ok ( nullable)
65+ Ok ( ( ) )
3266}
3367
34- impl ToDuckDB for ArrayRef {
68+ impl ToDuckDB for ArrowArrayRef {
3569 fn to_duckdb ( & self , chunk : & mut dyn WritableVector ) -> VortexResult < ( ) > {
36- let arrow = & self . clone ( ) . into_arrow_preferred ( ) ?;
37- write_arrow_array_to_vector ( arrow, chunk)
70+ write_arrow_array_to_vector ( self , chunk)
3871 . map_err ( |e| vortex_err ! ( "Failed to convert vrotex duckdb array: {}" , e. to_string( ) ) )
3972 }
4073}
@@ -89,9 +122,11 @@ impl FromDuckDB<SizedFlatVector> for ArrayRef {
89122
90123#[ cfg( test) ]
91124mod tests {
92- use duckdb:: core:: DataChunkHandle ;
93- use itertools:: Itertools ;
94- use vortex_array:: arrays:: { BoolArray , PrimitiveArray , StructArray , VarBinArray } ;
125+
126+ use duckdb:: core:: { DataChunkHandle , LogicalTypeHandle , LogicalTypeId } ;
127+ use vortex_array:: arrays:: {
128+ BoolArray , ConstantArray , PrimitiveArray , StructArray , VarBinArray ,
129+ } ;
95130 use vortex_array:: validity:: Validity ;
96131 use vortex_array:: variants:: StructArrayTrait ;
97132 use vortex_array:: { Array , ArrayRef , ToCanonical } ;
@@ -122,16 +157,16 @@ mod tests {
122157 #[ test]
123158 fn test_vortex_to_duckdb ( ) {
124159 let arr = data ( ) ;
125- let ddb_type = arr
160+ let ( nullable , ddb_type) : ( Vec < _ > , Vec < _ > ) = arr
126161 . dtype ( )
127162 . as_struct ( )
128163 . unwrap ( )
129164 . fields ( )
130- . map ( |f| f . to_duckdb_type ( ) . unwrap ( ) )
131- . collect_vec ( ) ;
165+ . map ( |f| ( f . is_nullable ( ) , f . to_duckdb_type ( ) . unwrap ( ) ) )
166+ . unzip ( ) ;
132167 let struct_arr = arr. to_struct ( ) . unwrap ( ) ;
133168 let mut output_chunk = DataChunkHandle :: new ( ddb_type. as_slice ( ) ) ;
134- let nullable = to_duckdb_chunk ( & struct_arr, & mut output_chunk) . unwrap ( ) ;
169+ to_duckdb_chunk ( & struct_arr, & mut output_chunk) . unwrap ( ) ;
135170
136171 let vx_arr = ArrayRef :: from_duckdb ( & NamedDataChunk :: new (
137172 & output_chunk,
@@ -149,4 +184,21 @@ mod tests {
149184 assert_eq ! ( vx_arr. len( ) , arr. len( ) ) ;
150185 assert_eq ! ( vx_arr. dtype( ) , arr. dtype( ) ) ;
151186 }
187+
188+ #[ test]
189+ fn test_const_vortex_to_duckdb ( ) {
190+ let arr = ConstantArray :: new :: < i64 > ( 23444233 , 100 ) . to_array ( ) ;
191+ let arr2 = ConstantArray :: new :: < i32 > ( 234 , 100 ) . to_array ( ) ;
192+ let st = StructArray :: from_fields ( & [ ( "1" , arr. clone ( ) ) , ( "2" , arr2. clone ( ) ) ] ) . unwrap ( ) ;
193+ let mut output_chunk = DataChunkHandle :: new ( & [
194+ LogicalTypeHandle :: from ( LogicalTypeId :: Bigint ) ,
195+ LogicalTypeHandle :: from ( LogicalTypeId :: Integer ) ,
196+ ] ) ;
197+ to_duckdb_chunk ( & st, & mut output_chunk) . unwrap ( ) ;
198+
199+ assert_eq ! (
200+ format!( "{:?}" , output_chunk) ,
201+ "Chunk - [2 Columns]\n - CONSTANT BIGINT: 100 = [ 23444233]\n - CONSTANT INTEGER: 100 = [ 234]\n "
202+ )
203+ }
152204}
0 commit comments