Coverage Report

Created: 2025-08-26 07:03

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/Users/andrewlamb/Software/arrow-rs/arrow-array/src/builder/primitive_builder.rs
Line
Count
Source
1
// Licensed to the Apache Software Foundation (ASF) under one
2
// or more contributor license agreements.  See the NOTICE file
3
// distributed with this work for additional information
4
// regarding copyright ownership.  The ASF licenses this file
5
// to you under the Apache License, Version 2.0 (the
6
// "License"); you may not use this file except in compliance
7
// with the License.  You may obtain a copy of the License at
8
//
9
//   http://www.apache.org/licenses/LICENSE-2.0
10
//
11
// Unless required by applicable law or agreed to in writing,
12
// software distributed under the License is distributed on an
13
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
// KIND, either express or implied.  See the License for the
15
// specific language governing permissions and limitations
16
// under the License.
17
18
use crate::builder::ArrayBuilder;
19
use crate::types::*;
20
use crate::{Array, ArrayRef, PrimitiveArray};
21
use arrow_buffer::{Buffer, MutableBuffer, NullBufferBuilder, ScalarBuffer};
22
use arrow_data::ArrayData;
23
use arrow_schema::{ArrowError, DataType};
24
use std::any::Any;
25
use std::sync::Arc;
26
27
/// A signed 8-bit integer array builder.
28
pub type Int8Builder = PrimitiveBuilder<Int8Type>;
29
/// A signed 16-bit integer array builder.
30
pub type Int16Builder = PrimitiveBuilder<Int16Type>;
31
/// A signed 32-bit integer array builder.
32
pub type Int32Builder = PrimitiveBuilder<Int32Type>;
33
/// A signed 64-bit integer array builder.
34
pub type Int64Builder = PrimitiveBuilder<Int64Type>;
35
/// An usigned 8-bit integer array builder.
36
pub type UInt8Builder = PrimitiveBuilder<UInt8Type>;
37
/// An usigned 16-bit integer array builder.
38
pub type UInt16Builder = PrimitiveBuilder<UInt16Type>;
39
/// An usigned 32-bit integer array builder.
40
pub type UInt32Builder = PrimitiveBuilder<UInt32Type>;
41
/// An usigned 64-bit integer array builder.
42
pub type UInt64Builder = PrimitiveBuilder<UInt64Type>;
43
/// A 16-bit floating point array builder.
44
pub type Float16Builder = PrimitiveBuilder<Float16Type>;
45
/// A 32-bit floating point array builder.
46
pub type Float32Builder = PrimitiveBuilder<Float32Type>;
47
/// A 64-bit floating point array builder.
48
pub type Float64Builder = PrimitiveBuilder<Float64Type>;
49
50
/// A timestamp second array builder.
51
pub type TimestampSecondBuilder = PrimitiveBuilder<TimestampSecondType>;
52
/// A timestamp millisecond array builder.
53
pub type TimestampMillisecondBuilder = PrimitiveBuilder<TimestampMillisecondType>;
54
/// A timestamp microsecond array builder.
55
pub type TimestampMicrosecondBuilder = PrimitiveBuilder<TimestampMicrosecondType>;
56
/// A timestamp nanosecond array builder.
57
pub type TimestampNanosecondBuilder = PrimitiveBuilder<TimestampNanosecondType>;
58
59
/// A 32-bit date array builder.
60
pub type Date32Builder = PrimitiveBuilder<Date32Type>;
61
/// A 64-bit date array builder.
62
pub type Date64Builder = PrimitiveBuilder<Date64Type>;
63
64
/// A 32-bit elaspsed time in seconds array builder.
65
pub type Time32SecondBuilder = PrimitiveBuilder<Time32SecondType>;
66
/// A 32-bit elaspsed time in milliseconds array builder.
67
pub type Time32MillisecondBuilder = PrimitiveBuilder<Time32MillisecondType>;
68
/// A 64-bit elaspsed time in microseconds array builder.
69
pub type Time64MicrosecondBuilder = PrimitiveBuilder<Time64MicrosecondType>;
70
/// A 64-bit elaspsed time in nanoseconds array builder.
71
pub type Time64NanosecondBuilder = PrimitiveBuilder<Time64NanosecondType>;
72
73
/// A “calendar” interval in months array builder.
74
pub type IntervalYearMonthBuilder = PrimitiveBuilder<IntervalYearMonthType>;
75
/// A “calendar” interval in days and milliseconds array builder.
76
pub type IntervalDayTimeBuilder = PrimitiveBuilder<IntervalDayTimeType>;
77
/// A “calendar” interval in months, days, and nanoseconds array builder.
78
pub type IntervalMonthDayNanoBuilder = PrimitiveBuilder<IntervalMonthDayNanoType>;
79
80
/// An elapsed time in seconds array builder.
81
pub type DurationSecondBuilder = PrimitiveBuilder<DurationSecondType>;
82
/// An elapsed time in milliseconds array builder.
83
pub type DurationMillisecondBuilder = PrimitiveBuilder<DurationMillisecondType>;
84
/// An elapsed time in microseconds array builder.
85
pub type DurationMicrosecondBuilder = PrimitiveBuilder<DurationMicrosecondType>;
86
/// An elapsed time in nanoseconds array builder.
87
pub type DurationNanosecondBuilder = PrimitiveBuilder<DurationNanosecondType>;
88
89
/// A decimal 32 array builder
90
pub type Decimal32Builder = PrimitiveBuilder<Decimal32Type>;
91
/// A decimal 64 array builder
92
pub type Decimal64Builder = PrimitiveBuilder<Decimal64Type>;
93
/// A decimal 128 array builder
94
pub type Decimal128Builder = PrimitiveBuilder<Decimal128Type>;
95
/// A decimal 256 array builder
96
pub type Decimal256Builder = PrimitiveBuilder<Decimal256Type>;
97
98
/// Builder for [`PrimitiveArray`]
99
#[derive(Debug)]
100
pub struct PrimitiveBuilder<T: ArrowPrimitiveType> {
101
    values_builder: Vec<T::Native>,
102
    null_buffer_builder: NullBufferBuilder,
103
    data_type: DataType,
104
}
105
106
impl<T: ArrowPrimitiveType> ArrayBuilder for PrimitiveBuilder<T> {
107
    /// Returns the builder as a non-mutable `Any` reference.
108
0
    fn as_any(&self) -> &dyn Any {
109
0
        self
110
0
    }
111
112
    /// Returns the builder as a mutable `Any` reference.
113
9
    fn as_any_mut(&mut self) -> &mut dyn Any {
114
9
        self
115
9
    }
116
117
    /// Returns the boxed builder as a box of `Any`.
118
0
    fn into_box_any(self: Box<Self>) -> Box<dyn Any> {
119
0
        self
120
0
    }
121
122
    /// Returns the number of array slots in the builder
123
140
    fn len(&self) -> usize {
124
140
        self.values_builder.len()
125
140
    }
126
127
    /// Builds the array and reset this builder.
128
11
    fn finish(&mut self) -> ArrayRef {
129
11
        Arc::new(self.finish())
130
11
    }
131
132
    /// Builds the array without resetting the builder.
133
0
    fn finish_cloned(&self) -> ArrayRef {
134
0
        Arc::new(self.finish_cloned())
135
0
    }
136
}
137
138
impl<T: ArrowPrimitiveType> Default for PrimitiveBuilder<T> {
139
    fn default() -> Self {
140
        Self::new()
141
    }
142
}
143
144
impl<T: ArrowPrimitiveType> PrimitiveBuilder<T> {
145
    /// Creates a new primitive array builder
146
26
    pub fn new() -> Self {
147
26
        Self::with_capacity(1024)
148
26
    }
149
150
    /// Creates a new primitive array builder with capacity no of items
151
83
    pub fn with_capacity(capacity: usize) -> Self {
152
83
        Self {
153
83
            values_builder: Vec::with_capacity(capacity),
154
83
            null_buffer_builder: NullBufferBuilder::new(capacity),
155
83
            data_type: T::DATA_TYPE,
156
83
        }
157
83
    }
158
159
    /// Creates a new primitive array builder from buffers
160
    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
    /// By default [`PrimitiveBuilder`] uses [`ArrowPrimitiveType::DATA_TYPE`] as the
178
    /// data type of the generated array.
179
    ///
180
    /// This method allows overriding the data type, to allow specifying timezones
181
    /// for [`DataType::Timestamp`] or precision and scale for [`DataType::Decimal32`],
182
    /// [`DataType::Decimal64`], [`DataType::Decimal128`] and [`DataType::Decimal256`]
183
    ///
184
    /// # Panics
185
    ///
186
    /// This method panics if `data_type` is not [PrimitiveArray::is_compatible]
187
57
    pub fn with_data_type(self, data_type: DataType) -> Self {
188
57
        assert!(
189
57
            PrimitiveArray::<T>::is_compatible(&data_type),
190
0
            "incompatible data type for builder, expected {} got {}",
191
0
            T::DATA_TYPE,
192
            data_type
193
        );
194
57
        Self { data_type, ..self }
195
57
    }
196
197
    /// Returns the capacity of this builder measured in slots of type `T`
198
    pub fn capacity(&self) -> usize {
199
        self.values_builder.capacity()
200
    }
201
202
    /// Appends a value of type `T` into the builder
203
    #[inline]
204
226
    pub fn append_value(&mut self, v: T::Native) {
205
226
        self.null_buffer_builder.append_non_null();
206
226
        self.values_builder.push(v);
207
226
    }
208
209
    /// Appends a value of type `T` into the builder `n` times
210
    #[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
    /// Appends a null slot into the builder
217
    #[inline]
218
4
    pub fn append_null(&mut self) {
219
4
        self.null_buffer_builder.append_null();
220
4
        self.values_builder.push(T::Native::default());
221
4
    }
222
223
    /// Appends `n` no. of null's into the builder
224
    #[inline]
225
0
    pub fn append_nulls(&mut self, n: usize) {
226
0
        self.null_buffer_builder.append_n_nulls(n);
227
0
        self.values_builder
228
0
            .extend(std::iter::repeat_n(T::Native::default(), n));
229
0
    }
230
231
    /// Appends an `Option<T>` into the builder
232
    #[inline]
233
0
    pub fn append_option(&mut self, v: Option<T::Native>) {
234
0
        match v {
235
0
            None => self.append_null(),
236
0
            Some(v) => self.append_value(v),
237
        };
238
0
    }
239
240
    /// Appends a slice of type `T` into the builder
241
    #[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
    /// Appends values from a slice of type `T` and a validity boolean slice
248
    ///
249
    /// # Panics
250
    ///
251
    /// Panics if `values` and `is_valid` have different lengths
252
    #[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
    /// Appends array values and null to this builder as is
264
    /// (this means that underlying null values are copied as is).
265
    ///
266
    /// # Panics
267
    ///
268
    /// Panics if `array` and `self` data types are different
269
    #[inline]
270
188
    pub fn append_array(&mut self, array: &PrimitiveArray<T>) {
271
188
        assert_eq!(
272
188
            &self.data_type,
273
188
            array.data_type(),
274
0
            "array data type mismatch"
275
        );
276
277
188
        self.values_builder.extend_from_slice(array.values());
278
188
        if let Some(
null_buffer8
) = array.nulls() {
279
8
            self.null_buffer_builder.append_buffer(null_buffer);
280
180
        } else {
281
180
            self.null_buffer_builder.append_n_non_nulls(array.len());
282
180
        }
283
188
    }
284
285
    /// Appends values from a trusted length iterator.
286
    ///
287
    /// # Safety
288
    /// This requires the iterator be a trusted length. This could instead require
289
    /// the iterator implement `TrustedLen` once that is stabilized.
290
    #[inline]
291
0
    pub unsafe fn append_trusted_len_iter(&mut self, iter: impl IntoIterator<Item = T::Native>) {
292
0
        let iter = iter.into_iter();
293
0
        let len = iter
294
0
            .size_hint()
295
0
            .1
296
0
            .expect("append_trusted_len_iter requires an upper bound");
297
298
0
        self.null_buffer_builder.append_n_non_nulls(len);
299
0
        self.values_builder.extend(iter);
300
0
    }
301
302
    /// Builds the [`PrimitiveArray`] and reset this builder.
303
119
    pub fn finish(&mut self) -> PrimitiveArray<T> {
304
119
        let len = self.len();
305
119
        let nulls = self.null_buffer_builder.finish();
306
119
        let builder = ArrayData::builder(self.data_type.clone())
307
119
            .len(len)
308
119
            .add_buffer(std::mem::take(&mut self.values_builder).into())
309
119
            .nulls(nulls);
310
311
119
        let array_data = unsafe { builder.build_unchecked() };
312
119
        PrimitiveArray::<T>::from(array_data)
313
119
    }
314
315
    /// Builds the [`PrimitiveArray`] without resetting the builder.
316
0
    pub fn finish_cloned(&self) -> PrimitiveArray<T> {
317
0
        let len = self.len();
318
0
        let nulls = self.null_buffer_builder.finish_cloned();
319
0
        let values_buffer = Buffer::from_slice_ref(self.values_builder.as_slice());
320
0
        let builder = ArrayData::builder(self.data_type.clone())
321
0
            .len(len)
322
0
            .add_buffer(values_buffer)
323
0
            .nulls(nulls);
324
325
0
        let array_data = unsafe { builder.build_unchecked() };
326
0
        PrimitiveArray::<T>::from(array_data)
327
0
    }
328
329
    /// Returns the current values buffer as a slice
330
    pub fn values_slice(&self) -> &[T::Native] {
331
        self.values_builder.as_slice()
332
    }
333
334
    /// Returns the current values buffer as a mutable slice
335
    pub fn values_slice_mut(&mut self) -> &mut [T::Native] {
336
        self.values_builder.as_mut_slice()
337
    }
338
339
    /// Returns the current null buffer as a slice
340
    pub fn validity_slice(&self) -> Option<&[u8]> {
341
        self.null_buffer_builder.as_slice()
342
    }
343
344
    /// Returns the current null buffer as a mutable slice
345
    pub fn validity_slice_mut(&mut self) -> Option<&mut [u8]> {
346
        self.null_buffer_builder.as_slice_mut()
347
    }
348
349
    /// Returns the current values buffer and null buffer as a slice
350
    pub fn slices_mut(&mut self) -> (&mut [T::Native], Option<&mut [u8]>) {
351
        (
352
            self.values_builder.as_mut_slice(),
353
            self.null_buffer_builder.as_slice_mut(),
354
        )
355
    }
356
}
357
358
impl<P: DecimalType> PrimitiveBuilder<P> {
359
    /// Sets the precision and scale
360
12
    pub fn with_precision_and_scale(self, precision: u8, scale: i8) -> Result<Self, ArrowError> {
361
12
        validate_decimal_precision_and_scale::<P>(precision, scale)
?0
;
362
12
        Ok(Self {
363
12
            data_type: P::TYPE_CONSTRUCTOR(precision, scale),
364
12
            ..self
365
12
        })
366
12
    }
367
}
368
369
impl<P: ArrowTimestampType> PrimitiveBuilder<P> {
370
    /// Sets the timezone
371
    pub fn with_timezone(self, timezone: impl Into<Arc<str>>) -> Self {
372
        self.with_timezone_opt(Some(timezone.into()))
373
    }
374
375
    /// Sets an optional timezone
376
    pub fn with_timezone_opt<S: Into<Arc<str>>>(self, timezone: Option<S>) -> Self {
377
        Self {
378
            data_type: DataType::Timestamp(P::UNIT, timezone.map(Into::into)),
379
            ..self
380
        }
381
    }
382
}
383
384
impl<P: ArrowPrimitiveType> Extend<Option<P::Native>> for PrimitiveBuilder<P> {
385
    #[inline]
386
    fn extend<T: IntoIterator<Item = Option<P::Native>>>(&mut self, iter: T) {
387
        for v in iter {
388
            self.append_option(v)
389
        }
390
    }
391
}
392
393
#[cfg(test)]
394
mod tests {
395
    use super::*;
396
    use arrow_buffer::{NullBuffer, ScalarBuffer};
397
    use arrow_schema::TimeUnit;
398
399
    use crate::array::Array;
400
    use crate::array::BooleanArray;
401
    use crate::array::Date32Array;
402
    use crate::array::Int32Array;
403
    use crate::array::TimestampSecondArray;
404
405
    #[test]
406
    fn test_primitive_array_builder_i32() {
407
        let mut builder = Int32Array::builder(5);
408
        for i in 0..5 {
409
            builder.append_value(i);
410
        }
411
        let arr = builder.finish();
412
        assert_eq!(5, arr.len());
413
        assert_eq!(0, arr.offset());
414
        assert_eq!(0, arr.null_count());
415
        for i in 0..5 {
416
            assert!(!arr.is_null(i));
417
            assert!(arr.is_valid(i));
418
            assert_eq!(i as i32, arr.value(i));
419
        }
420
    }
421
422
    #[test]
423
    fn test_primitive_array_builder_i32_append_iter() {
424
        let mut builder = Int32Array::builder(5);
425
        unsafe { builder.append_trusted_len_iter(0..5) };
426
        let arr = builder.finish();
427
        assert_eq!(5, arr.len());
428
        assert_eq!(0, arr.offset());
429
        assert_eq!(0, arr.null_count());
430
        for i in 0..5 {
431
            assert!(!arr.is_null(i));
432
            assert!(arr.is_valid(i));
433
            assert_eq!(i as i32, arr.value(i));
434
        }
435
    }
436
437
    #[test]
438
    fn test_primitive_array_builder_i32_append_nulls() {
439
        let mut builder = Int32Array::builder(5);
440
        builder.append_nulls(5);
441
        let arr = builder.finish();
442
        assert_eq!(5, arr.len());
443
        assert_eq!(0, arr.offset());
444
        assert_eq!(5, arr.null_count());
445
        for i in 0..5 {
446
            assert!(arr.is_null(i));
447
            assert!(!arr.is_valid(i));
448
        }
449
    }
450
451
    #[test]
452
    fn test_primitive_array_builder_date32() {
453
        let mut builder = Date32Array::builder(5);
454
        for i in 0..5 {
455
            builder.append_value(i);
456
        }
457
        let arr = builder.finish();
458
        assert_eq!(5, arr.len());
459
        assert_eq!(0, arr.offset());
460
        assert_eq!(0, arr.null_count());
461
        for i in 0..5 {
462
            assert!(!arr.is_null(i));
463
            assert!(arr.is_valid(i));
464
            assert_eq!(i as i32, arr.value(i));
465
        }
466
    }
467
468
    #[test]
469
    fn test_primitive_array_builder_timestamp_second() {
470
        let mut builder = TimestampSecondArray::builder(5);
471
        for i in 0..5 {
472
            builder.append_value(i);
473
        }
474
        let arr = builder.finish();
475
        assert_eq!(5, arr.len());
476
        assert_eq!(0, arr.offset());
477
        assert_eq!(0, arr.null_count());
478
        for i in 0..5 {
479
            assert!(!arr.is_null(i));
480
            assert!(arr.is_valid(i));
481
            assert_eq!(i as i64, arr.value(i));
482
        }
483
    }
484
485
    #[test]
486
    fn test_primitive_array_builder_bool() {
487
        // 00000010 01001000
488
        let buf = Buffer::from([72_u8, 2_u8]);
489
        let mut builder = BooleanArray::builder(10);
490
        for i in 0..10 {
491
            if i == 3 || i == 6 || i == 9 {
492
                builder.append_value(true);
493
            } else {
494
                builder.append_value(false);
495
            }
496
        }
497
498
        let arr = builder.finish();
499
        assert_eq!(&buf, arr.values().inner());
500
        assert_eq!(10, arr.len());
501
        assert_eq!(0, arr.offset());
502
        assert_eq!(0, arr.null_count());
503
        for i in 0..10 {
504
            assert!(!arr.is_null(i));
505
            assert!(arr.is_valid(i));
506
            assert_eq!(i == 3 || i == 6 || i == 9, arr.value(i), "failed at {i}")
507
        }
508
    }
509
510
    #[test]
511
    fn test_primitive_array_builder_append_option() {
512
        let arr1 = Int32Array::from(vec![Some(0), None, Some(2), None, Some(4)]);
513
514
        let mut builder = Int32Array::builder(5);
515
        builder.append_option(Some(0));
516
        builder.append_option(None);
517
        builder.append_option(Some(2));
518
        builder.append_option(None);
519
        builder.append_option(Some(4));
520
        let arr2 = builder.finish();
521
522
        assert_eq!(arr1.len(), arr2.len());
523
        assert_eq!(arr1.offset(), arr2.offset());
524
        assert_eq!(arr1.null_count(), arr2.null_count());
525
        for i in 0..5 {
526
            assert_eq!(arr1.is_null(i), arr2.is_null(i));
527
            assert_eq!(arr1.is_valid(i), arr2.is_valid(i));
528
            if arr1.is_valid(i) {
529
                assert_eq!(arr1.value(i), arr2.value(i));
530
            }
531
        }
532
    }
533
534
    #[test]
535
    fn test_primitive_array_builder_append_null() {
536
        let arr1 = Int32Array::from(vec![Some(0), Some(2), None, None, Some(4)]);
537
538
        let mut builder = Int32Array::builder(5);
539
        builder.append_value(0);
540
        builder.append_value(2);
541
        builder.append_null();
542
        builder.append_null();
543
        builder.append_value(4);
544
        let arr2 = builder.finish();
545
546
        assert_eq!(arr1.len(), arr2.len());
547
        assert_eq!(arr1.offset(), arr2.offset());
548
        assert_eq!(arr1.null_count(), arr2.null_count());
549
        for i in 0..5 {
550
            assert_eq!(arr1.is_null(i), arr2.is_null(i));
551
            assert_eq!(arr1.is_valid(i), arr2.is_valid(i));
552
            if arr1.is_valid(i) {
553
                assert_eq!(arr1.value(i), arr2.value(i));
554
            }
555
        }
556
    }
557
558
    #[test]
559
    fn test_primitive_array_builder_append_slice() {
560
        let arr1 = Int32Array::from(vec![Some(0), Some(2), None, None, Some(4)]);
561
562
        let mut builder = Int32Array::builder(5);
563
        builder.append_slice(&[0, 2]);
564
        builder.append_null();
565
        builder.append_null();
566
        builder.append_value(4);
567
        let arr2 = builder.finish();
568
569
        assert_eq!(arr1.len(), arr2.len());
570
        assert_eq!(arr1.offset(), arr2.offset());
571
        assert_eq!(arr1.null_count(), arr2.null_count());
572
        for i in 0..5 {
573
            assert_eq!(arr1.is_null(i), arr2.is_null(i));
574
            assert_eq!(arr1.is_valid(i), arr2.is_valid(i));
575
            if arr1.is_valid(i) {
576
                assert_eq!(arr1.value(i), arr2.value(i));
577
            }
578
        }
579
    }
580
581
    #[test]
582
    fn test_primitive_array_builder_finish() {
583
        let mut builder = Int32Builder::new();
584
        builder.append_slice(&[2, 4, 6, 8]);
585
        let mut arr = builder.finish();
586
        assert_eq!(4, arr.len());
587
        assert_eq!(0, builder.len());
588
589
        builder.append_slice(&[1, 3, 5, 7, 9]);
590
        arr = builder.finish();
591
        assert_eq!(5, arr.len());
592
        assert_eq!(0, builder.len());
593
    }
594
595
    #[test]
596
    fn test_primitive_array_builder_finish_cloned() {
597
        let mut builder = Int32Builder::new();
598
        builder.append_value(23);
599
        builder.append_value(45);
600
        let result = builder.finish_cloned();
601
        assert_eq!(result, Int32Array::from(vec![23, 45]));
602
        builder.append_value(56);
603
        assert_eq!(builder.finish_cloned(), Int32Array::from(vec![23, 45, 56]));
604
605
        builder.append_slice(&[2, 4, 6, 8]);
606
        let mut arr = builder.finish();
607
        assert_eq!(7, arr.len());
608
        assert_eq!(arr, Int32Array::from(vec![23, 45, 56, 2, 4, 6, 8]));
609
        assert_eq!(0, builder.len());
610
611
        builder.append_slice(&[1, 3, 5, 7, 9]);
612
        arr = builder.finish();
613
        assert_eq!(5, arr.len());
614
        assert_eq!(0, builder.len());
615
    }
616
617
    #[test]
618
    fn test_primitive_array_builder_with_data_type() {
619
        let mut builder = Decimal128Builder::new().with_data_type(DataType::Decimal128(1, 2));
620
        builder.append_value(1);
621
        let array = builder.finish();
622
        assert_eq!(array.precision(), 1);
623
        assert_eq!(array.scale(), 2);
624
625
        let data_type = DataType::Timestamp(TimeUnit::Nanosecond, Some("+00:00".into()));
626
        let mut builder = TimestampNanosecondBuilder::new().with_data_type(data_type.clone());
627
        builder.append_value(1);
628
        let array = builder.finish();
629
        assert_eq!(array.data_type(), &data_type);
630
    }
631
632
    #[test]
633
    #[should_panic(expected = "incompatible data type for builder, expected Int32 got Int64")]
634
    fn test_invalid_with_data_type() {
635
        Int32Builder::new().with_data_type(DataType::Int64);
636
    }
637
638
    #[test]
639
    fn test_extend() {
640
        let mut builder = PrimitiveBuilder::<Int16Type>::new();
641
        builder.extend([1, 2, 3, 5, 2, 4, 4].into_iter().map(Some));
642
        builder.extend([2, 4, 6, 2].into_iter().map(Some));
643
        let array = builder.finish();
644
        assert_eq!(array.values(), &[1, 2, 3, 5, 2, 4, 4, 2, 4, 6, 2]);
645
    }
646
647
    #[test]
648
    fn test_primitive_array_append_array() {
649
        let input = vec![
650
            Some(1),
651
            None,
652
            Some(3),
653
            None,
654
            Some(5),
655
            None,
656
            None,
657
            None,
658
            Some(7),
659
            Some(9),
660
            Some(8),
661
            Some(6),
662
            Some(4),
663
        ];
664
        let arr1 = Int32Array::from(input[..5].to_vec());
665
        let arr2 = Int32Array::from(input[5..8].to_vec());
666
        let arr3 = Int32Array::from(input[8..].to_vec());
667
668
        let mut builder = Int32Array::builder(5);
669
        builder.append_array(&arr1);
670
        builder.append_array(&arr2);
671
        builder.append_array(&arr3);
672
        let actual = builder.finish();
673
        let expected = Int32Array::from(input);
674
675
        assert_eq!(actual, expected);
676
    }
677
678
    #[test]
679
    fn test_append_array_add_underlying_null_values() {
680
        let array = Int32Array::new(
681
            ScalarBuffer::from(vec![2, 3, 4, 5]),
682
            Some(NullBuffer::from(&[true, true, false, false])),
683
        );
684
685
        let mut builder = Int32Array::builder(5);
686
        builder.append_array(&array);
687
        let actual = builder.finish();
688
689
        assert_eq!(actual, array);
690
        assert_eq!(actual.values(), array.values())
691
    }
692
693
    #[test]
694
    #[should_panic(expected = "array data type mismatch")]
695
    fn test_invalid_with_data_type_in_append_array() {
696
        let array = {
697
            let mut builder = Decimal128Builder::new().with_data_type(DataType::Decimal128(1, 2));
698
            builder.append_value(1);
699
            builder.finish()
700
        };
701
702
        let mut builder = Decimal128Builder::new().with_data_type(DataType::Decimal128(2, 3));
703
        builder.append_array(&array)
704
    }
705
}