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