Skip to content

Navigation Menu

Sign in
Sign up

fix: track batch position delete references - #842

Open
u70b3 wants to merge 3 commits into
apache:main from
u70b3:fix-position-delete-batch-metadata
Open

fix: track batch position delete references #842
u70b3 wants to merge 3 commits into
apache:main from
u70b3:fix-position-delete-batch-metadata

Conversation

@u70b3

@u70b3 u70b3 commented Jul 24, 2026
edited
Loading

Copy link
Copy Markdown

Summary

  • collect referenced data-file paths when writing position deletes as an Arrow batch
  • update referenced-path metadata only after the underlying write succeeds
  • reject null batch inputs, null file paths, and sliced (non-zero offset) batches
  • cover single-file, multi-file, mixed, empty, invalid, and failed-then-successful batches

Testing

  • pre-commit run --files src/iceberg/data/position_delete_writer.cc src/iceberg/test/data_writer_test.cc
  • build-gcc14/src/iceberg/test/data_test (159 tests passed)
  • git diff --check

u70b3 added 3 commits July 24, 2026 13:02
Take ownership before validation so early-return paths honor the FileWriter contract and do not leak Arrow buffers. Assert that rejected sliced and null-path batches are released.

u70b3 commented Aug 11, 2026

Copy link
Copy Markdown
Author

Hi @wgtmac, gentle ping for a review when you have a moment. This has been sitting for about two weeks; all CI checks are green and it merges cleanly against the latest main. The change tracks referenced data-file paths for batch position-delete writes so referenced_data_file and bounds metadata match the WriteDelete path, and hardens ownership/validation for rejected batches. Thanks!

Copy link
Copy Markdown

This pull request has been marked as stale due to 30 days of inactivity. It will be closed in 1 week if no further activity occurs. If you think that’s incorrect or this pull request requires a review, please simply write any comment. If closed, you can revive the PR at any time and @mention a reviewer or discuss it on the dev@iceberg.apache.org list. Thank you for your contributions.

@wgtmac wgtmac left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @u70b3 for fixing this and sorry for the delay! I have left some comments.

ArrowArrayViewSetArray(&array_view, data, &error), error);

const auto* path_view = array_view.children[0];
if (ArrowArrayViewComputeNullCount(path_view) != 0) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ArrowArrayViewComputeNullCount(path_view) scans the child view length, not necessarily the parent batch length. Please check it only for i less than data->length, and apply the same check to pos field.

// TODO(anyone): Extract file paths from ArrowArray to update referenced_paths_.
return writer_->Write(data);

ArrowSchema arrow_schema;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Every Write rebuilds the same schema and allocates a fresh ArrowArrayView. The schema is immutable for this writer, so this adds allocator work to every batch. Perhaps we can initialize the schema and view once in Impl and only rebind the incoming array here.

return InvalidArrowData("Position delete file paths must not contain null values");
}

std::set<std::string> pending_paths;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pending_paths allocates a tree node and copies each unique path for every batch, then merges into another set. Batch writes can be frequent so a reusable scratch set or a vector plus post-write insertion would avoid much of this churn while keeping the failure-safe delayed merge.

EXPECT_EQ(data_file->referenced_data_file.value(), "data_file_1.parquet");
}

TEST_F(PositionDeleteWriterTest, WriteBatchDataForMultipleFiles) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is one batch containing two paths, not multiple successful Write calls. A bug that replaces referenced_paths_ instead of unioning across batches would still pass. Add two successful batches with disjoint paths.

ArrowArray bad_array;
ASSERT_TRUE(::arrow::ExportArray(*bad_data, &bad_array).ok());
internal::ArrowArrayGuard bad_array_guard(&bad_array);
ASSERT_THAT(writer->Write(&bad_array), IsError(ErrorKind::kInvalidArrowData));

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks odd to me because we continue to use a failed writer which should not happen in production. And this does actually verify the case name FailedBatchWriteDoesNotTrackReferencedFiles.


auto metadata_result = writer->Metadata();
ASSERT_THAT(metadata_result, IsOk());
EXPECT_FALSE(metadata_result.value().data_files[0]->referenced_data_file.has_value());

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This only checks the per-file hint. WriteResult also exposes referenced_data_files; assert that public result as well if this writer is meant to satisfy the FileWriter contract.

HasErrorMessage("Position delete file paths must not contain null values"));
}

TEST_F(PositionDeleteWriterTest, WriteBatchRejectsNullData) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This only exercises a one-line null precondition and does not touch batch paths or metadata. It is low-value so please consider dropping it or folding it into a broader invalid-input test.

std::set<std::string> pending_paths;
for (int64_t i = 0; i < data->length; ++i) {
auto path = ArrowArrayViewGetStringUnsafe(path_view, i);
if (path.size_bytes == 0) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we error out in this case?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

@wgtmac wgtmac wgtmac requested changes

Requested changes must be addressed to merge this pull request.

Assignees

No one assigned

Labels

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

2 participants

AltStyle によって変換されたページ (->オリジナル) /