Skip to content

feat: add rewrite manifests - #774

Open
zhjwpku wants to merge 3 commits into
apache:mainfrom
zhjwpku:support_rewrite_manifests
Open

zhjwpku wants to merge 3 commits into
apache:mainfrom
zhjwpku:support_rewrite_manifests

Conversation

@zhjwpku

@zhjwpku zhjwpku commented Jun 23, 2026

Copy link
Copy Markdown
Collaborator

No description provided.

@zhjwpku
zhjwpku force-pushed the support_rewrite_manifests branch 7 times, most recently from 18bade1 to 7de6949 Compare June 28, 2026 06:40
@zhjwpku
zhjwpku marked this pull request as ready for review June 28, 2026 06:42
@zhjwpku
zhjwpku force-pushed the support_rewrite_manifests branch 2 times, most recently from 5c1ee1f to dd9c7e6 Compare July 1, 2026 16:56
Comment thread src/iceberg/update/rewrite_manifests.cc Outdated
Comment thread src/iceberg/update/rewrite_manifests.cc Outdated
@zhjwpku
zhjwpku force-pushed the support_rewrite_manifests branch from dd9c7e6 to 3736bc1 Compare July 4, 2026 16:01
Comment thread src/iceberg/update/rewrite_manifests.cc Outdated
@manuzhang manuzhang added this to the 0.4.0 milestone Jul 21, 2026
@zhjwpku
zhjwpku force-pushed the support_rewrite_manifests branch from 3736bc1 to ecc0058 Compare July 24, 2026 09:19
/// snapshot and reattempting the commit.
class ICEBERG_EXPORT RewriteManifests : public SnapshotUpdate {
public:
using ClusterByFunc = std::function<std::string(const DataFile&)>;

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.

Why this function returns string instead of size_t just like what C++ hash function does?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

I think a hash could merge distinct keys on collisions(though little chance). Java accepts an Object key, so I used string here.

Comment thread src/iceberg/update/rewrite_manifests.h Outdated
Comment thread src/iceberg/update/rewrite_manifests.cc Outdated
return *this;
}

Status RewriteManifests::ValidateTargetBranch(const std::string& branch) const {

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.

Why do we need this? I didn't find this in the Java code.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

This preserves Java's behavior: SnapshotUpdate.toBranch() defaults to throwing UnsupportedOperationException, and BaseRewriteManifests does not override it. Since the C++ base class provides a shared ToBranch implementation, RewriteManifests needs this check to preserve that restriction

Comment thread src/iceberg/update/rewrite_manifests.cc Outdated
Comment thread src/iceberg/update/pending_update.cc Outdated
Comment thread src/iceberg/update/snapshot_update.h Outdated
return self.AddError(ErrorKind::kInvalidArgument, "Branch name cannot be empty");
}

