1use crate::builder::ArrayBuilder;
19use crate::types::*;
20use crate::{Array, ArrayRef, PrimitiveArray};
21use arrow_buffer::{Buffer, MutableBuffer, NullBufferBuilder, ScalarBuffer};
22use arrow_data::ArrayData;
23use arrow_schema::{ArrowError, DataType};
24use std::any::Any;
25use std::sync::Arc;
26
27pub type Int8Builder = PrimitiveBuilder<Int8Type>;
29pub type Int16Builder = PrimitiveBuilder<Int16Type>;
31pub type Int32Builder = PrimitiveBuilder<Int32Type>;
33pub type Int64Builder = PrimitiveBuilder<Int64Type>;
35pub type UInt8Builder = PrimitiveBuilder<UInt8Type>;
37pub type UInt16Builder = PrimitiveBuilder<UInt16Type>;
39pub type UInt32Builder = PrimitiveBuilder<UInt32Type>;
41pub type UInt64Builder = PrimitiveBuilder<UInt64Type>;
43pub type Float16Builder = PrimitiveBuilder<Float16Type>;
45pub type Float32Builder = PrimitiveBuilder<Float32Type>;
47pub type Float64Builder = PrimitiveBuilder<Float64Type>;
49
50pub type TimestampSecondBuilder = PrimitiveBuilder<TimestampSecondType>;
52pub type TimestampMillisecondBuilder = PrimitiveBuilder<TimestampMillisecondType>;
54pub type TimestampMicrosecondBuilder = PrimitiveBuilder<TimestampMicrosecondType>;
56pub type TimestampNanosecondBuilder = PrimitiveBuilder<TimestampNanosecondType>;
58
59pub type Date32Builder = PrimitiveBuilder<Date32Type>;
61pub type Date64Builder = PrimitiveBuilder<Date64Type>;
63
64pub type Time32SecondBuilder = PrimitiveBuilder<Time32SecondType>;
66pub type Time32MillisecondBuilder = PrimitiveBuilder<Time32MillisecondType>;
68pub type Time64MicrosecondBuilder = PrimitiveBuilder<Time64MicrosecondType>;
70pub type Time64NanosecondBuilder = PrimitiveBuilder<Time64NanosecondType>;
72
73pub type IntervalYearMonthBuilder = PrimitiveBuilder<IntervalYearMonthType>;
75pub type IntervalDayTimeBuilder = PrimitiveBuilder<IntervalDayTimeType>;
77pub type IntervalMonthDayNanoBuilder = PrimitiveBuilder<IntervalMonthDayNanoType>;
79
80pub type DurationSecondBuilder = PrimitiveBuilder<DurationSecondType>;
82pub type DurationMillisecondBuilder = PrimitiveBuilder<DurationMillisecondType>;
84pub type DurationMicrosecondBuilder = PrimitiveBuilder<DurationMicrosecondType>;
86pub type DurationNanosecondBuilder = PrimitiveBuilder<DurationNanosecondType>;
88
89pub type Decimal32Builder = PrimitiveBuilder<Decimal32Type>;
91pub type Decimal64Builder = PrimitiveBuilder<Decimal64Type>;
93pub type Decimal128Builder = PrimitiveBuilder<Decimal128Type>;
95pub type Decimal256Builder = PrimitiveBuilder<Decimal256Type>;
97
98#[derive(Debug)]
100pub struct PrimitiveBuilder<T: ArrowPrimitiveType> {
101 values_builder: Vec<T::Native>,
102 null_buffer_builder: NullBufferBuilder,
103 data_type: DataType,
104}
105
106impl<T: ArrowPrimitiveType> ArrayBuilder for PrimitiveBuilder<T> {
107 fn as_any(&self) -> &dyn Any {
109 self
110 }
111
112 fn as_any_mut(&mut self) -> &mut dyn Any {
114 self
115 }
116
117 fn into_box_any(self: Box<Self>) -> Box<dyn Any> {
119 self
120 }
121
122 fn len(&self) -> usize {
124 self.values_builder.len()
125 }
126
127 fn finish(&mut self) -> ArrayRef {
129 Arc::new(self.finish())
130 }
131
132 fn finish_cloned(&self) -> ArrayRef {
134 Arc::new(self.finish_cloned())
135 }
136}
137
138impl<T: ArrowPrimitiveType> Default for PrimitiveBuilder<T> {
139 fn default() -> Self {
140 Self::new()
141 }
142}
143
144impl<T: ArrowPrimitiveType> PrimitiveBuilder<T> {
145 pub fn new() -> Self {
147 Self::with_capacity(1024)
148 }
149
150 pub fn with_capacity(capacity: usize) -> Self {
152 Self {
153 values_builder: Vec::with_capacity(capacity),
154 null_buffer_builder: NullBufferBuilder::new(capacity),
155 data_type: T::DATA_TYPE,
156 }
157 }
158
159 pub fn new_from_buffer(
161 values_buffer: MutableBuffer,
162 null_buffer: Option<MutableBuffer>,
163 ) -> Self {
164 let values_builder: Vec<T::Native> = ScalarBuffer::<T::Native>::from(values_buffer).into();
165
166 let null_buffer_builder = null_buffer
167 .map(|buffer| NullBufferBuilder::new_from_buffer(buffer, values_builder.len()))
168 .unwrap_or_else(|| NullBufferBuilder::new_with_len(values_builder.len()));
169
170 Self {
171 values_builder,
172 null_buffer_builder,
173 data_type: T::DATA_TYPE,
174 }
175 }
176
177 pub fn with_data_type(self, data_type: DataType) -> Self {
188 assert!(
189 PrimitiveArray::<T>::is_compatible(&data_type),
190 "incompatible data type for builder, expected {} got {}",
191 T::DATA_TYPE,
192 data_type
193 );
194 Self { data_type, ..self }
195 }
196
197 pub fn capacity(&self) -> usize {
199 self.values_builder.capacity()
200 }
201
202 #[inline]
204 pub fn append_value(&mut self, v: T::Native) {
205 self.null_buffer_builder.append_non_null();
206 self.values_builder.push(v);
207 }
208
209 #[inline]
211 pub fn append_value_n(&mut self, v: T::Native, n: usize) {
212 self.null_buffer_builder.append_n_non_nulls(n);
213 self.values_builder.extend(std::iter::repeat_n(v, n));
214 }
215
216 #[inline]
218 pub fn append_null(&mut self) {
219 self.null_buffer_builder.append_null();
220 self.values_builder.push(T::Native::default());
221 }
222
223 #[inline]
225 pub fn append_nulls(&mut self, n: usize) {
226 self.null_buffer_builder.append_n_nulls(n);
227 self.values_builder
228 .extend(std::iter::repeat_n(T::Native::default(), n));
229 }
230
231 #[inline]
233 pub fn append_option(&mut self, v: Option<T::Native>) {
234 match v {
235 None => self.append_null(),
236 Some(v) => self.append_value(v),
237 };
238 }
239
240 #[inline]
242 pub fn append_slice(&mut self, v: &[T::Native]) {
243 self.null_buffer_builder.append_n_non_nulls(v.len());
244 self.values_builder.extend_from_slice(v);
245 }
246
247 #[inline]
253 pub fn append_values(&mut self, values: &[T::Native], is_valid: &[bool]) {
254 assert_eq!(
255 values.len(),
256 is_valid.len(),
257 "Value and validity lengths must be equal"
258 );
259 self.null_buffer_builder.append_slice(is_valid);
260 self.values_builder.extend_from_slice(values);
261 }
262
263 #[inline]
269 pub fn extend_from_iter_option<I: IntoIterator<Item = Option<T::Native>>>(&mut self, iter: I) {
270 let iter = iter.into_iter();
271 self.values_builder.extend(iter.map(|v| match v {
272 Some(v) => {
273 self.null_buffer_builder.append_non_null();
274 v
275 }
276 None => {
277 self.null_buffer_builder.append_null();
278 T::Native::default()
279 }
280 }));
281 }
282
283 #[inline]
290 pub fn append_array(&mut self, array: &PrimitiveArray<T>) {
291 assert_eq!(
292 &self.data_type,
293 array.data_type(),
294 "array data type mismatch"
295 );
296
297 self.values_builder.extend_from_slice(array.values());
298 if let Some(null_buffer) = array.nulls() {
299 self.null_buffer_builder.append_buffer(null_buffer);
300 } else {
301 self.null_buffer_builder.append_n_non_nulls(array.len());
302 }
303 }
304
305 #[inline]
311 pub unsafe fn append_trusted_len_iter(&mut self, iter: impl IntoIterator<Item = T::Native>) {
312 let iter = iter.into_iter();
313 let len = iter
314 .size_hint()
315 .1
316 .expect("append_trusted_len_iter requires an upper bound");
317
318 self.null_buffer_builder.append_n_non_nulls(len);
319 self.values_builder.extend(iter);
320 }
321
322 pub fn finish(&mut self) -> PrimitiveArray<T> {
324 let len = self.len();
325 let nulls = self.null_buffer_builder.finish();
326 let builder = ArrayData::builder(self.data_type.clone())
327 .len(len)
328 .add_buffer(std::mem::take(&mut self.values_builder).into())
329 .nulls(nulls);
330
331 let array_data = unsafe { builder.build_unchecked() };
332 PrimitiveArray::<T>::from(array_data)
333 }
334
335 pub fn finish_cloned(&self) -> PrimitiveArray<T> {
337 let len = self.len();
338 let nulls = self.null_buffer_builder.finish_cloned();
339 let values_buffer = Buffer::from_slice_ref(self.values_builder.as_slice());
340 let builder = ArrayData::builder(self.data_type.clone())
341 .len(len)
342 .add_buffer(values_buffer)
343 .nulls(nulls);
344
345 let array_data = unsafe { builder.build_unchecked() };
346 PrimitiveArray::<T>::from(array_data)
347 }
348
349 pub fn values_slice(&self) -> &[T::Native] {
351 self.values_builder.as_slice()
352 }
353
354 pub fn values_slice_mut(&mut self) -> &mut [T::Native] {
356 self.values_builder.as_mut_slice()
357 }
358
359 pub fn validity_slice(&self) -> Option<&[u8]> {
361 self.null_buffer_builder.as_slice()
362 }
363
364 pub fn validity_capacity(&self) -> usize {
366 self.null_buffer_builder.allocated_size()
367 }
368
369 pub fn validity_slice_mut(&mut self) -> Option<&mut [u8]> {
371 self.null_buffer_builder.as_slice_mut()
372 }
373
374 pub fn slices_mut(&mut self) -> (&mut [T::Native], Option<&mut [u8]>) {
376 (
377 self.values_builder.as_mut_slice(),
378 self.null_buffer_builder.as_slice_mut(),
379 )
380 }
381}
382
383impl<P: DecimalType> PrimitiveBuilder<P> {
384 pub fn with_precision_and_scale(self, precision: u8, scale: i8) -> Result<Self, ArrowError> {
386 validate_decimal_precision_and_scale::<P>(precision, scale)?;
387 Ok(Self {
388 data_type: P::TYPE_CONSTRUCTOR(precision, scale),
389 ..self
390 })
391 }
392}
393
394impl<P: ArrowTimestampType> PrimitiveBuilder<P> {
395 pub fn with_timezone(self, timezone: impl Into<Arc<str>>) -> Self {
397 self.with_timezone_opt(Some(timezone.into()))
398 }
399
400 pub fn with_timezone_opt<S: Into<Arc<str>>>(self, timezone: Option<S>) -> Self {
402 Self {
403 data_type: DataType::Timestamp(P::UNIT, timezone.map(Into::into)),
404 ..self
405 }
406 }
407}
408
409impl<P: ArrowPrimitiveType> Extend<Option<P::Native>> for PrimitiveBuilder<P> {
410 #[inline]
411 fn extend<T: IntoIterator<Item = Option<P::Native>>>(&mut self, iter: T) {
412 for v in iter {
413 self.append_option(v)
414 }
415 }
416}
417
418#[cfg(test)]
419mod tests {
420 use super::*;
421 use arrow_buffer::{NullBuffer, ScalarBuffer};
422 use arrow_schema::TimeUnit;
423
424 use crate::array::Array;
425 use crate::array::BooleanArray;
426 use crate::array::Date32Array;
427 use crate::array::Int32Array;
428 use crate::array::TimestampSecondArray;
429
430 #[test]
431 fn test_primitive_array_builder_i32() {
432 let mut builder = Int32Array::builder(5);
433 for i in 0..5 {
434 builder.append_value(i);
435 }
436 let arr = builder.finish();
437 assert_eq!(5, arr.len());
438 assert_eq!(0, arr.offset());
439 assert_eq!(0, arr.null_count());
440 for i in 0..5 {
441 assert!(!arr.is_null(i));
442 assert!(arr.is_valid(i));
443 assert_eq!(i as i32, arr.value(i));
444 }
445 }
446
447 #[test]
448 fn test_primitive_array_builder_i32_append_iter() {
449 let mut builder = Int32Array::builder(5);
450 unsafe { builder.append_trusted_len_iter(0..5) };
451 let arr = builder.finish();
452 assert_eq!(5, arr.len());
453 assert_eq!(0, arr.offset());
454 assert_eq!(0, arr.null_count());
455 for i in 0..5 {
456 assert!(!arr.is_null(i));
457 assert!(arr.is_valid(i));
458 assert_eq!(i as i32, arr.value(i));
459 }
460 }
461
462 #[test]
463 fn test_primitive_array_builder_i32_append_nulls() {
464 let mut builder = Int32Array::builder(5);
465 builder.append_nulls(5);
466 let arr = builder.finish();
467 assert_eq!(5, arr.len());
468 assert_eq!(0, arr.offset());
469 assert_eq!(5, arr.null_count());
470 for i in 0..5 {
471 assert!(arr.is_null(i));
472 assert!(!arr.is_valid(i));
473 }
474 }
475
476 #[test]
477 fn test_primitive_array_builder_date32() {
478 let mut builder = Date32Array::builder(5);
479 for i in 0..5 {
480 builder.append_value(i);
481 }
482 let arr = builder.finish();
483 assert_eq!(5, arr.len());
484 assert_eq!(0, arr.offset());
485 assert_eq!(0, arr.null_count());
486 for i in 0..5 {
487 assert!(!arr.is_null(i));
488 assert!(arr.is_valid(i));
489 assert_eq!(i as i32, arr.value(i));
490 }
491 }
492
493 #[test]
494 fn test_primitive_array_builder_timestamp_second() {
495 let mut builder = TimestampSecondArray::builder(5);
496 for i in 0..5 {
497 builder.append_value(i);
498 }
499 let arr = builder.finish();
500 assert_eq!(5, arr.len());
501 assert_eq!(0, arr.offset());
502 assert_eq!(0, arr.null_count());
503 for i in 0..5 {
504 assert!(!arr.is_null(i));
505 assert!(arr.is_valid(i));
506 assert_eq!(i as i64, arr.value(i));
507 }
508 }
509
510 #[test]
511 fn test_primitive_array_builder_bool() {
512 let buf = Buffer::from([72_u8, 2_u8]);
514 let mut builder = BooleanArray::builder(10);
515 for i in 0..10 {
516 if i == 3 || i == 6 || i == 9 {
517 builder.append_value(true);
518 } else {
519 builder.append_value(false);
520 }
521 }
522
523 let arr = builder.finish();
524 assert_eq!(&buf, arr.values().inner());
525 assert_eq!(10, arr.len());
526 assert_eq!(0, arr.offset());
527 assert_eq!(0, arr.null_count());
528 for i in 0..10 {
529 assert!(!arr.is_null(i));
530 assert!(arr.is_valid(i));
531 assert_eq!(i == 3 || i == 6 || i == 9, arr.value(i), "failed at {i}")
532 }
533 }
534
535 #[test]
536 fn test_primitive_array_builder_append_option() {
537 let arr1 = Int32Array::from(vec![Some(0), None, Some(2), None, Some(4)]);
538
539 let mut builder = Int32Array::builder(5);
540 builder.append_option(Some(0));
541 builder.append_option(None);
542 builder.append_option(Some(2));
543 builder.append_option(None);
544 builder.append_option(Some(4));
545 let arr2 = builder.finish();
546
547 assert_eq!(arr1.len(), arr2.len());
548 assert_eq!(arr1.offset(), arr2.offset());
549 assert_eq!(arr1.null_count(), arr2.null_count());
550 for i in 0..5 {
551 assert_eq!(arr1.is_null(i), arr2.is_null(i));
552 assert_eq!(arr1.is_valid(i), arr2.is_valid(i));
553 if arr1.is_valid(i) {
554 assert_eq!(arr1.value(i), arr2.value(i));
555 }
556 }
557 }
558
559 #[test]
560 fn test_primitive_array_builder_append_null() {
561 let arr1 = Int32Array::from(vec![Some(0), Some(2), None, None, Some(4)]);
562
563 let mut builder = Int32Array::builder(5);
564 builder.append_value(0);
565 builder.append_value(2);
566 builder.append_null();
567 builder.append_null();
568 builder.append_value(4);
569 let arr2 = builder.finish();
570
571 assert_eq!(arr1.len(), arr2.len());
572 assert_eq!(arr1.offset(), arr2.offset());
573 assert_eq!(arr1.null_count(), arr2.null_count());
574 for i in 0..5 {
575 assert_eq!(arr1.is_null(i), arr2.is_null(i));
576 assert_eq!(arr1.is_valid(i), arr2.is_valid(i));
577 if arr1.is_valid(i) {
578 assert_eq!(arr1.value(i), arr2.value(i));
579 }
580 }
581 }
582
583 #[test]
584 fn test_primitive_array_builder_append_slice() {
585 let arr1 = Int32Array::from(vec![Some(0), Some(2), None, None, Some(4)]);
586
587 let mut builder = Int32Array::builder(5);
588 builder.append_slice(&[0, 2]);
589 builder.append_null();
590 builder.append_null();
591 builder.append_value(4);
592 let arr2 = builder.finish();
593
594 assert_eq!(arr1.len(), arr2.len());
595 assert_eq!(arr1.offset(), arr2.offset());
596 assert_eq!(arr1.null_count(), arr2.null_count());
597 for i in 0..5 {
598 assert_eq!(arr1.is_null(i), arr2.is_null(i));
599 assert_eq!(arr1.is_valid(i), arr2.is_valid(i));
600 if arr1.is_valid(i) {
601 assert_eq!(arr1.value(i), arr2.value(i));
602 }
603 }
604 }
605
606 #[test]
607 fn test_primitive_array_builder_finish() {
608 let mut builder = Int32Builder::new();
609 builder.append_slice(&[2, 4, 6, 8]);
610 let mut arr = builder.finish();
611 assert_eq!(4, arr.len());
612 assert_eq!(0, builder.len());
613
614 builder.append_slice(&[1, 3, 5, 7, 9]);
615 arr = builder.finish();
616 assert_eq!(5, arr.len());
617 assert_eq!(0, builder.len());
618 }
619
620 #[test]
621 fn test_primitive_array_builder_finish_cloned() {
622 let mut builder = Int32Builder::new();
623 builder.append_value(23);
624 builder.append_value(45);
625 let result = builder.finish_cloned();
626 assert_eq!(result, Int32Array::from(vec![23, 45]));
627 builder.append_value(56);
628 assert_eq!(builder.finish_cloned(), Int32Array::from(vec![23, 45, 56]));
629
630 builder.append_slice(&[2, 4, 6, 8]);
631 let mut arr = builder.finish();
632 assert_eq!(7, arr.len());
633 assert_eq!(arr, Int32Array::from(vec![23, 45, 56, 2, 4, 6, 8]));
634 assert_eq!(0, builder.len());
635
636 builder.append_slice(&[1, 3, 5, 7, 9]);
637 arr = builder.finish();
638 assert_eq!(5, arr.len());
639 assert_eq!(0, builder.len());
640 }
641
642 #[test]
643 fn test_primitive_array_builder_with_data_type() {
644 let mut builder = Decimal128Builder::new().with_data_type(DataType::Decimal128(1, 2));
645 builder.append_value(1);
646 let array = builder.finish();
647 assert_eq!(array.precision(), 1);
648 assert_eq!(array.scale(), 2);
649
650 let data_type = DataType::Timestamp(TimeUnit::Nanosecond, Some("+00:00".into()));
651 let mut builder = TimestampNanosecondBuilder::new().with_data_type(data_type.clone());
652 builder.append_value(1);
653 let array = builder.finish();
654 assert_eq!(array.data_type(), &data_type);
655 }
656
657 #[test]
658 #[should_panic(expected = "incompatible data type for builder, expected Int32 got Int64")]
659 fn test_invalid_with_data_type() {
660 Int32Builder::new().with_data_type(DataType::Int64);
661 }
662
663 #[test]
664 fn test_extend() {
665 let mut builder = PrimitiveBuilder::<Int16Type>::new();
666 builder.extend([1, 2, 3, 5, 2, 4, 4].into_iter().map(Some));
667 builder.extend([2, 4, 6, 2].into_iter().map(Some));
668 let array = builder.finish();
669 assert_eq!(array.values(), &[1, 2, 3, 5, 2, 4, 4, 2, 4, 6, 2]);
670 }
671
672 #[test]
673 fn test_primitive_array_append_array() {
674 let input = vec![
675 Some(1),
676 None,
677 Some(3),
678 None,
679 Some(5),
680 None,
681 None,
682 None,
683 Some(7),
684 Some(9),
685 Some(8),
686 Some(6),
687 Some(4),
688 ];
689 let arr1 = Int32Array::from(input[..5].to_vec());
690 let arr2 = Int32Array::from(input[5..8].to_vec());
691 let arr3 = Int32Array::from(input[8..].to_vec());
692
693 let mut builder = Int32Array::builder(5);
694 builder.append_array(&arr1);
695 builder.append_array(&arr2);
696 builder.append_array(&arr3);
697 let actual = builder.finish();
698 let expected = Int32Array::from(input);
699
700 assert_eq!(actual, expected);
701 }
702
703 #[test]
704 fn test_append_array_add_underlying_null_values() {
705 let array = Int32Array::new(
706 ScalarBuffer::from(vec![2, 3, 4, 5]),
707 Some(NullBuffer::from(&[true, true, false, false])),
708 );
709
710 let mut builder = Int32Array::builder(5);
711 builder.append_array(&array);
712 let actual = builder.finish();
713
714 assert_eq!(actual, array);
715 assert_eq!(actual.values(), array.values())
716 }
717
718 #[test]
719 #[should_panic(expected = "array data type mismatch")]
720 fn test_invalid_with_data_type_in_append_array() {
721 let array = {
722 let mut builder = Decimal128Builder::new().with_data_type(DataType::Decimal128(1, 2));
723 builder.append_value(1);
724 builder.finish()
725 };
726
727 let mut builder = Decimal128Builder::new().with_data_type(DataType::Decimal128(2, 3));
728 builder.append_array(&array)
729 }
730}