@@ -84,6 +84,53 @@ pub struct DecimalBytesPartsMetadata {
8484}
8585
8686impl DecimalBytesPartsMetadata {
87+ fn from_array ( array : ArrayView < ' _ , DecimalByteParts > ) -> VortexResult < Self > {
88+ Ok ( Self {
89+ zeroth_child_ptype : PType :: try_from ( array. msp ( ) . dtype ( ) ) ? as i32 ,
90+ lower_part_count : u32:: try_from ( array. lower_parts ( ) . len ( ) )
91+ . map_err ( |_| vortex_err ! ( "lower part count exceeds u32" ) ) ?,
92+ } )
93+ }
94+
95+ fn into_array_parts (
96+ self ,
97+ dtype : & DType ,
98+ len : usize ,
99+ children : & dyn ArrayChildren ,
100+ ) -> VortexResult < ArrayParts < DecimalByteParts > > {
101+ vortex_ensure ! (
102+ dtype. as_decimal_opt( ) . is_some( ) ,
103+ "decoding decimal but given non decimal dtype {dtype}"
104+ ) ;
105+
106+ let encoded_dtype = DType :: Primitive ( self . zeroth_child_ptype ( ) , dtype. nullability ( ) ) ;
107+
108+ let lower_part_count = self . lower_part_count ( ) ?;
109+ vortex_ensure ! (
110+ children. len( ) == DecimalBytePartsSlots :: FIXED_COUNT + lower_part_count,
111+ "expected {} children, got {}" ,
112+ DecimalBytePartsSlots :: FIXED_COUNT + lower_part_count,
113+ children. len( )
114+ ) ;
115+
116+ let msp = children. get ( DecimalBytePartsSlots :: MSP , & encoded_dtype, len) ?;
117+
118+ let mut slots = ArraySlots :: with_capacity ( children. len ( ) ) ;
119+ slots. push ( Some ( msp) ) ;
120+ for idx in 0 ..lower_part_count {
121+ slots. push ( Some ( children. get (
122+ DecimalBytePartsSlots :: LOWER_PARTS_OFFSET + idx,
123+ & LOWER_PART_DTYPE ,
124+ len,
125+ ) ?) ) ;
126+ }
127+
128+ Ok (
129+ ArrayParts :: new ( DecimalByteParts , dtype. clone ( ) , len, DecimalBytePartsData )
130+ . with_slots ( slots) ,
131+ )
132+ }
133+
87134 /// The number of lower parts encoded in this array.
88135 ///
89136 /// # Errors
@@ -155,14 +202,12 @@ impl VTable for DecimalByteParts {
155202 array : ArrayView < ' _ , Self > ,
156203 _session : & VortexSession ,
157204 ) -> VortexResult < Option < Vec < u8 > > > {
158- let lower_part_count = u32:: try_from ( array. lower_parts ( ) . len ( ) )
159- . map_err ( |_| vortex_err ! ( "lower part count exceeds u32" ) ) ?;
205+ vortex_ensure ! (
206+ array. lower_parts( ) . is_empty( ) ,
207+ "serializing DecimalByteParts with lower parts requires DecimalBytePartsPlugin"
208+ ) ;
160209 Ok ( Some (
161- DecimalBytesPartsMetadata {
162- zeroth_child_ptype : PType :: try_from ( array. msp ( ) . dtype ( ) ) ? as i32 ,
163- lower_part_count,
164- }
165- . encode_to_vec ( ) ,
210+ DecimalBytesPartsMetadata :: from_array ( array) ?. encode_to_vec ( ) ,
166211 ) )
167212 }
168213
@@ -177,36 +222,10 @@ impl VTable for DecimalByteParts {
177222 ) -> VortexResult < ArrayParts < Self > > {
178223 let metadata = DecimalBytesPartsMetadata :: decode ( metadata) ?;
179224 vortex_ensure ! (
180- dtype . as_decimal_opt ( ) . is_some ( ) ,
181- "decoding decimal but given non decimal dtype {dtype} "
225+ metadata . lower_part_count ( ) ? == 0 ,
226+ "vortex.decimal_byte_parts must not carry lower parts "
182227 ) ;
183-
184- let encoded_dtype = DType :: Primitive ( metadata. zeroth_child_ptype ( ) , dtype. nullability ( ) ) ;
185-
186- let lower_part_count = metadata. lower_part_count ( ) ?;
187- vortex_ensure ! (
188- children. len( ) == DecimalBytePartsSlots :: FIXED_COUNT + lower_part_count,
189- "expected {} children, got {}" ,
190- DecimalBytePartsSlots :: FIXED_COUNT + lower_part_count,
191- children. len( )
192- ) ;
193-
194- let msp = children. get ( DecimalBytePartsSlots :: MSP , & encoded_dtype, len) ?;
195-
196- let mut slots = ArraySlots :: with_capacity ( children. len ( ) ) ;
197- slots. push ( Some ( msp) ) ;
198- for idx in 0 ..lower_part_count {
199- slots. push ( Some ( children. get (
200- DecimalBytePartsSlots :: LOWER_PARTS_OFFSET + idx,
201- & LOWER_PART_DTYPE ,
202- len,
203- ) ?) ) ;
204- }
205-
206- Ok (
207- ArrayParts :: new ( self . clone ( ) , dtype. clone ( ) , len, DecimalBytePartsData )
208- . with_slots ( slots) ,
209- )
228+ metadata. into_array_parts ( dtype, len, children)
210229 }
211230
212231 fn slot_name ( _array : ArrayView < ' _ , Self > , idx : usize ) -> String {
@@ -362,6 +381,9 @@ pub fn decimal_byte_parts_v2_id() -> ArrayId {
362381/// serializes under [`decimal_byte_parts_v2_id`]. Reading holds each ID to its own contract:
363382/// the frozen ID carries no lower parts and the v2 ID carries at least one, so recognizing the
364383/// newer format never widens what the frozen one may mean.
384+ ///
385+ /// Register this plugin, or call [`crate::initialize`], to enable both formats. Registering
386+ /// [`DecimalByteParts`] directly only supports the frozen format.
365387#[ derive( Clone , Debug ) ]
366388pub struct DecimalBytePartsPlugin ;
367389
@@ -377,25 +399,33 @@ impl ArrayPlugin for DecimalBytePartsPlugin {
377399 fn serialize (
378400 & self ,
379401 array : & ArrayRef ,
380- session : & VortexSession ,
402+ _session : & VortexSession ,
381403 ) -> VortexResult < Option < ArraySerialization > > {
382- let Some ( mut serialization) = ArrayPlugin :: serialize ( & DecimalByteParts , array, session) ?
383- else {
384- return Ok ( None ) ;
404+ let view = array. as_opt :: < DecimalByteParts > ( ) . ok_or_else ( || {
405+ vortex_err ! (
406+ "DecimalByteParts plugin cannot serialize {}" ,
407+ array. encoding_id( )
408+ )
409+ } ) ?;
410+ let serialized_id = if view. lower_parts ( ) . is_empty ( ) {
411+ VTable :: id ( & DecimalByteParts )
412+ } else {
413+ decimal_byte_parts_v2_id ( )
385414 } ;
386- if !array. as_ :: < DecimalByteParts > ( ) . lower_parts ( ) . is_empty ( ) {
387- serialization. serialized_id = decimal_byte_parts_v2_id ( ) ;
388- }
389- Ok ( Some ( serialization) )
415+ Ok ( Some ( ArraySerialization :: from_array (
416+ serialized_id,
417+ array,
418+ DecimalBytesPartsMetadata :: from_array ( view) ?. encode_to_vec ( ) ,
419+ ) ) )
390420 }
391421
392422 fn deserialize (
393423 & self ,
394424 parts : ArrayDeserialization < ' _ > ,
395- session : & VortexSession ,
425+ _session : & VortexSession ,
396426 ) -> VortexResult < ArrayRef > {
397- let lower_part_count =
398- DecimalBytesPartsMetadata :: decode ( parts . metadata ) ? . lower_part_count ( ) ?;
427+ let metadata = DecimalBytesPartsMetadata :: decode ( parts . metadata ) ? ;
428+ let lower_part_count = metadata. lower_part_count ( ) ?;
399429 if parts. serialized_id == decimal_byte_parts_v2_id ( ) {
400430 vortex_ensure ! (
401431 lower_part_count > 0 ,
@@ -414,14 +444,10 @@ impl ArrayPlugin for DecimalBytePartsPlugin {
414444 parts. serialized_id
415445 ) ;
416446 }
417- Ok ( Array :: try_from_parts ( VTable :: deserialize (
418- & DecimalByteParts ,
447+ Ok ( Array :: try_from_parts ( metadata. into_array_parts (
419448 parts. dtype ,
420449 parts. len ,
421- parts. metadata ,
422- parts. buffers ,
423450 parts. children ,
424- session,
425451 ) ?) ?
426452 . into_array ( ) )
427453 }
@@ -897,26 +923,19 @@ mod tests {
897923 fn deserialize_with (
898924 lower_part_count : u32 ,
899925 children : Vec < ArrayRef > ,
900- ) -> VortexResult < ArrayParts < DecimalByteParts > > {
901- let metadata = DecimalBytesPartsMetadata {
902- zeroth_child_ptype : PType :: I64 as i32 ,
903- lower_part_count,
926+ ) -> VortexResult < DecimalBytePartsArray > {
927+ let serialized_id = if lower_part_count == 0 {
928+ VTable :: id ( & DecimalByteParts )
929+ } else {
930+ decimal_byte_parts_v2_id ( )
904931 } ;
905- VTable :: deserialize (
906- & DecimalByteParts ,
907- & DType :: Decimal ( DecimalDType :: new ( 38 , 2 ) , Nullability :: NonNullable ) ,
908- 3 ,
909- & metadata. encode_to_vec ( ) ,
910- & [ ] ,
911- & children,
912- & array_session ( ) ,
913- )
932+ plugin_deserialize_with ( serialized_id, lower_part_count, children)
933+ . map ( |array| array. as_ :: < DecimalByteParts > ( ) . into_owned ( ) )
914934 }
915935
916936 #[ test]
917937 fn test_deserialize_reads_lower_parts ( ) -> VortexResult < ( ) > {
918- let parts = deserialize_with ( 1 , vec ! [ msp( ) , lower_part( ) ] ) ?;
919- let array = Array :: try_from_parts ( parts) ?;
938+ let array = deserialize_with ( 1 , vec ! [ msp( ) , lower_part( ) ] ) ?;
920939 assert_eq ! ( array. lower_parts( ) . len( ) , 1 ) ;
921940
922941 let mut ctx = array_session ( ) . create_execution_ctx ( ) ;
@@ -936,9 +955,7 @@ mod tests {
936955 let session = array_session ( ) ;
937956 crate :: initialize ( & session) ;
938957
939- let array = deserialize_with ( 1 , vec ! [ msp( ) , lower_part( ) ] )
940- . and_then ( Array :: try_from_parts) ?
941- . into_array ( ) ;
958+ let array = deserialize_with ( 1 , vec ! [ msp( ) , lower_part( ) ] ) ?. into_array ( ) ;
942959
943960 let serialization = session
944961 . array_serialize ( & array) ?
@@ -968,9 +985,7 @@ mod tests {
968985 let mut ctx = session. create_execution_ctx ( ) ;
969986
970987 // Stands in for an array materialized from a file: the parts already exist.
971- let array = deserialize_with ( 1 , vec ! [ msp( ) , lower_part( ) ] )
972- . and_then ( Array :: try_from_parts) ?
973- . into_array ( ) ;
988+ let array = deserialize_with ( 1 , vec ! [ msp( ) , lower_part( ) ] ) ?. into_array ( ) ;
974989
975990 let sliced = array. slice ( 0 ..2 ) ?;
976991 assert_eq ! ( sliced. execute:: <DecimalArray >( & mut ctx) ?. len( ) , 2 ) ;
@@ -984,7 +999,7 @@ mod tests {
984999 let mut children = vec ! [ buffer![ 0i64 ; 3 ] . into_array( ) ] ;
9851000 children. extend ( ( 1 ..lower_part_count) . map ( |_| buffer ! [ 0u64 ; 3 ] . into_array ( ) ) ) ;
9861001 children. push ( lower_part ( ) ) ;
987- let array = Array :: try_from_parts ( deserialize_with ( lower_part_count, children) ? ) ?;
1002+ let array = deserialize_with ( lower_part_count, children) ?;
9881003 let expected = DecimalArray :: new (
9891004 buffer ! [ 1i128 , 2 , 3 ] ,
9901005 DecimalDType :: new ( 38 , 2 ) ,
0 commit comments