From 49982d180f7cfcd09b8e4f7648f2934d07e5b315 Mon Sep 17 00:00:00 2001 From: Liang-Chi Hsieh Date: Tue, 1 Jul 2025 10:56:41 -0700 Subject: [PATCH 1/7] Implement Drop for builders --- parquet-variant/src/builder.rs | 55 ++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/parquet-variant/src/builder.rs b/parquet-variant/src/builder.rs index 3a8f7af6a077..326b4114a1fc 100644 --- a/parquet-variant/src/builder.rs +++ b/parquet-variant/src/builder.rs @@ -515,6 +515,7 @@ pub struct ListBuilder<'a> { /// Is there a pending nested object or list that needs to be finalized? pending: bool, validate_unique_fields: bool, + finished: bool, } impl<'a> ListBuilder<'a> { @@ -526,6 +527,7 @@ impl<'a> ListBuilder<'a> { buffer: ValueBuffer::default(), pending: false, validate_unique_fields: false, + finished: false, } } @@ -545,11 +547,15 @@ impl<'a> ListBuilder<'a> { /// Propagates the validation flag to any [`ObjectBuilder`]s created using /// [`ListBuilder::new_object`]. pub fn with_validate_unique_fields(mut self, validate_unique_fields: bool) -> Self { + assert!(!self.finished, "ListBuilder has already been finished"); + self.validate_unique_fields = validate_unique_fields; self } pub fn new_object(&mut self) -> ObjectBuilder { + assert!(!self.finished, "ListBuilder has already been finished"); + self.check_new_offset(); let obj_builder = ObjectBuilder::new(&mut self.buffer, self.metadata_builder) @@ -560,6 +566,8 @@ impl<'a> ListBuilder<'a> { } pub fn new_list(&mut self) -> ListBuilder { + assert!(!self.finished, "ListBuilder has already been finished"); + self.check_new_offset(); let list_builder = ListBuilder::new(&mut self.buffer, self.metadata_builder) @@ -570,6 +578,8 @@ impl<'a> ListBuilder<'a> { } pub fn append_value<'m, 'd, T: Into>>(&mut self, value: T) { + assert!(!self.finished, "ListBuilder has already been finished"); + self.check_new_offset(); self.buffer.append_non_nested_value(value); @@ -578,6 +588,12 @@ impl<'a> ListBuilder<'a> { } pub fn finish(mut self) { + self._finish() + } + + fn _finish(&mut self) { + assert!(!self.finished, "ListBuilder has already been finished"); + self.check_new_offset(); let data_size = self.buffer.offset(); @@ -600,6 +616,16 @@ impl<'a> ListBuilder<'a> { // Append values self.parent_buffer.append_slice(self.buffer.inner()); + + self.finished = true; + } +} + +impl Drop for ListBuilder<'_> { + fn drop(&mut self) { + if !self.finished { + self._finish(); + } } } @@ -616,6 +642,7 @@ pub struct ObjectBuilder<'a, 'b> { validate_unique_fields: bool, /// Set of duplicate fields to report for errors duplicate_fields: HashSet, + finished: bool, } impl<'a, 'b> ObjectBuilder<'a, 'b> { @@ -628,6 +655,7 @@ impl<'a, 'b> ObjectBuilder<'a, 'b> { pending: None, validate_unique_fields: false, duplicate_fields: HashSet::new(), + finished: false, } } @@ -647,6 +675,8 @@ impl<'a, 'b> ObjectBuilder<'a, 'b> { /// Note: when inserting duplicate keys, the new value overwrites the previous mapping, /// but the old value remains in the buffer, resulting in a larger variant pub fn insert<'m, 'd, T: Into>>(&mut self, key: &str, value: T) { + assert!(!self.finished, "ObjectBuilder has already been finished"); + self.check_pending_field(); let field_id = self.metadata_builder.upsert_field_name(key); @@ -664,6 +694,8 @@ impl<'a, 'b> ObjectBuilder<'a, 'b> { /// When this is enabled, calling [`ObjectBuilder::finish`] will return an error /// if any duplicate field keys were added using [`ObjectBuilder::insert`]. pub fn with_validate_unique_fields(mut self, validate_unique_fields: bool) -> Self { + assert!(!self.finished, "ObjectBuilder has already been finished"); + self.validate_unique_fields = validate_unique_fields; self } @@ -671,6 +703,8 @@ impl<'a, 'b> ObjectBuilder<'a, 'b> { /// Return a new [`ObjectBuilder`] to add a nested object with the specified /// key to the object. pub fn new_object(&mut self, key: &'b str) -> ObjectBuilder { + assert!(!self.finished, "ObjectBuilder has already been finished"); + self.check_pending_field(); let field_start = self.buffer.offset(); @@ -684,6 +718,8 @@ impl<'a, 'b> ObjectBuilder<'a, 'b> { /// Return a new [`ListBuilder`] to add a list with the specified key to the /// object. pub fn new_list(&mut self, key: &'b str) -> ListBuilder { + assert!(!self.finished, "ObjectBuilder has already been finished"); + self.check_pending_field(); let field_start = self.buffer.offset(); @@ -698,6 +734,15 @@ impl<'a, 'b> ObjectBuilder<'a, 'b> { /// /// This consumes self and writes the object to the parent buffer. pub fn finish(mut self) -> Result<(), ArrowError> { + self._finish() + } + + /// Internal function to finalize object + /// + /// This doesn't consume self but just writes the object to the parent buffer. + fn _finish(&mut self) -> Result<(), ArrowError> { + assert!(!self.finished, "ObjectBuilder has already been finished"); + self.check_pending_field(); if self.validate_unique_fields && !self.duplicate_fields.is_empty() { @@ -752,10 +797,20 @@ impl<'a, 'b> ObjectBuilder<'a, 'b> { self.parent_buffer.append_slice(self.buffer.inner()); + self.finished = true; + Ok(()) } } +impl Drop for ObjectBuilder<'_, '_> { + fn drop(&mut self) { + if !self.finished { + self._finish().expect("Failed to finalize ObjectBuilder"); + } + } +} + #[cfg(test)] mod tests { use super::*; From dc09a483dce3f49ffcd4dc786fd44e424db65e5f Mon Sep 17 00:00:00 2001 From: Liang-Chi Hsieh Date: Tue, 1 Jul 2025 11:05:15 -0700 Subject: [PATCH 2/7] fix test --- parquet-variant/src/builder.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/parquet-variant/src/builder.rs b/parquet-variant/src/builder.rs index 326b4114a1fc..23290fec8383 100644 --- a/parquet-variant/src/builder.rs +++ b/parquet-variant/src/builder.rs @@ -755,6 +755,9 @@ impl<'a, 'b> ObjectBuilder<'a, 'b> { names.sort_unstable(); let joined = names.join(", "); + + self.finished = true; + return Err(ArrowError::InvalidArgumentError(format!( "Duplicate field keys detected: [{joined}]", ))); @@ -1507,6 +1510,9 @@ mod tests { "Invalid argument error: Duplicate field keys detected: [x]" ); + inner_list.finish(); + outer_list.finish(); + // Valid object should succeed let mut list = builder.new_list(); let mut valid_obj = list.new_object(); From 9fc30d7a69071662d3e107a1d743a45e277818e2 Mon Sep 17 00:00:00 2001 From: Liang-Chi Hsieh Date: Tue, 1 Jul 2025 11:19:23 -0700 Subject: [PATCH 3/7] Remove unnecessary checks --- parquet-variant/src/builder.rs | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/parquet-variant/src/builder.rs b/parquet-variant/src/builder.rs index 23290fec8383..f6be29627114 100644 --- a/parquet-variant/src/builder.rs +++ b/parquet-variant/src/builder.rs @@ -547,15 +547,11 @@ impl<'a> ListBuilder<'a> { /// Propagates the validation flag to any [`ObjectBuilder`]s created using /// [`ListBuilder::new_object`]. pub fn with_validate_unique_fields(mut self, validate_unique_fields: bool) -> Self { - assert!(!self.finished, "ListBuilder has already been finished"); - self.validate_unique_fields = validate_unique_fields; self } pub fn new_object(&mut self) -> ObjectBuilder { - assert!(!self.finished, "ListBuilder has already been finished"); - self.check_new_offset(); let obj_builder = ObjectBuilder::new(&mut self.buffer, self.metadata_builder) @@ -566,8 +562,6 @@ impl<'a> ListBuilder<'a> { } pub fn new_list(&mut self) -> ListBuilder { - assert!(!self.finished, "ListBuilder has already been finished"); - self.check_new_offset(); let list_builder = ListBuilder::new(&mut self.buffer, self.metadata_builder) @@ -578,8 +572,6 @@ impl<'a> ListBuilder<'a> { } pub fn append_value<'m, 'd, T: Into>>(&mut self, value: T) { - assert!(!self.finished, "ListBuilder has already been finished"); - self.check_new_offset(); self.buffer.append_non_nested_value(value); @@ -675,8 +667,6 @@ impl<'a, 'b> ObjectBuilder<'a, 'b> { /// Note: when inserting duplicate keys, the new value overwrites the previous mapping, /// but the old value remains in the buffer, resulting in a larger variant pub fn insert<'m, 'd, T: Into>>(&mut self, key: &str, value: T) { - assert!(!self.finished, "ObjectBuilder has already been finished"); - self.check_pending_field(); let field_id = self.metadata_builder.upsert_field_name(key); @@ -694,8 +684,6 @@ impl<'a, 'b> ObjectBuilder<'a, 'b> { /// When this is enabled, calling [`ObjectBuilder::finish`] will return an error /// if any duplicate field keys were added using [`ObjectBuilder::insert`]. pub fn with_validate_unique_fields(mut self, validate_unique_fields: bool) -> Self { - assert!(!self.finished, "ObjectBuilder has already been finished"); - self.validate_unique_fields = validate_unique_fields; self } @@ -703,8 +691,6 @@ impl<'a, 'b> ObjectBuilder<'a, 'b> { /// Return a new [`ObjectBuilder`] to add a nested object with the specified /// key to the object. pub fn new_object(&mut self, key: &'b str) -> ObjectBuilder { - assert!(!self.finished, "ObjectBuilder has already been finished"); - self.check_pending_field(); let field_start = self.buffer.offset(); @@ -718,8 +704,6 @@ impl<'a, 'b> ObjectBuilder<'a, 'b> { /// Return a new [`ListBuilder`] to add a list with the specified key to the /// object. pub fn new_list(&mut self, key: &'b str) -> ListBuilder { - assert!(!self.finished, "ObjectBuilder has already been finished"); - self.check_pending_field(); let field_start = self.buffer.offset(); From 198c03348db0ce4034a10a4f188571cc6e8cd4cb Mon Sep 17 00:00:00 2001 From: Andrew Lamb Date: Tue, 1 Jul 2025 16:06:42 -0400 Subject: [PATCH 4/7] Add comments and examples to clarify panic behavior on drop --- parquet-variant/src/builder.rs | 68 +++++++++++++++++++++++++++++++--- 1 file changed, 63 insertions(+), 5 deletions(-) diff --git a/parquet-variant/src/builder.rs b/parquet-variant/src/builder.rs index f6be29627114..1bf35dc28f85 100644 --- a/parquet-variant/src/builder.rs +++ b/parquet-variant/src/builder.rs @@ -395,14 +395,14 @@ impl MetadataBuilder { /// let mut object_builder = list_builder.new_object(); /// object_builder.insert("id", 1); /// object_builder.insert("type", "Cauliflower"); -/// object_builder.finish(); +/// // finish is called automatically when the builder is dropped /// } /// /// { /// let mut object_builder = list_builder.new_object(); /// object_builder.insert("id", 2); /// object_builder.insert("type", "Beets"); -/// object_builder.finish(); +/// // finish is called automatically when the builder is dropped /// } /// /// list_builder.finish(); @@ -450,6 +450,7 @@ impl MetadataBuilder { /// obj.insert("a", 1); /// obj.insert("a", 2); // duplicate field /// +/// // When validation is enabled, finish will return an error /// let result = obj.finish(); // returns Err /// assert!(result.is_err()); /// ``` @@ -474,6 +475,12 @@ impl VariantBuilder { /// This setting is propagated to all [`ObjectBuilder`]s created through this [`VariantBuilder`] /// (including via any [`ListBuilder`]), and causes [`ObjectBuilder::finish()`] to return /// an error if duplicate keys were inserted. + /// + /// # Panics + /// + /// When set to `true`, you **must** call [`ObjectBuilder::finish`] for all + /// nested builders to check for errors, otherwise those builders will + /// `panic` on `drop` if there are duplicate fields. pub fn with_validate_unique_fields(mut self, validate_unique_fields: bool) -> Self { self.validate_unique_fields = validate_unique_fields; self @@ -495,10 +502,20 @@ impl VariantBuilder { .with_validate_unique_fields(self.validate_unique_fields) } + /// Append a non-nested value to the builder. + /// + /// # Example + /// ``` + /// # use parquet_variant::{Variant, VariantBuilder}; + /// let mut builder = VariantBuilder::new(); + /// // most primitive types can be appended directly as they implement `Into` + /// builder.append_value(42i8); + /// ``` pub fn append_value<'m, 'd, T: Into>>(&mut self, value: T) { self.buffer.append_non_nested_value(value); } + /// Finish the builder and return the metadata and value buffers. pub fn finish(self) -> (Vec, Vec) { (self.metadata_builder.finish(), self.buffer.into_inner()) } @@ -546,6 +563,12 @@ impl<'a> ListBuilder<'a> { /// /// Propagates the validation flag to any [`ObjectBuilder`]s created using /// [`ListBuilder::new_object`]. + /// + /// # Panics + /// + /// When set to `true`, you **must** call [`ObjectBuilder::finish`] for + /// all nested builders to check for errors, otherwise those + /// builders will `panic` on `drop` if there are duplicate fields. pub fn with_validate_unique_fields(mut self, validate_unique_fields: bool) -> Self { self.validate_unique_fields = validate_unique_fields; self @@ -579,6 +602,7 @@ impl<'a> ListBuilder<'a> { self.offsets.push(element_end); } + /// Finish the list, writing it to the parent buffer and consuming self. pub fn finish(mut self) { self._finish() } @@ -624,6 +648,7 @@ impl Drop for ListBuilder<'_> { /// A builder for creating [`Variant::Object`] values. /// /// See the examples on [`VariantBuilder`] for usage. +/// pub struct ObjectBuilder<'a, 'b> { parent_buffer: &'a mut ValueBuffer, metadata_builder: &'a mut MetadataBuilder, @@ -683,6 +708,12 @@ impl<'a, 'b> ObjectBuilder<'a, 'b> { /// /// When this is enabled, calling [`ObjectBuilder::finish`] will return an error /// if any duplicate field keys were added using [`ObjectBuilder::insert`]. + /// + /// # Panics + /// + /// When set to `true`, you **must** call [`ObjectBuilder::finish`] for + /// `self` and all nested builders to check for errors, otherwise this + /// builder will `panic` on `drop` if there are duplicate fields. pub fn with_validate_unique_fields(mut self, validate_unique_fields: bool) -> Self { self.validate_unique_fields = validate_unique_fields; self @@ -714,9 +745,7 @@ impl<'a, 'b> ObjectBuilder<'a, 'b> { list_builder } - /// Finalize object - /// - /// This consumes self and writes the object to the parent buffer. + /// Finalize the object, writing it to the parent buffer and consuming self. pub fn finish(mut self) -> Result<(), ArrowError> { self._finish() } @@ -1506,4 +1535,33 @@ mod tests { let valid_result = valid_obj.finish(); assert!(valid_result.is_ok()); } + + #[test] + #[should_panic( + expected = "Failed to finalize ObjectBuilder: InvalidArgumentError(\"Duplicate field keys detected: [a]\")" + )] + fn test_object_drop_with_unique_field_validation() { + let mut builder = VariantBuilder::new().with_validate_unique_fields(true); + // Root-level object with duplicates + { + let mut root_obj = builder.new_object(); + root_obj.insert("a", 1); + root_obj.insert("a", 4); + // Not calling finish, should panic on drop + } + } + + #[test] + #[should_panic( + expected = "Failed to finalize ObjectBuilder: InvalidArgumentError(\"Duplicate field keys detected: [a]\")" + )] + fn test_object_drop_in_list_with_unique_field_validation() { + let mut builder = VariantBuilder::new().with_validate_unique_fields(true); + let mut list_builder = builder.new_list(); + { + let mut obj_builder = list_builder.new_object(); + obj_builder.insert("a", 1); + obj_builder.insert("a", 4); + } + } } From c2d5e70b8768e1163f87fa3abd9639833643e590 Mon Sep 17 00:00:00 2001 From: Liang-Chi Hsieh Date: Tue, 1 Jul 2025 21:53:21 -0700 Subject: [PATCH 5/7] revert --- parquet-variant/src/builder.rs | 94 +--------------------------------- 1 file changed, 2 insertions(+), 92 deletions(-) diff --git a/parquet-variant/src/builder.rs b/parquet-variant/src/builder.rs index 1bf35dc28f85..c95c837386e5 100644 --- a/parquet-variant/src/builder.rs +++ b/parquet-variant/src/builder.rs @@ -395,14 +395,14 @@ impl MetadataBuilder { /// let mut object_builder = list_builder.new_object(); /// object_builder.insert("id", 1); /// object_builder.insert("type", "Cauliflower"); -/// // finish is called automatically when the builder is dropped +/// object_builder.finish(); /// } /// /// { /// let mut object_builder = list_builder.new_object(); /// object_builder.insert("id", 2); /// object_builder.insert("type", "Beets"); -/// // finish is called automatically when the builder is dropped +/// object_builder.finish(); /// } /// /// list_builder.finish(); @@ -475,12 +475,6 @@ impl VariantBuilder { /// This setting is propagated to all [`ObjectBuilder`]s created through this [`VariantBuilder`] /// (including via any [`ListBuilder`]), and causes [`ObjectBuilder::finish()`] to return /// an error if duplicate keys were inserted. - /// - /// # Panics - /// - /// When set to `true`, you **must** call [`ObjectBuilder::finish`] for all - /// nested builders to check for errors, otherwise those builders will - /// `panic` on `drop` if there are duplicate fields. pub fn with_validate_unique_fields(mut self, validate_unique_fields: bool) -> Self { self.validate_unique_fields = validate_unique_fields; self @@ -532,7 +526,6 @@ pub struct ListBuilder<'a> { /// Is there a pending nested object or list that needs to be finalized? pending: bool, validate_unique_fields: bool, - finished: bool, } impl<'a> ListBuilder<'a> { @@ -544,7 +537,6 @@ impl<'a> ListBuilder<'a> { buffer: ValueBuffer::default(), pending: false, validate_unique_fields: false, - finished: false, } } @@ -563,12 +555,6 @@ impl<'a> ListBuilder<'a> { /// /// Propagates the validation flag to any [`ObjectBuilder`]s created using /// [`ListBuilder::new_object`]. - /// - /// # Panics - /// - /// When set to `true`, you **must** call [`ObjectBuilder::finish`] for - /// all nested builders to check for errors, otherwise those - /// builders will `panic` on `drop` if there are duplicate fields. pub fn with_validate_unique_fields(mut self, validate_unique_fields: bool) -> Self { self.validate_unique_fields = validate_unique_fields; self @@ -604,12 +590,6 @@ impl<'a> ListBuilder<'a> { /// Finish the list, writing it to the parent buffer and consuming self. pub fn finish(mut self) { - self._finish() - } - - fn _finish(&mut self) { - assert!(!self.finished, "ListBuilder has already been finished"); - self.check_new_offset(); let data_size = self.buffer.offset(); @@ -632,23 +612,12 @@ impl<'a> ListBuilder<'a> { // Append values self.parent_buffer.append_slice(self.buffer.inner()); - - self.finished = true; - } -} - -impl Drop for ListBuilder<'_> { - fn drop(&mut self) { - if !self.finished { - self._finish(); - } } } /// A builder for creating [`Variant::Object`] values. /// /// See the examples on [`VariantBuilder`] for usage. -/// pub struct ObjectBuilder<'a, 'b> { parent_buffer: &'a mut ValueBuffer, metadata_builder: &'a mut MetadataBuilder, @@ -659,7 +628,6 @@ pub struct ObjectBuilder<'a, 'b> { validate_unique_fields: bool, /// Set of duplicate fields to report for errors duplicate_fields: HashSet, - finished: bool, } impl<'a, 'b> ObjectBuilder<'a, 'b> { @@ -672,7 +640,6 @@ impl<'a, 'b> ObjectBuilder<'a, 'b> { pending: None, validate_unique_fields: false, duplicate_fields: HashSet::new(), - finished: false, } } @@ -708,12 +675,6 @@ impl<'a, 'b> ObjectBuilder<'a, 'b> { /// /// When this is enabled, calling [`ObjectBuilder::finish`] will return an error /// if any duplicate field keys were added using [`ObjectBuilder::insert`]. - /// - /// # Panics - /// - /// When set to `true`, you **must** call [`ObjectBuilder::finish`] for - /// `self` and all nested builders to check for errors, otherwise this - /// builder will `panic` on `drop` if there are duplicate fields. pub fn with_validate_unique_fields(mut self, validate_unique_fields: bool) -> Self { self.validate_unique_fields = validate_unique_fields; self @@ -747,15 +708,6 @@ impl<'a, 'b> ObjectBuilder<'a, 'b> { /// Finalize the object, writing it to the parent buffer and consuming self. pub fn finish(mut self) -> Result<(), ArrowError> { - self._finish() - } - - /// Internal function to finalize object - /// - /// This doesn't consume self but just writes the object to the parent buffer. - fn _finish(&mut self) -> Result<(), ArrowError> { - assert!(!self.finished, "ObjectBuilder has already been finished"); - self.check_pending_field(); if self.validate_unique_fields && !self.duplicate_fields.is_empty() { @@ -768,9 +720,6 @@ impl<'a, 'b> ObjectBuilder<'a, 'b> { names.sort_unstable(); let joined = names.join(", "); - - self.finished = true; - return Err(ArrowError::InvalidArgumentError(format!( "Duplicate field keys detected: [{joined}]", ))); @@ -813,20 +762,10 @@ impl<'a, 'b> ObjectBuilder<'a, 'b> { self.parent_buffer.append_slice(self.buffer.inner()); - self.finished = true; - Ok(()) } } -impl Drop for ObjectBuilder<'_, '_> { - fn drop(&mut self) { - if !self.finished { - self._finish().expect("Failed to finalize ObjectBuilder"); - } - } -} - #[cfg(test)] mod tests { use super::*; @@ -1535,33 +1474,4 @@ mod tests { let valid_result = valid_obj.finish(); assert!(valid_result.is_ok()); } - - #[test] - #[should_panic( - expected = "Failed to finalize ObjectBuilder: InvalidArgumentError(\"Duplicate field keys detected: [a]\")" - )] - fn test_object_drop_with_unique_field_validation() { - let mut builder = VariantBuilder::new().with_validate_unique_fields(true); - // Root-level object with duplicates - { - let mut root_obj = builder.new_object(); - root_obj.insert("a", 1); - root_obj.insert("a", 4); - // Not calling finish, should panic on drop - } - } - - #[test] - #[should_panic( - expected = "Failed to finalize ObjectBuilder: InvalidArgumentError(\"Duplicate field keys detected: [a]\")" - )] - fn test_object_drop_in_list_with_unique_field_validation() { - let mut builder = VariantBuilder::new().with_validate_unique_fields(true); - let mut list_builder = builder.new_list(); - { - let mut obj_builder = list_builder.new_object(); - obj_builder.insert("a", 1); - obj_builder.insert("a", 4); - } - } } From d6b28319b358d25d6a5f6b0fa6b3ecabb469c430 Mon Sep 17 00:00:00 2001 From: Liang-Chi Hsieh Date: Tue, 1 Jul 2025 22:17:29 -0700 Subject: [PATCH 6/7] Add empty Drop impl --- parquet-variant/src/builder.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/parquet-variant/src/builder.rs b/parquet-variant/src/builder.rs index c95c837386e5..b8797cef801e 100644 --- a/parquet-variant/src/builder.rs +++ b/parquet-variant/src/builder.rs @@ -615,6 +615,14 @@ impl<'a> ListBuilder<'a> { } } +/// Drop implementation for ListBuilder does nothing +/// as the `finish` method must be called to finalize the list. +/// This is to ensure that the list is always finalized before its parent builder +/// is finalized. +impl Drop for ListBuilder<'_> { + fn drop(&mut self) {} +} + /// A builder for creating [`Variant::Object`] values. /// /// See the examples on [`VariantBuilder`] for usage. @@ -766,6 +774,14 @@ impl<'a, 'b> ObjectBuilder<'a, 'b> { } } +/// Drop implementation for ObjectBuilder does nothing +/// as the `finish` method must be called to finalize the object. +/// This is to ensure that the object is always finalized before its parent builder +/// is finalized. +impl Drop for ObjectBuilder<'_, '_> { + fn drop(&mut self) {} +} + #[cfg(test)] mod tests { use super::*; From 933eb73e18e729d72d8672c4b881d91669f93c55 Mon Sep 17 00:00:00 2001 From: Liang-Chi Hsieh Date: Thu, 3 Jul 2025 16:47:27 -0700 Subject: [PATCH 7/7] Fix lint error --- parquet-variant/src/builder.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/parquet-variant/src/builder.rs b/parquet-variant/src/builder.rs index de634d8f47c5..cb3a373cb832 100644 --- a/parquet-variant/src/builder.rs +++ b/parquet-variant/src/builder.rs @@ -774,7 +774,6 @@ impl<'a, 'b> ObjectBuilder<'a, 'b> { } } - /// Drop implementation for ObjectBuilder does nothing /// as the `finish` method must be called to finalize the object. /// This is to ensure that the object is always finalized before its parent builder