feat(commit): support TruncateTable/Abort/RollbackToAsLatest and add ut#432
Conversation
There was a problem hiding this comment.
Pull request overview
This PR extends the C++ FileStoreCommit commit path with table-wide truncation and best-effort abort cleanup, and adds unit tests covering these new behaviors along with additional commit-path correctness checks.
Changes:
- Add new public
FileStoreCommitAPIs:TruncateTable()andAbort(...), with correspondingFileStoreCommitImplimplementations. - Implement truncate as an overwrite of all partitions with empty changes; implement abort as best-effort deletion of newly produced data/index files from commit messages.
- Add/extend unit tests (including a new
sequence_snapshot_properties_test.cpp) and wire the new test into the CMake test sources.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| include/paimon/file_store_commit.h | Adds new public commit APIs and documents their semantics. |
| src/paimon/core/operation/file_store_commit_impl.h | Declares the new override methods in FileStoreCommitImpl. |
| src/paimon/core/operation/file_store_commit_impl.cpp | Implements TruncateTable and Abort behaviors in the commit implementation. |
| src/paimon/core/operation/file_store_commit_impl_test.cpp | Adds unit tests for truncation, abort cleanup, and additional commit-path validation behaviors. |
| src/paimon/core/operation/commit/sequence_snapshot_properties_test.cpp | Introduces UT coverage for sequence snapshot properties parsing/merging. |
| src/paimon/CMakeLists.txt | Registers the new test source in the test build. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
zjw1111
left a comment
There was a problem hiding this comment.
Reviewed the three new commit operations against the Java FileStoreCommitImpl. No blocking correctness issues; the implementations track Java line-by-line and the tests are behavior-level (write files → operate → assert file/snapshot state).
Verified as correct:
TruncateTable: emptypartitions={}maps to "all partitions" in both the data scan (FileStoreScan::CreatePartitionPredicate) and the index filter (CommitScanner::ReadAllIndexEntriesFromPartitions), equivalent to JavatryOverwritePartition(null, ...).Abort: delete set =newFiles + changelogFiles + compactAfter + compact.changelogFiles(data) andnewIndexFilesfrom both increments; correctly excludescompactBefore. Matches Java exactly.RollbackToAsLatest:Snapshotctor argument order matches the regular commit path;total_record_count/index_manifest/watermark/statistics/propertiesfrom target,delta_record_countfrom the diff,commit_identifier=int64_max,next_row_id=max(latest,target)— all consistent with Java. Skipping pre/post-commit callbacks is consistent with the C++ path not implementing callbacks yet.
One inline comment on scope. Test blind spots (non-blocking):
RollbackToAsLatest: no coverage for thesuccess=false(concurrent-conflict) branch and the temp-manifest-list leak on that path (leak matches Java).Abort: no coverage for a delete that fails on IO/permission and is silently ignored (only the missing-file no-op is covered).TruncateTable: only single-truncate covered; no empty-table case.
zjw1111
left a comment
There was a problem hiding this comment.
Two follow-ups after the latest fixes.
|
Minor: the PR description has a lot of hard line breaks in the middle of sentences. Please drop them and let the text wrap naturally — the forced wrapping reads awkwardly in the rendered view. |
Purpose
Linked issue: close #xxx
This change aligns the C++
FileStoreCommitwith Java Paimon by adding three missing commit operations, plus unit-test coverage for the commit path.TruncateTable(commit_identifier): truncates the whole table by overwriting all partitions with no new files. It reuses the existingTryOverwritepath with an empty partition list (which matches all partitions), producing anOVERWRITEsnapshot that deletes every existing file. Mirrors JavaFileStoreCommit.truncateTable.Abort(commit_messages): cleans up after an unsuccessful commit by best-effort deleting the data and index files referenced by the given commit messages (new files, changelog files, compact-after files, and new index files from both the data and compact increments). Delete failures are ignored, matching JavadeleteQuietly. A non-CommitMessageImplmessage is rejected with an error. Mirrors JavaFileStoreCommit.abort.RollbackToAsLatest(target_snapshot_id): rolls the table back to a target snapshot and materializes it as a new latest snapshot. It reads the survivingADDdata files of both the current latest snapshot and the target snapshot, computes their difference (files only in latest becomeDELETE, files only in target becomeADD), and writes the base and delta manifests. It then commits a singleOVERWRITEsnapshot whose visible state equals the target: the new snapshot inherits the target's schema id, index manifest, total record count, watermark, statistics, and properties, and itsnextRowIdis the larger of the latest and targetnextRowIdto keep row-id allocation monotonic. Mirrors JavaFileStoreCommit.rollbackToAsLatest.Unlike Java, the C++ commit path has no commit-callback mechanism, so for
RollbackToAsLatestthe Java pre/post callbacks androllbackIndexChangesare intentionally omitted; the new snapshot's index manifest points directly to the target's, which is equivalent for the on-disk result. Two private helpers are added toFileStoreCommitImpl:ReadAddManifestEntries(mirrorsFileEntry.mergeEntriesfollowed by keeping onlyADDentries) andMaxNextRowId(mirrors JavamaxNextRowId).The change also adds unit tests for
FileStoreCommitImpland introduces a dedicatedsequence_snapshot_properties_test.cppsuite.Tests
Added GoogleTest cases (run via
paimon-core-test):FileStoreCommitImplTest.TestTruncateTable— truncates a committed table and asserts a newOVERWRITEsnapshot whose delta manifest deletes all files (0 added, 3 deleted for theappend_09fixture).FileStoreCommitImplTest.TestAbortDeletesDataAndIndexFiles— materializes the data/index files referenced by a commit message and verifiesAbortremoves them.FileStoreCommitImplTest.AbortIgnoresMissingFilesAndFailsForNonImplMessage— aborting missing files is a no-op; a non-impl message returns an error.FileStoreCommitImplTest.TestRollbackToAsLatest— appends three snapshots, then rolls back to snapshot 1 (exercising theDELETE-only delta branch) and rolls forward to snapshot 3 (exercising theADD-only delta branch). Asserts a newOVERWRITEsnapshot with the target's schema id, total record count, index manifest,nextRowId == max(latest, target), and a surviving file set equal to the target.FileStoreCommitImplTest.TestRollbackToAsLatestDeletionVectorOnlyChange— when the target and latest share identical data files and differ only in the deletion vector (index) manifest, the rollback produces an empty data delta (DeltaRecordCount == 0) and the new snapshot inherits the target's index manifest, dropping the deletion vector.FileStoreCommitImplTest.TestRollbackToAsLatestNoLatestSnapshotReturnsError— rolling back an empty table returns an error.FileStoreCommitImplTest.TestRollbackToAsLatestTargetNotExistReturnsError— rolling back to a non-existent target snapshot returns an error.FileStoreCommitImplTestcoverage (drop-partition validation, filter-and-commit, overwrite ownership/upgrade, conflict checks, etc.).SequenceSnapshotPropertiesTestsuite covering max-sequence-number parsing, extraction from files, and merge behavior.API and Format
Yes — public API additions. Three new pure-virtual methods on
paimon::FileStoreCommit(include/paimon/file_store_commit.h):virtual Status TruncateTable(int64_t commit_identifier) = 0;virtual Status Abort(const std::vector<std::shared_ptr<CommitMessage>>& commit_messages) = 0;virtual Result<bool> RollbackToAsLatest(int64_t target_snapshot_id) = 0;No storage format or protocol change.
TruncateTableandRollbackToAsLatestproduce standardOVERWRITEsnapshots; there is no on-disk layout change.Documentation
New public API methods, documented via doxygen comments in the header. No new user-guide page is required.
Generative AI tooling
Generated-by: Qoder