1use crate::VariantArray;
21use arrow::array::{ArrayRef, BinaryViewArray, BinaryViewBuilder, NullBufferBuilder, StructArray};
22use arrow_schema::{ArrowError, DataType, Field, Fields};
23use parquet_variant::{
24 BuilderSpecificState, ListBuilder, MetadataBuilder, ObjectBuilder, Variant, VariantBuilderExt,
25 VariantMetadata,
26};
27use parquet_variant::{
28 ParentState, ReadOnlyMetadataBuilder, ValueBuilder, WritableMetadataBuilder,
29};
30use std::sync::Arc;
31
32#[derive(Debug)]
75pub struct VariantArrayBuilder {
76 nulls: NullBufferBuilder,
78 metadata_builder: WritableMetadataBuilder,
80 metadata_offsets: Vec<usize>,
82 value_builder: ValueBuilder,
84 value_offsets: Vec<usize>,
86 fields: Fields,
91}
92
93impl VariantArrayBuilder {
94 pub fn new(row_capacity: usize) -> Self {
95 let metadata_field = Field::new("metadata", DataType::BinaryView, false);
97 let value_field = Field::new("value", DataType::BinaryView, false);
98
99 Self {
100 nulls: NullBufferBuilder::new(row_capacity),
101 metadata_builder: WritableMetadataBuilder::default(),
102 metadata_offsets: Vec::with_capacity(row_capacity),
103 value_builder: ValueBuilder::new(),
104 value_offsets: Vec::with_capacity(row_capacity),
105 fields: Fields::from(vec![metadata_field, value_field]),
106 }
107 }
108
109 pub fn build(self) -> VariantArray {
111 let Self {
112 mut nulls,
113 metadata_builder,
114 metadata_offsets,
115 value_builder,
116 value_offsets,
117 fields,
118 } = self;
119
120 let metadata_buffer = metadata_builder.into_inner();
121 let metadata_array = binary_view_array_from_buffers(metadata_buffer, metadata_offsets);
122
123 let value_buffer = value_builder.into_inner();
124 let value_array = binary_view_array_from_buffers(value_buffer, value_offsets);
125
126 let inner = StructArray::new(
128 fields,
129 vec![
130 Arc::new(metadata_array) as ArrayRef,
131 Arc::new(value_array) as ArrayRef,
132 ],
133 nulls.finish(),
134 );
135 VariantArray::try_new(&inner).expect("valid VariantArray by construction")
138 }
139
140 pub fn append_null(&mut self) {
142 self.nulls.append_null();
143 self.metadata_offsets.push(self.metadata_builder.offset());
145 self.value_offsets.push(self.value_builder.offset());
146 }
147
148 pub fn append_variant(&mut self, variant: Variant) {
150 ValueBuilder::append_variant(self.parent_state(), variant);
151 }
152
153 fn parent_state(&mut self) -> ParentState<'_, ArrayBuilderState<'_>> {
155 let state = ArrayBuilderState {
156 metadata_offsets: &mut self.metadata_offsets,
157 value_offsets: &mut self.value_offsets,
158 nulls: &mut self.nulls,
159 };
160
161 ParentState::new(&mut self.value_builder, &mut self.metadata_builder, state)
162 }
163}
164
165#[derive(Debug)]
168pub struct ArrayBuilderState<'a> {
169 metadata_offsets: &'a mut Vec<usize>,
170 value_offsets: &'a mut Vec<usize>,
171 nulls: &'a mut NullBufferBuilder,
172}
173
174impl BuilderSpecificState for ArrayBuilderState<'_> {
176 fn finish(
177 &mut self,
178 metadata_builder: &mut dyn MetadataBuilder,
179 value_builder: &mut ValueBuilder,
180 ) {
181 self.metadata_offsets.push(metadata_builder.finish());
182 self.value_offsets.push(value_builder.offset());
183 self.nulls.append_non_null();
184 }
185}
186
187impl VariantBuilderExt for VariantArrayBuilder {
188 type State<'a>
189 = ArrayBuilderState<'a>
190 where
191 Self: 'a;
192
193 fn append_null(&mut self) {
195 self.append_null();
196 }
197
198 fn append_value<'m, 'v>(&mut self, value: impl Into<Variant<'m, 'v>>) {
199 self.append_variant(value.into());
200 }
201
202 fn try_new_list(&mut self) -> Result<ListBuilder<'_, Self::State<'_>>, ArrowError> {
203 Ok(ListBuilder::new(self.parent_state(), false))
204 }
205
206 fn try_new_object(&mut self) -> Result<ObjectBuilder<'_, Self::State<'_>>, ArrowError> {
207 Ok(ObjectBuilder::new(self.parent_state(), false))
208 }
209}
210
211#[derive(Debug)]
239pub struct VariantValueArrayBuilder {
240 value_builder: ValueBuilder,
241 value_offsets: Vec<usize>,
242 nulls: NullBufferBuilder,
243}
244
245impl VariantValueArrayBuilder {
246 pub fn new(row_capacity: usize) -> Self {
248 Self {
249 value_builder: ValueBuilder::new(),
250 value_offsets: Vec::with_capacity(row_capacity),
251 nulls: NullBufferBuilder::new(row_capacity),
252 }
253 }
254
255 pub fn build(mut self) -> Result<BinaryViewArray, ArrowError> {
260 let value_buffer = self.value_builder.into_inner();
261 let mut array = binary_view_array_from_buffers(value_buffer, self.value_offsets);
262 if let Some(nulls) = self.nulls.finish() {
263 let (views, buffers, _) = array.into_parts();
264 array = BinaryViewArray::try_new(views, buffers, Some(nulls))?;
265 }
266 Ok(array)
267 }
268
269 pub fn append_null(&mut self) {
276 self.value_offsets.push(self.value_builder.offset());
277 self.nulls.append_null();
278 }
279
280 pub fn append_value(&mut self, value: Variant<'_, '_>) {
298 self.builder_ext(&value.metadata().clone())
300 .append_value(value);
301 }
302
303 pub fn parent_state<'a>(
328 &'a mut self,
329 metadata_builder: &'a mut dyn MetadataBuilder,
330 ) -> ParentState<'a, ValueArrayBuilderState<'a>> {
331 let state = ValueArrayBuilderState {
332 value_offsets: &mut self.value_offsets,
333 nulls: &mut self.nulls,
334 };
335
336 ParentState::new(&mut self.value_builder, metadata_builder, state)
337 }
338
339 pub fn builder_ext<'a>(
342 &'a mut self,
343 metadata: &'a VariantMetadata<'a>,
344 ) -> VariantValueArrayBuilderExt<'a> {
345 VariantValueArrayBuilderExt {
346 metadata_builder: ReadOnlyMetadataBuilder::new(metadata),
347 value_builder: self,
348 }
349 }
350}
351
352#[derive(Debug)]
355pub struct ValueArrayBuilderState<'a> {
356 value_offsets: &'a mut Vec<usize>,
357 nulls: &'a mut NullBufferBuilder,
358}
359
360impl BuilderSpecificState for ValueArrayBuilderState<'_> {
362 fn finish(
363 &mut self,
364 _metadata_builder: &mut dyn MetadataBuilder,
365 value_builder: &mut ValueBuilder,
366 ) {
367 self.value_offsets.push(value_builder.offset());
368 self.nulls.append_non_null();
369 }
370}
371
372pub struct VariantValueArrayBuilderExt<'a> {
375 metadata_builder: ReadOnlyMetadataBuilder<'a>,
376 value_builder: &'a mut VariantValueArrayBuilder,
377}
378
379impl<'a> VariantValueArrayBuilderExt<'a> {
380 pub fn new(
382 metadata_builder: ReadOnlyMetadataBuilder<'a>,
383 value_builder: &'a mut VariantValueArrayBuilder,
384 ) -> Self {
385 Self {
386 metadata_builder,
387 value_builder,
388 }
389 }
390}
391
392impl<'a> VariantBuilderExt for VariantValueArrayBuilderExt<'a> {
393 type State<'b>
394 = ValueArrayBuilderState<'b>
395 where
396 Self: 'b;
397
398 fn append_null(&mut self) {
399 self.value_builder.append_null()
400 }
401
402 fn append_value<'m, 'v>(&mut self, value: impl Into<Variant<'m, 'v>>) {
403 let state = self.value_builder.parent_state(&mut self.metadata_builder);
404 ValueBuilder::append_variant_bytes(state, value.into());
405 }
406
407 fn try_new_list(&mut self) -> Result<ListBuilder<'_, Self::State<'_>>, ArrowError> {
408 let state = self.value_builder.parent_state(&mut self.metadata_builder);
409 Ok(ListBuilder::new(state, false))
410 }
411
412 fn try_new_object(&mut self) -> Result<ObjectBuilder<'_, Self::State<'_>>, ArrowError> {
413 let state = self.value_builder.parent_state(&mut self.metadata_builder);
414 Ok(ObjectBuilder::new(state, false))
415 }
416}
417
418fn binary_view_array_from_buffers(buffer: Vec<u8>, offsets: Vec<usize>) -> BinaryViewArray {
419 u32::try_from(buffer.len()).expect("buffer length should fit in u32");
422
423 let mut builder = BinaryViewBuilder::with_capacity(offsets.len());
424 let block = builder.append_block(buffer.into());
425 let mut start = 0;
427 for end in offsets {
428 let end = end as u32; builder
430 .try_append_view(block, start, end - start)
431 .expect("Failed to append view");
432 start = end;
433 }
434 builder.finish()
435}
436
437#[cfg(test)]
438mod test {
439 use super::*;
440 use arrow::array::Array;
441 use parquet_variant::Variant;
442
443 #[test]
445 fn test_variant_array_builder_non_nullable() {
446 let mut builder = VariantArrayBuilder::new(10);
447 builder.append_null(); builder.append_variant(Variant::from(42i32));
449 let variant_array = builder.build();
450
451 assert_eq!(variant_array.len(), 2);
452 assert!(variant_array.is_null(0));
453 assert!(!variant_array.is_null(1));
454 assert_eq!(variant_array.value(1), Variant::from(42i32));
455
456 assert!(variant_array.metadata_field().nulls().is_none());
458 assert!(variant_array.value_field().unwrap().nulls().is_none());
459 let DataType::Struct(fields) = variant_array.data_type() else {
460 panic!("Expected VariantArray to have Struct data type");
461 };
462 for field in fields {
463 assert!(
464 !field.is_nullable(),
465 "Field {} should be non-nullable",
466 field.name()
467 );
468 }
469 }
470
471 #[test]
473 fn test_variant_array_builder() {
474 let mut builder = VariantArrayBuilder::new(10);
475 builder.append_null(); builder.append_variant(Variant::from(42i32));
477
478 builder.new_object().with_field("foo", "bar").finish();
480
481 builder
483 .new_list()
484 .with_value(Variant::from(1i32))
485 .with_value(Variant::from(2i32))
486 .finish();
487 let variant_array = builder.build();
488
489 assert_eq!(variant_array.len(), 4);
490 assert!(variant_array.is_null(0));
491 assert!(!variant_array.is_null(1));
492 assert_eq!(variant_array.value(1), Variant::from(42i32));
493 assert!(!variant_array.is_null(2));
494 let variant = variant_array.value(2);
495 let variant = variant.as_object().expect("variant to be an object");
496 assert_eq!(variant.get("foo").unwrap(), Variant::from("bar"));
497 assert!(!variant_array.is_null(3));
498 let variant = variant_array.value(3);
499 let list = variant.as_list().expect("variant to be a list");
500 assert_eq!(list.len(), 2);
501 }
502
503 #[test]
504 fn test_variant_value_array_builder_basic() {
505 let mut builder = VariantValueArrayBuilder::new(10);
506
507 builder.append_value(Variant::from(42i32));
509 builder.append_null();
510 builder.append_value(Variant::from("hello"));
511
512 let value_array = builder.build().unwrap();
513 assert_eq!(value_array.len(), 3);
514 }
515
516 #[test]
517 fn test_variant_value_array_builder_with_objects() {
518 let mut builder = VariantArrayBuilder::new(3);
520 builder
521 .new_object()
522 .with_field("name", "Alice")
523 .with_field("age", 30i32)
524 .finish();
525
526 builder
527 .new_object()
528 .with_field("name", "Bob")
529 .with_field("age", 42i32)
530 .with_field("city", "Wonderland")
531 .finish();
532
533 builder
534 .new_object()
535 .with_field("name", "Charlie")
536 .with_field("age", 1i32)
537 .finish();
538
539 let array = builder.build();
540
541 let mut value_builder = VariantValueArrayBuilder::new(3);
546
547 value_builder.append_value(array.value(0));
549
550 let value = array.value(1);
552 let mut builder = value_builder.builder_ext(value.metadata());
553 builder
554 .new_object()
555 .with_field("name", value.get_object_field("name").unwrap())
556 .with_field("age", value.get_object_field("age").unwrap())
557 .finish();
558
559 let value = array.value(2);
561 let mut builder = value_builder.builder_ext(value.metadata());
562 builder
563 .new_list()
564 .with_value(value.clone())
565 .with_value(value.clone())
566 .finish();
567
568 let array2 = VariantArray::from_parts(
569 array.metadata_field().clone(),
570 Some(value_builder.build().unwrap()),
571 None,
572 None,
573 );
574
575 assert_eq!(array2.len(), 3);
576 assert_eq!(array.value(0), array2.value(0));
577
578 assert_eq!(
579 array.value(1).get_object_field("name"),
580 array2.value(1).get_object_field("name")
581 );
582 assert_eq!(
583 array.value(1).get_object_field("age"),
584 array2.value(1).get_object_field("age")
585 );
586
587 assert_eq!(array.value(2), array2.value(2).get_list_element(0).unwrap());
588 assert_eq!(array.value(2), array2.value(2).get_list_element(1).unwrap());
589 }
590}