Skip to content

fix(manifest): preserve snapshot ID inheritance semantics - #947

Merged
wgtmac merged 2 commits into
apache:mainfrom
wgtmac:fix_snapshot_id_inheritance
Sep 20, 2026
Merged

wgtmac merged 2 commits into
apache:mainfrom
wgtmac:fix_snapshot_id_inheritance

Conversation

@wgtmac

@wgtmac wgtmac commented Sep 20, 2026

Copy link
Copy Markdown
Member

Purpose

C++ converted an unassigned manifest snapshot ID from null to -1.
This made inheritance-ready manifests indistinguishable from manifests
containing a literal -1.

As a result, FastAppend and MergeAppend could directly reuse a manifest
with explicit -1 entry snapshot IDs instead of rewriting those entries
with the new commit snapshot ID.

Changes

  • Change ManifestFile::added_snapshot_id to std::optional<int64_t>.
  • Preserve null from ManifestWriter::ToManifestFile.
  • Directly reuse manifests only when added_snapshot_id is null.
  • Copy manifests with an explicit -1 and assign the commit snapshot ID.
  • Continue requiring added_snapshot_id when writing manifest lists.
  • Update committed-manifest consumers to handle the optional in-memory field.
  • Add FastAppend and MergeAppend coverage for null inheritance and explicit -1.

Represent ManifestFile::added_snapshot_id as optional to distinguish an
inheritance-ready null ID from a literal -1.

Reuse manifests only when the ID is null, rewrite explicit -1 manifests
with the commit snapshot ID, and continue requiring the field when
writing manifest lists.
Copilot AI lite review requested due to automatic review settings September 20, 2026 03:56

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Copilot review overview

🟢 Approval recommended

No unresolved review comments remain, and targeted test coverage is included.

Review effort: Lite
Findings: None

What changed in this PR

Preserves the distinction between unassigned (null) and explicit -1 manifest snapshot IDs.

Changes:

  • Uses std::optional<int64_t> for manifest snapshot IDs.
  • Rewrites explicit -1 manifests while reusing only null-ID manifests.
  • Updates consumers, serialization, scanning, cleanup, and test coverage.
File Summary
src/​iceberg/​update/​snapshot_update.cc Updates commit-time metadata handling.
src/​iceberg/​update/​merging_snapshot_update.cc Applies inheritance-aware append behavior.
src/​iceberg/​update/​merge_append.cc Handles null and explicit -1 IDs.
src/​iceberg/​update/​fast_append.cc Rewrites explicit -1 manifests.
src/​iceberg/​update/​expire_snapshots.cc Validates optional IDs during cleanup.
src/​iceberg/​test/​merging_snapshot_update_test.cc Updates inheritance fixtures.
src/​iceberg/​test/​merge_append_test.cc Tests inheritance and explicit -1 copying.
src/​iceberg/​test/​manifest_list_versions_test.cc Tests rejection of unassigned IDs.
src/​iceberg/​test/​fast_append_test.cc Tests inheritance and copying behavior.
src/​iceberg/​table_scan.cc Handles optional IDs during scans.
src/​iceberg/​row/​manifest_wrapper.cc Exposes optional snapshot IDs.
src/​iceberg/​manifest/​v3_metadata.cc Handles optional IDs for V3 metadata.
src/​iceberg/​manifest/​v2_metadata.cc Handles optional IDs for V2 metadata.
src/​iceberg/​manifest/​manifest_writer.h Documents nullable ID semantics.
src/​iceberg/​manifest/​manifest_writer.cc Preserves null IDs.
src/​iceberg/​manifest/​manifest_merge_manager.cc Updates merge and replacement accounting.
src/​iceberg/​manifest/​manifest_list.h Makes snapshot IDs optional.
src/​iceberg/​manifest/​manifest_adapter.cc Rejects null IDs during serialization.
src/​iceberg/​inheritable_metadata.cc Validates assigned IDs for reading.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@zhjwpku zhjwpku left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I checked the Java FastAppend impl [0]. It reuses the original manifest only when canInheritSnapshotId() && snapshotId() == null. For an explicit -1, it rewrites the manifest. These changes align the C++ behavior with Java, thanks.

+1

[0] https://github.com/apache/iceberg/blob/main/core/src/main/java/org/apache/iceberg/FastAppend.java#L120-L127

Copilot AI review requested due to automatic review settings September 20, 2026 08:25

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Copilot review overview

🟢 Approval recommended

No blocking issues were identified.

Review effort: Lite
Findings: None

@wgtmac
wgtmac merged commit 168cb52 into apache:main Sep 20, 2026
15 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants