Skip to content

Commit d221034

Browse files
committed
fix: address PR #780 review comments
- Rename row_builder_internal.cc → arrow_row_builder.cc (no _internal suffix) - Move files from inspect/ to core level; rename to arrow_row_builder* - Merge NanoarrowArrayBuilder into ArrowRowBuilder as a single RAII class - Add Make(const ArrowSchema*) overload for low-level callers - Add ArrowArrayGuard::Release() and guard InitFromSchema in Make() - Move test to arrow_row_builder_test.cc in data_test target
1 parent b42f0da commit d221034

7 files changed

Lines changed: 62 additions & 45 deletions

File tree

src/iceberg/CMakeLists.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,9 @@
1818
set(ICEBERG_INCLUDES "$<BUILD_INTERFACE:${PROJECT_BINARY_DIR}/src>"
1919
"$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/src>")
2020
set(ICEBERG_SOURCES
21-
arrow_c_data_util.cc
2221
arrow_c_data_guard_internal.cc
22+
arrow_c_data_util.cc
23+
arrow_row_builder.cc
2324
catalog/memory/in_memory_catalog.cc
2425
catalog/session_catalog.cc
2526
catalog/session_context.cc
@@ -45,7 +46,6 @@ set(ICEBERG_SOURCES
4546
file_writer.cc
4647
inspect/history_table.cc
4748
inspect/metadata_table.cc
48-
inspect/row_builder_internal.cc
4949
inspect/snapshots_table.cc
5050
inheritable_metadata.cc
5151
json_serde.cc

src/iceberg/arrow_c_data_guard_internal.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,12 @@ class ICEBERG_EXPORT ArrowArrayGuard {
3131
explicit ArrowArrayGuard(ArrowArray* array) : array_(array) {}
3232
~ArrowArrayGuard();
3333

34+
/// \brief Release the guard without calling ArrowArrayRelease.
35+
///
36+
/// Call this when ownership of the underlying ArrowArray has been
37+
/// transferred elsewhere and the guard should not release it.
38+
void Release() { array_ = nullptr; }
39+
3440
private:
3541
ArrowArray* array_;
3642
};

src/iceberg/inspect/row_builder_internal.cc renamed to src/iceberg/arrow_row_builder.cc

Lines changed: 28 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,13 @@
1717
* under the License.
1818
*/
1919

20-
#include "iceberg/inspect/row_builder_internal.h"
21-
2220
#include <utility>
2321

2422
#include <nanoarrow/nanoarrow.h>
2523

2624
#include "iceberg/arrow/nanoarrow_status_internal.h"
2725
#include "iceberg/arrow_c_data_guard_internal.h"
26+
#include "iceberg/arrow_row_builder_internal.h"
2827
#include "iceberg/schema.h"
2928
#include "iceberg/schema_internal.h"
3029

@@ -34,60 +33,64 @@ Result<ArrowRowBuilder> ArrowRowBuilder::Make(const Schema& schema) {
3433
ArrowSchema arrow_schema;
3534
ICEBERG_RETURN_UNEXPECTED(ToArrowSchema(schema, &arrow_schema));
3635
internal::ArrowSchemaGuard schema_guard(&arrow_schema);
36+
return Make(&arrow_schema);
37+
}
3738

38-
auto array = std::make_unique<ArrowArray>();
39+
Result<ArrowRowBuilder> ArrowRowBuilder::Make(const ArrowSchema* schema) {
40+
ArrowRowBuilder builder;
3941
ArrowError error;
4042
ICEBERG_NANOARROW_RETURN_UNEXPECTED_WITH_ERROR(
41-
ArrowArrayInitFromSchema(array.get(), &arrow_schema, &error), error);
42-
ICEBERG_NANOARROW_RETURN_UNEXPECTED(ArrowArrayStartAppending(array.get()));
43-
44-
return ArrowRowBuilder(std::move(array));
43+
ArrowArrayInitFromSchema(&builder.array_, schema, &error), error);
44+
// Guard the array in case StartAppending fails.
45+
internal::ArrowArrayGuard guard(&builder.array_);
46+
ICEBERG_NANOARROW_RETURN_UNEXPECTED(ArrowArrayStartAppending(&builder.array_));
47+
// Ownership stays with the builder — disarm the guard.
48+
guard.Release();
49+
return builder;
4550
}
4651

47-
ArrowRowBuilder::ArrowRowBuilder(std::unique_ptr<ArrowArray>&& array) noexcept
48-
: array_(std::move(array)) {}
49-
5052
ArrowRowBuilder::ArrowRowBuilder(ArrowRowBuilder&& other) noexcept
51-
: array_(std::move(other.array_)) {}
53+
: array_(other.array_) {
54+
other.array_.release = nullptr;
55+
}
5256

5357
ArrowRowBuilder& ArrowRowBuilder::operator=(ArrowRowBuilder&& other) noexcept {
5458
if (this != &other) {
55-
if (array_ != nullptr && array_->release != nullptr) {
56-
ArrowArrayRelease(array_.get());
59+
if (array_.release != nullptr) {
60+
ArrowArrayRelease(&array_);
5761
}
58-
array_ = std::move(other.array_);
62+
array_ = other.array_;
63+
other.array_.release = nullptr;
5964
}
6065
return *this;
6166
}
6267

6368
ArrowRowBuilder::~ArrowRowBuilder() {
64-
if (array_ != nullptr && array_->release != nullptr) {
65-
ArrowArrayRelease(array_.get());
69+
if (array_.release != nullptr) {
70+
ArrowArrayRelease(&array_);
6671
}
6772
}
6873

69-
int64_t ArrowRowBuilder::num_columns() const {
70-
return array_ == nullptr ? 0 : array_->n_children;
71-
}
74+
int64_t ArrowRowBuilder::num_columns() const { return array_.n_children; }
7275

7376
ArrowArray* ArrowRowBuilder::column(int64_t index) {
74-
if (array_ == nullptr || index < 0 || index >= array_->n_children) {
77+
if (index < 0 || index >= array_.n_children) {
7578
return nullptr;
7679
}
77-
return array_->children[index];
80+
return array_.children[index];
7881
}
7982

8083
Status ArrowRowBuilder::FinishRow() {
81-
ICEBERG_NANOARROW_RETURN_UNEXPECTED(ArrowArrayFinishElement(array_.get()));
84+
ICEBERG_NANOARROW_RETURN_UNEXPECTED(ArrowArrayFinishElement(&array_));
8285
return {};
8386
}
8487

8588
Result<ArrowArray> ArrowRowBuilder::Finish() && {
8689
ArrowError error;
8790
ICEBERG_NANOARROW_RETURN_UNEXPECTED_WITH_ERROR(
88-
ArrowArrayFinishBuildingDefault(array_.get(), &error), error);
89-
ArrowArray result = *array_;
90-
array_->release = nullptr;
91+
ArrowArrayFinishBuildingDefault(&array_, &error), error);
92+
ArrowArray result = array_;
93+
array_.release = nullptr;
9194
return result;
9295
}
9396

src/iceberg/inspect/row_builder_internal.h renamed to src/iceberg/arrow_row_builder_internal.h

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,13 @@
1919

2020
#pragma once
2121

22-
/// \file iceberg/inspect/row_builder_internal.h
22+
/// \file iceberg/arrow_row_builder_internal.h
2323
/// Internal Arrow row-building utilities shared by metadata tables.
2424
///
2525
/// Metadata tables (snapshots, history, manifests, ...) materialize in-memory
2626
/// structures into Arrow batches that conform to the table's Iceberg schema.
2727
/// `ArrowRowBuilder` wraps a nanoarrow `ArrowArray` initialized from such a
28-
/// schema and exposes per-column builders plus typed append helpers so each
28+
/// schema and exposes per-column access plus typed append helpers so each
2929
/// metadata table can emit rows without re-implementing the nanoarrow
3030
/// boilerplate.
3131

@@ -41,7 +41,15 @@
4141

4242
namespace iceberg {
4343

44-
/// \brief Builds an Arrow struct array (a batch) for an arbitrary Iceberg schema.
44+
/// \brief Movable RAII builder that materializes rows into an Arrow struct array.
45+
///
46+
/// Handles the nanoarrow lifecycle: InitFromSchema → StartAppending →
47+
/// ... append values ... → FinishBuilding → Release.
48+
///
49+
/// Two constructors:
50+
/// - `Make(schema)` accepts an Iceberg Schema (typical for metadata tables).
51+
/// - `Make(arrow_schema)` accepts a raw ArrowSchema (for lower-level callers
52+
/// like position_delete_writer or manifest_adapter).
4553
///
4654
/// Typical usage:
4755
/// \code
@@ -55,9 +63,15 @@ namespace iceberg {
5563
/// \endcode
5664
class ICEBERG_EXPORT ArrowRowBuilder {
5765
public:
58-
/// \brief Create a row builder for the given Iceberg schema.
66+
/// \brief Create a row builder from an Iceberg schema.
5967
static Result<ArrowRowBuilder> Make(const Schema& schema);
6068

69+
/// \brief Create a row builder from an ArrowSchema.
70+
///
71+
/// The schema must outlive this call (the caller guards it). On failure the
72+
/// partially-initialized array is released automatically.
73+
static Result<ArrowRowBuilder> Make(const ArrowSchema* schema);
74+
6175
ArrowRowBuilder(ArrowRowBuilder&& other) noexcept;
6276
ArrowRowBuilder& operator=(ArrowRowBuilder&& other) noexcept;
6377

@@ -85,9 +99,8 @@ class ICEBERG_EXPORT ArrowRowBuilder {
8599
Result<ArrowArray> Finish() &&;
86100

87101
private:
88-
explicit ArrowRowBuilder(std::unique_ptr<ArrowArray>&& array) noexcept;
89-
90-
std::unique_ptr<ArrowArray> array_;
102+
ArrowRowBuilder() = default;
103+
ArrowArray array_{};
91104
};
92105

93106
/// \brief Append a null to a nanoarrow array builder.

src/iceberg/meson.build

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ iceberg_include_dir = include_directories('..')
4545
iceberg_sources = files(
4646
'arrow_c_data_guard_internal.cc',
4747
'arrow_c_data_util.cc',
48+
'arrow_row_builder.cc',
4849
'catalog/memory/in_memory_catalog.cc',
4950
'catalog/session_catalog.cc',
5051
'catalog/session_context.cc',
@@ -71,7 +72,6 @@ iceberg_sources = files(
7172
'inheritable_metadata.cc',
7273
'inspect/history_table.cc',
7374
'inspect/metadata_table.cc',
74-
'inspect/row_builder_internal.cc',
7575
'inspect/snapshots_table.cc',
7676
'json_serde.cc',
7777
'location_provider.cc',

src/iceberg/test/CMakeLists.txt

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,7 @@ set(INSTALL_GTEST
2424
fetchcontent_declare(googletest
2525
GIT_REPOSITORY https://github.com/google/googletest.git
2626
GIT_TAG b514bdc898e2951020cbdca1304b75f5950d1f59 # release-1.15.2
27-
FIND_PACKAGE_ARGS
28-
NAMES
29-
GTest)
27+
FIND_PACKAGE_ARGS NAMES GTest)
3028

3129
fetchcontent_makeavailable(googletest)
3230

@@ -184,11 +182,7 @@ if(ICEBERG_BUILD_BUNDLE)
184182

185183
add_iceberg_test(catalog_test USE_BUNDLE SOURCES in_memory_catalog_test.cc)
186184

187-
add_iceberg_test(metadata_table_test
188-
USE_BUNDLE
189-
SOURCES
190-
metadata_table_test.cc
191-
row_builder_test.cc)
185+
add_iceberg_test(metadata_table_test USE_BUNDLE SOURCES metadata_table_test.cc)
192186

193187
add_iceberg_test(eval_expr_test
194188
USE_BUNDLE
@@ -249,6 +243,7 @@ if(ICEBERG_BUILD_BUNDLE)
249243
USE_BUNDLE
250244
SOURCES
251245
arrow_c_data_util_test.cc
246+
arrow_row_builder_test.cc
252247
data_writer_test.cc
253248
delete_filter_test.cc
254249
delete_loader_test.cc

src/iceberg/test/row_builder_test.cc renamed to src/iceberg/test/arrow_row_builder_test.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
* under the License.
1818
*/
1919

20-
/// \file row_builder_test.cc
20+
/// \file arrow_row_builder_test.cc
2121
/// Unit tests for ArrowRowBuilder and its typed append helpers.
2222

2323
#include <memory>
@@ -28,7 +28,7 @@
2828
#include <arrow/record_batch.h>
2929
#include <gtest/gtest.h>
3030

31-
#include "iceberg/inspect/row_builder_internal.h"
31+
#include "iceberg/arrow_row_builder_internal.h"
3232
#include "iceberg/schema.h"
3333
#include "iceberg/schema_field.h"
3434
#include "iceberg/schema_internal.h"

0 commit comments

Comments
 (0)