1use crate::StructArray;
19use crate::builder::*;
20use arrow_buffer::NullBufferBuilder;
21use arrow_schema::{Fields, SchemaBuilder};
22use std::sync::Arc;
23
24pub struct StructBuilder {
106 fields: Fields,
107 field_builders: Vec<Box<dyn ArrayBuilder>>,
108 null_buffer_builder: NullBufferBuilder,
109}
110
111impl std::fmt::Debug for StructBuilder {
112 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
113 f.debug_struct("StructBuilder")
114 .field("fields", &self.fields)
115 .field("bitmap_builder", &self.null_buffer_builder)
116 .field("len", &self.len())
117 .finish()
118 }
119}
120
121impl ArrayBuilder for StructBuilder {
122 fn len(&self) -> usize {
128 self.null_buffer_builder.len()
129 }
130
131 fn finish(&mut self) -> ArrayRef {
133 Arc::new(self.finish())
134 }
135
136 fn finish_cloned(&self) -> ArrayRef {
138 Arc::new(self.finish_cloned())
139 }
140
141 fn finish_preserve_values(&mut self) -> ArrayRef {
142 Arc::new(self.finish_preserve_values())
143 }
144
145 fn as_any(&self) -> &dyn Any {
151 self
152 }
153
154 fn as_any_mut(&mut self) -> &mut dyn Any {
160 self
161 }
162
163 fn into_box_any(self: Box<Self>) -> Box<dyn Any> {
165 self
166 }
167}
168
169impl StructBuilder {
170 pub fn new(fields: impl Into<Fields>, field_builders: Vec<Box<dyn ArrayBuilder>>) -> Self {
172 Self {
173 field_builders,
174 fields: fields.into(),
175 null_buffer_builder: NullBufferBuilder::new(0),
176 }
177 }
178
179 pub fn from_fields(fields: impl Into<Fields>, capacity: usize) -> Self {
181 let fields = fields.into();
182 let mut builders = Vec::with_capacity(fields.len());
183 for field in &fields {
184 builders.push(make_builder(field.data_type(), capacity));
185 }
186 Self::new(fields, builders)
187 }
188
189 pub fn field_builder<T: ArrayBuilder>(&mut self, i: usize) -> Option<&mut T> {
193 self.field_builders[i].as_any_mut().downcast_mut::<T>()
194 }
195
196 pub fn field_builders(&self) -> &[Box<dyn ArrayBuilder>] {
198 &self.field_builders
199 }
200
201 pub fn field_builders_mut(&mut self) -> &mut [Box<dyn ArrayBuilder>] {
203 &mut self.field_builders
204 }
205
206 pub fn num_fields(&self) -> usize {
208 self.field_builders.len()
209 }
210
211 pub fn fields(&self) -> &Fields {
213 &self.fields
214 }
215
216 #[inline]
219 pub fn append(&mut self, is_valid: bool) {
220 self.null_buffer_builder.append(is_valid);
221 }
222
223 #[inline]
225 pub fn append_non_nulls(&mut self, n: usize) {
226 self.null_buffer_builder.append_n_non_nulls(n);
227 }
228
229 #[inline]
231 pub fn append_null(&mut self) {
232 self.append(false)
233 }
234
235 #[inline]
237 pub fn append_nulls(&mut self, n: usize) {
238 self.null_buffer_builder.append_n_nulls(n);
239 }
240
241 pub fn finish(&mut self) -> StructArray {
248 self.validate_content();
249 if self.fields.is_empty() {
250 return StructArray::new_empty_fields(self.len(), self.null_buffer_builder.finish());
251 }
252
253 let arrays = self.field_builders.iter_mut().map(|f| f.finish()).collect();
254 let nulls = self.null_buffer_builder.finish();
255 StructArray::new(self.fields.clone(), arrays, nulls)
256 }
257
258 pub fn finish_cloned(&self) -> StructArray {
265 self.validate_content();
266
267 if self.fields.is_empty() {
268 return StructArray::new_empty_fields(
269 self.len(),
270 self.null_buffer_builder.finish_cloned(),
271 );
272 }
273
274 let arrays = self
275 .field_builders
276 .iter()
277 .map(|f| f.finish_cloned())
278 .collect();
279
280 let nulls = self.null_buffer_builder.finish_cloned();
281
282 StructArray::new(self.fields.clone(), arrays, nulls)
283 }
284
285 fn finish_preserve_values(&mut self) -> StructArray {
286 self.validate_content();
287 if self.fields.is_empty() {
288 return StructArray::new_empty_fields(self.len(), self.null_buffer_builder.finish());
289 }
290
291 let arrays = self
292 .field_builders
293 .iter_mut()
294 .map(|f| f.finish_preserve_values())
295 .collect();
296
297 let nulls = self.null_buffer_builder.finish();
298
299 StructArray::new(self.fields.clone(), arrays, nulls)
300 }
301
302 fn validate_content(&self) {
306 if self.fields.len() != self.field_builders.len() {
307 panic!("Number of fields is not equal to the number of field_builders.");
308 }
309 self.field_builders.iter().enumerate().for_each(|(idx, x)| {
310 if x.len() != self.len() {
311 let builder = SchemaBuilder::from(&self.fields);
312 let schema = builder.finish();
313
314 panic!("{}", format!(
315 "StructBuilder ({}) and field_builder with index {} ({}) are of unequal lengths: ({} != {}).",
316 schema,
317 idx,
318 self.fields[idx].data_type(),
319 self.len(),
320 x.len()
321 ));
322 }
323 });
324 }
325
326 pub fn validity_slice(&self) -> Option<&[u8]> {
328 self.null_buffer_builder.as_slice()
329 }
330
331 pub fn validity_capacity(&self) -> usize {
333 self.null_buffer_builder.allocated_size()
334 }
335}
336
337#[cfg(test)]
338mod tests {
339 use std::any::type_name;
340
341 use super::*;
342 use arrow_buffer::Buffer;
343 use arrow_data::ArrayData;
344 use arrow_schema::Field;
345
346 use crate::{array::Array, builder::tests::PreserveValuesMock, types::ArrowDictionaryKeyType};
347
348 #[test]
349 fn test_struct_array_builder() {
350 let string_builder = StringBuilder::new();
351 let int_builder = Int32Builder::new();
352
353 let fields = vec![
354 Field::new("f1", DataType::Utf8, true),
355 Field::new("f2", DataType::Int32, true),
356 ];
357 let field_builders = vec![
358 Box::new(string_builder) as Box<dyn ArrayBuilder>,
359 Box::new(int_builder) as Box<dyn ArrayBuilder>,
360 ];
361
362 let mut builder = StructBuilder::new(fields, field_builders);
363 assert_eq!(2, builder.num_fields());
364
365 let string_builder = builder
366 .field_builder::<StringBuilder>(0)
367 .expect("builder at field 0 should be string builder");
368 string_builder.append_value("joe");
369 string_builder.append_null();
370 string_builder.append_null();
371 string_builder.append_value("mark");
372 string_builder.append_nulls(2);
373 string_builder.append_value("terry");
374
375 let int_builder = builder
376 .field_builder::<Int32Builder>(1)
377 .expect("builder at field 1 should be int builder");
378 int_builder.append_value(1);
379 int_builder.append_value(2);
380 int_builder.append_null();
381 int_builder.append_value(4);
382 int_builder.append_nulls(2);
383 int_builder.append_value(3);
384
385 builder.append(true);
386 builder.append(true);
387 builder.append_null();
388 builder.append(true);
389
390 builder.append_nulls(2);
391 builder.append(true);
392
393 let struct_data = builder.finish().into_data();
394
395 assert_eq!(7, struct_data.len());
396 assert_eq!(3, struct_data.null_count());
397 assert_eq!(&[75_u8], struct_data.nulls().unwrap().validity());
398
399 let expected_string_data = ArrayData::builder(DataType::Utf8)
400 .len(7)
401 .null_bit_buffer(Some(Buffer::from(&[73_u8])))
402 .add_buffer(Buffer::from_slice_ref([0, 3, 3, 3, 7, 7, 7, 12]))
403 .add_buffer(Buffer::from_slice_ref(b"joemarkterry"))
404 .build()
405 .unwrap();
406
407 let expected_int_data = ArrayData::builder(DataType::Int32)
408 .len(7)
409 .null_bit_buffer(Some(Buffer::from_slice_ref([75_u8])))
410 .add_buffer(Buffer::from_slice_ref([1, 2, 0, 4, 4, 4, 3]))
411 .build()
412 .unwrap();
413
414 assert_eq!(expected_string_data, struct_data.child_data()[0]);
415 assert_eq!(expected_int_data, struct_data.child_data()[1]);
416
417 assert!(struct_data.is_null(4));
418 assert!(struct_data.is_null(5));
419 }
420
421 #[test]
422 fn test_struct_array_builder_finish() {
423 let int_builder = Int32Builder::new();
424 let bool_builder = BooleanBuilder::new();
425
426 let fields = vec![
427 Field::new("f1", DataType::Int32, false),
428 Field::new("f2", DataType::Boolean, false),
429 ];
430 let field_builders = vec![
431 Box::new(int_builder) as Box<dyn ArrayBuilder>,
432 Box::new(bool_builder) as Box<dyn ArrayBuilder>,
433 ];
434
435 let mut builder = StructBuilder::new(fields, field_builders);
436 builder
437 .field_builder::<Int32Builder>(0)
438 .unwrap()
439 .append_slice(&[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
440 builder
441 .field_builder::<BooleanBuilder>(1)
442 .unwrap()
443 .append_slice(&[
444 false, true, false, true, false, true, false, true, false, true,
445 ]);
446
447 for _ in 0..10 {
449 builder.append(true);
450 }
451
452 assert_eq!(10, builder.len());
453
454 let arr = builder.finish();
455
456 assert_eq!(10, arr.len());
457 assert_eq!(0, builder.len());
458
459 builder
460 .field_builder::<Int32Builder>(0)
461 .unwrap()
462 .append_slice(&[1, 3, 5, 7, 9]);
463 builder
464 .field_builder::<BooleanBuilder>(1)
465 .unwrap()
466 .append_slice(&[false, true, false, true, false]);
467
468 for _ in 0..5 {
470 builder.append(true);
471 }
472
473 assert_eq!(5, builder.len());
474
475 let arr = builder.finish();
476
477 assert_eq!(5, arr.len());
478 assert_eq!(0, builder.len());
479 }
480
481 #[test]
482 fn test_build_fixed_size_list() {
483 const LIST_LENGTH: i32 = 4;
484 let fixed_size_list_dtype =
485 DataType::new_fixed_size_list(DataType::Int32, LIST_LENGTH, false);
486 let mut builder = make_builder(&fixed_size_list_dtype, 10);
487 let builder = builder
488 .as_any_mut()
489 .downcast_mut::<FixedSizeListBuilder<Box<dyn ArrayBuilder>>>();
490 match builder {
491 Some(builder) => {
492 assert_eq!(builder.value_length(), LIST_LENGTH);
493 assert!(
494 builder
495 .values()
496 .as_any_mut()
497 .downcast_mut::<Int32Builder>()
498 .is_some()
499 );
500 }
501 None => panic!("expected FixedSizeListBuilder, got a different builder type"),
502 }
503 }
504
505 #[test]
506 fn test_struct_array_builder_finish_cloned() {
507 let int_builder = Int32Builder::new();
508 let bool_builder = BooleanBuilder::new();
509
510 let fields = vec![
511 Field::new("f1", DataType::Int32, false),
512 Field::new("f2", DataType::Boolean, false),
513 ];
514 let field_builders = vec![
515 Box::new(int_builder) as Box<dyn ArrayBuilder>,
516 Box::new(bool_builder) as Box<dyn ArrayBuilder>,
517 ];
518
519 let mut builder = StructBuilder::new(fields, field_builders);
520 builder
521 .field_builder::<Int32Builder>(0)
522 .unwrap()
523 .append_slice(&[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
524 builder
525 .field_builder::<BooleanBuilder>(1)
526 .unwrap()
527 .append_slice(&[
528 false, true, false, true, false, true, false, true, false, true,
529 ]);
530
531 for _ in 0..10 {
533 builder.append(true);
534 }
535
536 assert_eq!(10, builder.len());
537
538 let mut arr = builder.finish_cloned();
539
540 assert_eq!(10, arr.len());
541 assert_eq!(10, builder.len());
542
543 builder
544 .field_builder::<Int32Builder>(0)
545 .unwrap()
546 .append_slice(&[1, 3, 5, 7, 9]);
547 builder
548 .field_builder::<BooleanBuilder>(1)
549 .unwrap()
550 .append_slice(&[false, true, false, true, false]);
551
552 for _ in 0..5 {
554 builder.append(true);
555 }
556
557 assert_eq!(15, builder.len());
558
559 arr = builder.finish();
560
561 assert_eq!(15, arr.len());
562 assert_eq!(0, builder.len());
563 }
564
565 #[test]
566 fn test_struct_array_builder_finish_preserve_values() {
567 let fields = vec![Field::new("mock", DataType::Int32, false)];
568 let field_builders = vec![Box::new(PreserveValuesMock::default()) as Box<dyn ArrayBuilder>];
569
570 let mut builder = StructBuilder::new(fields, field_builders);
571 builder
572 .field_builder::<PreserveValuesMock>(0)
573 .unwrap()
574 .inner
575 .append_value(1);
576 builder.append(true);
577
578 assert_eq!(1, builder.len());
579
580 let arr = builder.finish_preserve_values();
581
582 assert_eq!(1, arr.len());
583 assert_eq!(
584 1,
585 builder
586 .field_builder::<PreserveValuesMock>(0)
587 .unwrap()
588 .called
589 );
590 }
591
592 #[test]
593 fn test_struct_array_builder_from_schema() {
594 let mut fields = vec![
595 Field::new("f1", DataType::Float32, false),
596 Field::new("f2", DataType::Utf8, false),
597 ];
598 let sub_fields = vec![
599 Field::new("g1", DataType::Int32, false),
600 Field::new("g2", DataType::Boolean, false),
601 ];
602 let struct_type = DataType::Struct(sub_fields.into());
603 fields.push(Field::new("f3", struct_type, false));
604
605 let mut builder = StructBuilder::from_fields(fields, 5);
606 assert_eq!(3, builder.num_fields());
607 assert!(builder.field_builder::<Float32Builder>(0).is_some());
608 assert!(builder.field_builder::<StringBuilder>(1).is_some());
609 assert!(builder.field_builder::<StructBuilder>(2).is_some());
610 }
611
612 #[test]
613 fn test_datatype_properties() {
614 let fields = Fields::from(vec![
615 Field::new("f1", DataType::Decimal128(1, 2), false),
616 Field::new(
617 "f2",
618 DataType::Timestamp(TimeUnit::Millisecond, Some("+00:00".into())),
619 false,
620 ),
621 ]);
622 let mut builder = StructBuilder::from_fields(fields.clone(), 1);
623 builder
624 .field_builder::<Decimal128Builder>(0)
625 .unwrap()
626 .append_value(1);
627 builder
628 .field_builder::<TimestampMillisecondBuilder>(1)
629 .unwrap()
630 .append_value(1);
631 builder.append(true);
632 let array = builder.finish();
633
634 assert_eq!(array.data_type(), &DataType::Struct(fields.clone()));
635 assert_eq!(array.column(0).data_type(), fields[0].data_type());
636 assert_eq!(array.column(1).data_type(), fields[1].data_type());
637 }
638
639 #[test]
640 fn test_struct_array_builder_from_dictionary_type_int8_key() {
641 test_struct_array_builder_from_dictionary_type_inner::<Int8Type>(DataType::Int8);
642 }
643
644 #[test]
645 fn test_struct_array_builder_from_dictionary_type_int16_key() {
646 test_struct_array_builder_from_dictionary_type_inner::<Int16Type>(DataType::Int16);
647 }
648
649 #[test]
650 fn test_struct_array_builder_from_dictionary_type_int32_key() {
651 test_struct_array_builder_from_dictionary_type_inner::<Int32Type>(DataType::Int32);
652 }
653
654 #[test]
655 fn test_struct_array_builder_from_dictionary_type_int64_key() {
656 test_struct_array_builder_from_dictionary_type_inner::<Int64Type>(DataType::Int64);
657 }
658
659 fn test_struct_array_builder_from_dictionary_type_inner<K: ArrowDictionaryKeyType>(
660 key_type: DataType,
661 ) {
662 let dict_field = Field::new(
663 "f1",
664 DataType::Dictionary(Box::new(key_type), Box::new(DataType::Utf8)),
665 false,
666 );
667 let fields = vec![dict_field.clone()];
668 let expected_dtype = DataType::Struct(fields.into());
669 let cloned_dict_field = dict_field.clone();
670 let expected_child_dtype = dict_field.data_type();
671 let mut struct_builder = StructBuilder::from_fields(vec![cloned_dict_field], 5);
672 let Some(dict_builder) = struct_builder.field_builder::<StringDictionaryBuilder<K>>(0)
673 else {
674 panic!(
675 "Builder should be StringDictionaryBuilder<{}>",
676 type_name::<K>()
677 )
678 };
679 dict_builder.append_value("dict string");
680 struct_builder.append(true);
681 let array = struct_builder.finish();
682
683 assert_eq!(array.data_type(), &expected_dtype);
684 assert_eq!(array.column(0).data_type(), expected_child_dtype);
685 assert_eq!(array.column(0).len(), 1);
686 }
687
688 #[test]
689 #[should_panic(
690 expected = "Data type Dictionary(UInt64, Utf8) with key type UInt64 is not currently supported"
691 )]
692 fn test_struct_array_builder_from_schema_unsupported_type() {
693 let fields = vec![
694 Field::new("f1", DataType::UInt64, false),
695 Field::new(
696 "f2",
697 DataType::Dictionary(Box::new(DataType::UInt64), Box::new(DataType::Utf8)),
698 false,
699 ),
700 ];
701
702 let _ = StructBuilder::from_fields(fields, 5);
703 }
704
705 #[test]
706 #[should_panic(expected = "Dictionary value type Int32 is not currently supported")]
707 fn test_struct_array_builder_from_dict_with_unsupported_value_type() {
708 let fields = vec![Field::new(
709 "f1",
710 DataType::Dictionary(Box::new(DataType::Int32), Box::new(DataType::Int32)),
711 false,
712 )];
713
714 let _ = StructBuilder::from_fields(fields, 5);
715 }
716
717 #[test]
718 fn test_struct_array_builder_field_builder_type_mismatch() {
719 let int_builder = Int32Builder::with_capacity(10);
720
721 let fields = vec![Field::new("f1", DataType::Int32, false)];
722 let field_builders = vec![Box::new(int_builder) as Box<dyn ArrayBuilder>];
723
724 let mut builder = StructBuilder::new(fields, field_builders);
725 assert!(builder.field_builder::<BinaryBuilder>(0).is_none());
726 }
727
728 #[test]
729 #[should_panic(
730 expected = "StructBuilder (Field { \"f1\": Int32 }, Field { \"f2\": Boolean }) and field_builder with index 1 (Boolean) are of unequal lengths: (2 != 1)."
731 )]
732 fn test_struct_array_builder_unequal_field_builders_lengths() {
733 let mut int_builder = Int32Builder::with_capacity(10);
734 let mut bool_builder = BooleanBuilder::new();
735
736 int_builder.append_value(1);
737 int_builder.append_value(2);
738 bool_builder.append_value(true);
739
740 let fields = vec![
741 Field::new("f1", DataType::Int32, false),
742 Field::new("f2", DataType::Boolean, false),
743 ];
744 let field_builders = vec![
745 Box::new(int_builder) as Box<dyn ArrayBuilder>,
746 Box::new(bool_builder) as Box<dyn ArrayBuilder>,
747 ];
748
749 let mut builder = StructBuilder::new(fields, field_builders);
750 builder.append(true);
751 builder.append(true);
752 builder.finish();
753 }
754
755 #[test]
756 #[should_panic(expected = "Number of fields is not equal to the number of field_builders.")]
757 fn test_struct_array_builder_unequal_field_field_builders() {
758 let int_builder = Int32Builder::with_capacity(10);
759
760 let fields = vec![
761 Field::new("f1", DataType::Int32, false),
762 Field::new("f2", DataType::Boolean, false),
763 ];
764 let field_builders = vec![Box::new(int_builder) as Box<dyn ArrayBuilder>];
765
766 let mut builder = StructBuilder::new(fields, field_builders);
767 builder.finish();
768 }
769
770 #[test]
771 #[should_panic(
772 expected = "Incorrect datatype for StructArray field \\\"timestamp\\\", expected Timestamp(ns, \\\"UTC\\\") got Timestamp(ns)"
773 )]
774 fn test_struct_array_mismatch_builder() {
775 let fields = vec![Field::new(
776 "timestamp",
777 DataType::Timestamp(TimeUnit::Nanosecond, Some("UTC".to_owned().into())),
778 false,
779 )];
780
781 let field_builders: Vec<Box<dyn ArrayBuilder>> =
782 vec![Box::new(TimestampNanosecondBuilder::new())];
783
784 let mut sa = StructBuilder::new(fields, field_builders);
785 sa.finish();
786 }
787
788 #[test]
789 fn test_empty() {
790 let mut builder = StructBuilder::new(Fields::empty(), vec![]);
791 builder.append(true);
792 builder.append(false);
793
794 let a1 = builder.finish_cloned();
795 let a2 = builder.finish();
796 assert_eq!(a1, a2);
797 assert_eq!(a1.len(), 2);
798 assert_eq!(a1.null_count(), 1);
799 assert!(a1.is_valid(0));
800 assert!(a1.is_null(1));
801 }
802
803 #[test]
804 fn test_append_non_nulls() {
805 let int_builder = Int32Builder::new();
806 let fields = vec![Field::new("f1", DataType::Int32, false)];
807 let field_builders = vec![Box::new(int_builder) as Box<dyn ArrayBuilder>];
808
809 let mut builder = StructBuilder::new(fields, field_builders);
810 builder
811 .field_builder::<Int32Builder>(0)
812 .unwrap()
813 .append_slice(&[1, 2, 3, 4, 5]);
814 builder.append_non_nulls(5);
815
816 let arr = builder.finish();
817 assert_eq!(arr.len(), 5);
818 assert_eq!(arr.null_count(), 0);
819 for i in 0..5 {
820 assert!(arr.is_valid(i));
821 }
822 }
823
824 #[test]
825 fn test_append_non_nulls_with_nulls() {
826 let mut builder = StructBuilder::new(Fields::empty(), vec![]);
827 builder.append_null();
828 builder.append_non_nulls(3);
829 builder.append_nulls(2);
830 builder.append_non_nulls(1);
831
832 let arr = builder.finish();
833 assert_eq!(arr.len(), 7);
834 assert_eq!(arr.null_count(), 3);
835 assert!(arr.is_null(0));
836 assert!(arr.is_valid(1));
837 assert!(arr.is_valid(2));
838 assert!(arr.is_valid(3));
839 assert!(arr.is_null(4));
840 assert!(arr.is_null(5));
841 assert!(arr.is_valid(6));
842 }
843
844 #[test]
845 fn test_append_non_nulls_zero() {
846 let mut builder = StructBuilder::new(Fields::empty(), vec![]);
847 builder.append_non_nulls(0);
848 assert_eq!(builder.len(), 0);
849
850 builder.append(true);
851 builder.append_non_nulls(0);
852 assert_eq!(builder.len(), 1);
853
854 let arr = builder.finish();
855 assert_eq!(arr.len(), 1);
856 assert_eq!(arr.null_count(), 0);
857 }
858}