Skip to content

Commit b82b9ba

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 b82b9ba

7 files changed

Lines changed: 61 additions & 38 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 & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
* under the License.
1818
*/
1919

20-
#include "iceberg/inspect/row_builder_internal.h"
20+
#include "iceberg/arrow_row_builder_internal.h"
2121

2222
#include <utility>
2323

@@ -34,60 +34,64 @@ Result<ArrowRowBuilder> ArrowRowBuilder::Make(const Schema& schema) {
3434
ArrowSchema arrow_schema;
3535
ICEBERG_RETURN_UNEXPECTED(ToArrowSchema(schema, &arrow_schema));
3636
internal::ArrowSchemaGuard schema_guard(&arrow_schema);
37+
return Make(&arrow_schema);
38+
}
3739

38-
auto array = std::make_unique<ArrowArray>();
40+
Result<ArrowRowBuilder> ArrowRowBuilder::Make(const ArrowSchema* schema) {
41+
ArrowRowBuilder builder;
3942
ArrowError error;
4043
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));
44+
ArrowArrayInitFromSchema(&builder.array_, schema, &error), error);
45+
// Guard the array in case StartAppending fails.
46+
internal::ArrowArrayGuard guard(&builder.array_);
47+
ICEBERG_NANOARROW_RETURN_UNEXPECTED(ArrowArrayStartAppending(&builder.array_));
48+
// Ownership stays with the builder — disarm the guard.
49+
guard.Release();
50+
return builder;
4551
}
4652

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

5358
ArrowRowBuilder& ArrowRowBuilder::operator=(ArrowRowBuilder&& other) noexcept {
5459
if (this != &other) {
55-
if (array_ != nullptr && array_->release != nullptr) {
56-
ArrowArrayRelease(array_.get());
60+
if (array_.release != nullptr) {
61+
ArrowArrayRelease(&array_);
5762
}
58-
array_ = std::move(other.array_);
63+
array_ = other.array_;
64+
other.array_.release = nullptr;
5965
}
6066
return *this;
6167
}
6268

6369
ArrowRowBuilder::~ArrowRowBuilder() {
64-
if (array_ != nullptr && array_->release != nullptr) {
65-
ArrowArrayRelease(array_.get());
70+
if (array_.release != nullptr) {
71+
ArrowArrayRelease(&array_);
6672
}
6773
}
6874

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

7377
ArrowArray* ArrowRowBuilder::column(int64_t index) {
74-
if (array_ == nullptr || index < 0 || index >= array_->n_children) {
78+
if (index < 0 || index >= array_.n_children) {
7579
return nullptr;
7680
}
77-
return array_->children[index];
81+
return array_.children[index];
7882
}
7983

8084
Status ArrowRowBuilder::FinishRow() {
81-
ICEBERG_NANOARROW_RETURN_UNEXPECTED(ArrowArrayFinishElement(array_.get()));
85+
ICEBERG_NANOARROW_RETURN_UNEXPECTED(ArrowArrayFinishElement(&array_));
8286
return {};
8387
}
8488

8589
Result<ArrowArray> ArrowRowBuilder::Finish() && {
8690
ArrowError error;
8791
ICEBERG_NANOARROW_RETURN_UNEXPECTED_WITH_ERROR(
88-
ArrowArrayFinishBuildingDefault(array_.get(), &error), error);
89-
ArrowArray result = *array_;
90-
array_->release = nullptr;
92+
ArrowArrayFinishBuildingDefault(&array_, &error), error);
93+
ArrowArray result = array_;
94+
array_.release = nullptr;
9195
return result;
9296
}
9397

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
@@ -71,7 +71,7 @@ iceberg_sources = files(
7171
'inheritable_metadata.cc',
7272
'inspect/history_table.cc',
7373
'inspect/metadata_table.cc',
74-
'inspect/row_builder_internal.cc',
74+
'arrow_row_builder.cc',
7575
'inspect/snapshots_table.cc',
7676
'json_serde.cc',
7777
'location_provider.cc',

src/iceberg/test/CMakeLists.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -187,8 +187,7 @@ if(ICEBERG_BUILD_BUNDLE)
187187
add_iceberg_test(metadata_table_test
188188
USE_BUNDLE
189189
SOURCES
190-
metadata_table_test.cc
191-
row_builder_test.cc)
190+
metadata_table_test.cc)
192191

193192
add_iceberg_test(eval_expr_test
194193
USE_BUNDLE
@@ -249,6 +248,7 @@ if(ICEBERG_BUILD_BUNDLE)
249248
USE_BUNDLE
250249
SOURCES
251250
arrow_c_data_util_test.cc
251+
arrow_row_builder_test.cc
252252
data_writer_test.cc
253253
delete_filter_test.cc
254254
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)