@@ -99,7 +99,8 @@ pub type Decimal256Builder = PrimitiveBuilder<Decimal256Type>;
9999pub struct PrimitiveBuilder < T : ArrowPrimitiveType > {
100100 values_builder : Vec < T :: Native > ,
101101 null_buffer_builder : NullBufferBuilder ,
102- data_type : DataType ,
102+ /// Optional data type override (e.g. to add timezone or precision/scale)
103+ data_type : Option < DataType > ,
103104}
104105
105106impl < T : ArrowPrimitiveType > ArrayBuilder for PrimitiveBuilder < T > {
@@ -151,7 +152,7 @@ impl<T: ArrowPrimitiveType> PrimitiveBuilder<T> {
151152 Self {
152153 values_builder : Vec :: with_capacity ( capacity) ,
153154 null_buffer_builder : NullBufferBuilder :: new ( capacity) ,
154- data_type : T :: DATA_TYPE ,
155+ data_type : None ,
155156 }
156157 }
157158
@@ -169,7 +170,7 @@ impl<T: ArrowPrimitiveType> PrimitiveBuilder<T> {
169170 Self {
170171 values_builder,
171172 null_buffer_builder,
172- data_type : T :: DATA_TYPE ,
173+ data_type : None ,
173174 }
174175 }
175176
@@ -190,7 +191,10 @@ impl<T: ArrowPrimitiveType> PrimitiveBuilder<T> {
190191 T :: DATA_TYPE ,
191192 data_type
192193 ) ;
193- Self { data_type, ..self }
194+ Self {
195+ data_type : Some ( data_type) ,
196+ ..self
197+ }
194198 }
195199
196200 /// Returns the capacity of this builder measured in slots of type `T`
@@ -267,11 +271,11 @@ impl<T: ArrowPrimitiveType> PrimitiveBuilder<T> {
267271 /// Panics if `array` and `self` data types are different
268272 #[ inline]
269273 pub fn append_array ( & mut self , array : & PrimitiveArray < T > ) {
270- assert_eq ! (
271- & self . data_type,
272- array . data_type ( ) ,
273- "array data type mismatch"
274- ) ;
274+ if let Some ( data_type ) = & self . data_type {
275+ assert_eq ! ( data_type , array . data_type( ) , "array data type mismatch" ) ;
276+ } else {
277+ assert_eq ! ( & T :: DATA_TYPE , array . data_type ( ) , "array data type mismatch" )
278+ }
275279
276280 self . values_builder . extend_from_slice ( array. values ( ) ) ;
277281 if let Some ( null_buffer) = array. nulls ( ) {
@@ -304,22 +308,22 @@ impl<T: ArrowPrimitiveType> PrimitiveBuilder<T> {
304308 pub fn finish ( & mut self ) -> PrimitiveArray < T > {
305309 let values_buffer = Buffer :: from ( std:: mem:: take ( & mut self . values_builder ) ) ;
306310 let nulls = self . null_buffer_builder . finish ( ) ;
307- PrimitiveArray :: < T > :: new_with_datatype (
308- self . data_type . clone ( ) ,
309- ScalarBuffer :: from ( values_buffer ) ,
310- nulls ,
311- )
311+ let mut new_array = PrimitiveArray :: < T > :: new ( ScalarBuffer :: from ( values_buffer ) , nulls ) ;
312+ if let Some ( data_type ) = & self . data_type {
313+ new_array = new_array . with_data_type ( data_type . clone ( ) )
314+ }
315+ new_array
312316 }
313317
314318 /// Builds the [`PrimitiveArray`] without resetting the builder.
315319 pub fn finish_cloned ( & self ) -> PrimitiveArray < T > {
316320 let nulls = self . null_buffer_builder . finish_cloned ( ) ;
317321 let values_buffer = Buffer :: from_slice_ref ( self . values_builder . as_slice ( ) ) ;
318- PrimitiveArray :: < T > :: new_with_datatype (
319- self . data_type . clone ( ) ,
320- ScalarBuffer :: from ( values_buffer ) ,
321- nulls ,
322- )
322+ let mut new_array = PrimitiveArray :: < T > :: new ( ScalarBuffer :: from ( values_buffer ) , nulls ) ;
323+ if let Some ( data_type ) = & self . data_type {
324+ new_array = new_array . with_data_type ( data_type . clone ( ) )
325+ }
326+ new_array
323327 }
324328
325329 /// Builds the [`PrimitiveArray`] , consuming this builder.
@@ -344,11 +348,14 @@ impl<T: ArrowPrimitiveType> PrimitiveBuilder<T> {
344348 null_buffer_builder,
345349 data_type,
346350 } = self ;
347- PrimitiveArray :: new_with_datatype (
348- data_type, // reuse data_type to save a DataType::drop()
349- ScalarBuffer :: from ( values_builder) ,
350- null_buffer_builder. build ( ) ,
351- )
351+
352+ let nulls = null_buffer_builder. build ( ) ;
353+ let values_buffer = ScalarBuffer :: from ( Buffer :: from ( values_builder) ) ;
354+ let mut new_array = PrimitiveArray :: < T > :: new ( values_buffer, nulls) ;
355+ if let Some ( data_type) = data_type {
356+ new_array = new_array. with_data_type ( data_type)
357+ }
358+ new_array
352359 }
353360
354361 /// Returns the current values buffer as a slice
@@ -385,7 +392,7 @@ impl<P: DecimalType> PrimitiveBuilder<P> {
385392 pub fn with_precision_and_scale ( self , precision : u8 , scale : i8 ) -> Result < Self , ArrowError > {
386393 validate_decimal_precision_and_scale :: < P > ( precision, scale) ?;
387394 Ok ( Self {
388- data_type : P :: TYPE_CONSTRUCTOR ( precision, scale) ,
395+ data_type : Some ( P :: TYPE_CONSTRUCTOR ( precision, scale) ) ,
389396 ..self
390397 } )
391398 }
@@ -400,7 +407,7 @@ impl<P: ArrowTimestampType> PrimitiveBuilder<P> {
400407 /// Sets an optional timezone
401408 pub fn with_timezone_opt < S : Into < Arc < str > > > ( self , timezone : Option < S > ) -> Self {
402409 Self {
403- data_type : DataType :: Timestamp ( P :: UNIT , timezone. map ( Into :: into) ) ,
410+ data_type : Some ( DataType :: Timestamp ( P :: UNIT , timezone. map ( Into :: into) ) ) ,
404411 ..self
405412 }
406413 }
0 commit comments