Skip to content

Commit f286c52

Browse files
committed
review feedback
1 parent 5959577 commit f286c52

File tree

1 file changed

+71
-24
lines changed

1 file changed

+71
-24
lines changed

parquet-variant-compute/src/variant_array_builder.rs

Lines changed: 71 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -225,8 +225,9 @@ impl VariantBuilderExt for VariantArrayBuilder {
225225
/// // Create a variant value builder for 10 rows
226226
/// let mut builder = VariantValueArrayBuilder::new(10);
227227
///
228-
/// // Append some values with their corresponding metadata
229-
/// // In practice, some of the variant values would be objects with internal metadata.
228+
/// // Append some values with their corresponding metadata. In practice, some of the variant
229+
/// // values would be objects with internal references to pre-existing metadata, which the
230+
/// // builder takes advantage of to avoid creating new metadata.
230231
/// builder.append_value(Variant::from(42));
231232
/// builder.append_null();
232233
/// builder.append_value(Variant::from("hello"));
@@ -268,7 +269,7 @@ impl VariantValueArrayBuilder {
268269

269270
/// Append a null row to the builder
270271
///
271-
/// WARNING: It is only safe to call this method when building the `value` field of a shredded
272+
/// WARNING: It is only valid to call this method when building the `value` field of a shredded
272273
/// variant column (which is nullable). The `value` field of a binary (unshredded) variant
273274
/// column is non-nullable, and callers should instead invoke [`Self::append_value`] with
274275
/// `Variant::Null`, passing the appropriate metadata value.
@@ -322,7 +323,7 @@ impl VariantValueArrayBuilder {
322323
/// object_builder.insert_bytes(field_name, field_value);
323324
/// }
324325
/// }
325-
/// object_builder.finish(); // appends the new object
326+
/// object_builder.finish(); // appends the filtered object
326327
/// ```
327328
pub fn parent_state<'a>(
328329
&'a mut self,
@@ -380,7 +381,7 @@ fn binary_view_array_from_buffers(buffer: Vec<u8>, offsets: Vec<usize>) -> Binar
380381
mod test {
381382
use super::*;
382383
use arrow::array::Array;
383-
use parquet_variant::{Variant, VariantBuilder, VariantMetadata};
384+
use parquet_variant::Variant;
384385

385386
/// Test that both the metadata and value buffers are non nullable
386387
#[test]
@@ -457,30 +458,76 @@ mod test {
457458

458459
#[test]
459460
fn test_variant_value_array_builder_with_objects() {
460-
// Create metadata with field names
461-
let mut metadata_builder = WritableMetadataBuilder::default();
462-
metadata_builder.upsert_field_name("name");
463-
metadata_builder.upsert_field_name("age");
464-
metadata_builder.finish();
465-
let metadata_bytes = metadata_builder.into_inner();
466-
let metadata = VariantMetadata::try_new(&metadata_bytes).unwrap();
467-
468-
// Create a variant with an object using the same metadata
469-
let mut variant_builder = VariantBuilder::new().with_metadata(metadata);
470-
variant_builder
461+
// Populate a variant array with objects
462+
let mut builder = VariantArrayBuilder::new(3);
463+
builder
471464
.new_object()
472465
.with_field("name", "Alice")
473466
.with_field("age", 30i32)
474467
.finish();
475-
let (_, value_bytes) = variant_builder.finish();
476-
let variant = Variant::try_new(&metadata_bytes, &value_bytes).unwrap();
477468

478-
// Now use the value array builder
479-
let mut builder = VariantValueArrayBuilder::new(10);
480-
builder.append_value(variant);
481-
builder.append_null();
469+
builder
470+
.new_object()
471+
.with_field("name", "Bob")
472+
.with_field("age", 42i32)
473+
.with_field("city", "Wonderland")
474+
.finish();
482475

483-
let value_array = builder.build().unwrap();
484-
assert_eq!(value_array.len(), 2);
476+
builder
477+
.new_object()
478+
.with_field("name", "Charlie")
479+
.with_field("age", 1i32)
480+
.finish();
481+
482+
let array = builder.build();
483+
484+
// Copy (some of) the objects over to the value array builder
485+
//
486+
// NOTE: Because we will reuse the metadata column, we cannot reorder rows. We can only
487+
// filter or manipulate values within a row.
488+
let mut builder = VariantValueArrayBuilder::new(3);
489+
490+
// straight copy
491+
builder.append_value(array.value(0));
492+
493+
// filtering fields takes more work because we need to manually create an object builder
494+
let value = array.value(1);
495+
let mut metadata_builder = ReadOnlyMetadataBuilder::new(value.metadata().unwrap().clone());
496+
let state = builder.parent_state(&mut metadata_builder);
497+
ObjectBuilder::new(state, false)
498+
.with_field("name", value.get_object_field("name").unwrap())
499+
.with_field("age", value.get_object_field("age").unwrap())
500+
.finish();
501+
502+
// same bytes, but now nested and duplicated inside a list
503+
let value = array.value(2);
504+
let mut metadata_builder = ReadOnlyMetadataBuilder::new(value.metadata().unwrap().clone());
505+
let state = builder.parent_state(&mut metadata_builder);
506+
ListBuilder::new(state, false)
507+
.with_value(value.clone())
508+
.with_value(value.clone())
509+
.finish();
510+
511+
let array2 = VariantArray::from_parts(
512+
array.metadata_field().clone(),
513+
Some(builder.build().unwrap()),
514+
None,
515+
None,
516+
);
517+
518+
assert_eq!(array2.len(), 3);
519+
assert_eq!(array.value(0), array2.value(0));
520+
521+
assert_eq!(
522+
array.value(1).get_object_field("name"),
523+
array2.value(1).get_object_field("name")
524+
);
525+
assert_eq!(
526+
array.value(1).get_object_field("age"),
527+
array2.value(1).get_object_field("age")
528+
);
529+
530+
assert_eq!(array.value(2), array2.value(2).get_list_element(0).unwrap());
531+
assert_eq!(array.value(2), array2.value(2).get_list_element(1).unwrap());
485532
}
486533
}

0 commit comments

Comments
 (0)