if (auto status = static_cast<SnapshotUpdate&>(self).ValidateTargetBranch(branch);

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.

Why do we need this?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

This hook lets derived snapshot updates validate branch support while reusing ToBranch. RewriteManifests uses it to preserve Java's unsupported-branch behavior.

Comment thread src/iceberg/update/rewrite_manifests.cc
Comment thread src/iceberg/update/rewrite_manifests.cc Outdated
Comment thread src/iceberg/update/rewrite_manifests.cc Outdated

@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.

These comments are about the standalone update lifecycle:

  • Registration must be mandatory so commit retries reapply the update.
  • The temporary transaction must stay detached so its expired weak pointer does not break a later Commit().
  • No-op commits must still call Finalize() because cleanup is now delegated to Transaction.

Together, these keep one ownership, retry, and finalization path for standalone and explicit transactions.

Comment thread src/iceberg/update/pending_update.cc Outdated
Comment thread src/iceberg/update/pending_update.cc Outdated
Comment thread src/iceberg/update/pending_update.cc Outdated
@zhjwpku

zhjwpku commented Aug 2, 2026

Copy link
Copy Markdown
Collaborator Author

These comments are about the standalone update lifecycle:

  • Registration must be mandatory so commit retries reapply the update.
  • The temporary transaction must stay detached so its expired weak pointer does not break a later Commit().
  • No-op commits must still call Finalize() because cleanup is now delegated to Transaction.

Together, these keep one ownership, retry, and finalization path for standalone and explicit transactions.

I think this standalone update lifecycle logic deserves a dedicated PR, so I do that in #868, please take a look

@github-actions

github-actions Bot commented Sep 2, 2026

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.

@github-actions github-actions Bot added the stale label Sep 2, 2026
@github-actions

Copy link
Copy Markdown

This pull request has been closed due to lack of activity. This is not a judgement on the merit of the PR in any way. It is just a way of keeping the PR queue manageable. If you think that is incorrect, or the pull request requires review, you can revive the PR at any time.

@manuzhang

Copy link
Copy Markdown
Member

@zhjwpku could you please revive this PR?

@zhjwpku

zhjwpku commented Oct 10, 2026

Copy link
Copy Markdown
Collaborator Author

@zhjwpku could you please revive this PR?

OK, I plan to work on this tomorrow, thanks for the reminder :)

@zhjwpku
zhjwpku force-pushed the support_rewrite_manifests branch from d8fd08b to d83d0a8 Compare October 11, 2026 09:31
@zhjwpku
zhjwpku requested review from manuzhang and wgtmac October 12, 2026 00:45
return writer->ToManifestFile();
}

Result<ManifestFile> CopyRewriteManifest(

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 has duplicate logic with CopyAddendManifest. It'd better to be put into a common helper.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

I took a closer look at CopyAppendManifest. The implementations are similar, but their parameters and behavior differ, I don't see a clean way to extract a common helper :(

Status ValidateTargetBranch(const std::string& branch) const override;

private:
std::string table_name_;

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.

where is this used?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

This follows the existing pattern: several update operations retain this field without using it. We could revisit these fields together in a follow-up PR.

Comment thread src/iceberg/update/rewrite_manifests.cc Outdated
ICEBERG_BUILDER_CHECK(manifest.sequence_number == kInvalidSequenceNumber,
"Sequence number must be assigned during commit");

if (can_inherit_snapshot_id()) {

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.

We need to check !manifest.added_snapshot_id.has_value() here as well.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Agreed, Java impl does this, will fix.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Fixed.

return summary_.Build();
}

void RewriteManifests::SetSummaryProperty(const std::string& property,

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 might be worth moving to SnapshotUpdate as a follow-up.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Will create a follow-up PR once this got merged.

}

Result<std::vector<ManifestEntry>> ReadManifestEntries(const ManifestFile& manifest) {
return ReadManifestEntries(std::span<const ManifestFile>(&manifest, 1));

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.

Might be worth replacing duplicates in fast_apend_test.cc with this as a follow-up.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Agreed. Reusing these helpers in fast_append_test.cc would be a useful follow-up cleanup, will do.

Comment thread src/iceberg/update/rewrite_manifests.h Outdated
/// If manifest entries are allowed to inherit the snapshot ID assigned on
/// commit, the manifest should never be deleted manually if the commit succeeds
/// as it will become part of the table metadata and will be cleaned up on
/// expiry. If the manifest gets merged with others while preparing a new

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.

Manifests are neither merged nor deleted in AddManifest.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Updated the docs to remove the merge/delete description and clarify ownership of the original manifest and its copy.

Normalize legacy replacement sequence numbers on format upgrades, invalidate cached output when rewrite settings change, and compute manifest counts in Summary.

Require an unset snapshot ID for manifest reuse, clarify AddManifest ownership, and add regression coverage.
/// be cleaned up on expiry. This update does not delete the original on failure.
RewriteManifests& AddManifest(const ManifestFile& manifest);

std::string operation() override;

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.

The methods from here should not be public interfaces.

This branch has not been deployed

No deployments
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.

3 participants