This is an automated email from the ASF dual-hosted git repository.
JingsongLi pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/paimon.git
The following commit(s) were added to refs/heads/master by this push:
new 94af1b2cc1 [core] Support branch creation from a tag whose snapshot
has expired (#8748)
94af1b2cc1 is described below
commit 94af1b2cc174f2051dc14ef1c761ca7b1d0a3308
Author: Arnav Balyan <[email protected]>
AuthorDate: Tue Jul 21 11:29:20 2026 +0530
[core] Support branch creation from a tag whose snapshot has expired (#8748)
---
.../paimon/utils/FileSystemBranchManager.java | 14 ++++++---
.../apache/paimon/table/SimpleTableTestBase.java | 36 ++++++++++++++++++++++
2 files changed, 46 insertions(+), 4 deletions(-)
diff --git
a/paimon-core/src/main/java/org/apache/paimon/utils/FileSystemBranchManager.java
b/paimon-core/src/main/java/org/apache/paimon/utils/FileSystemBranchManager.java
index aee1787850..9466ccd851 100644
---
a/paimon-core/src/main/java/org/apache/paimon/utils/FileSystemBranchManager.java
+++
b/paimon-core/src/main/java/org/apache/paimon/utils/FileSystemBranchManager.java
@@ -123,10 +123,16 @@ public class FileSystemBranchManager implements
BranchManager {
tagManager.tagPath(tagName),
tagManager.copyWithBranch(branchName).tagPath(tagName),
true);
- fileIO.copyFile(
- snapshotManager.snapshotPath(snapshot.id()),
-
snapshotManager.copyWithBranch(branchName).snapshotPath(snapshot.id()),
- true);
+ Path branchSnapshotPath =
+
snapshotManager.copyWithBranch(branchName).snapshotPath(snapshot.id());
+ if (snapshotManager.snapshotExists(snapshot.id())) {
+ fileIO.copyFile(
+ snapshotManager.snapshotPath(snapshot.id()),
branchSnapshotPath, true);
+ } else {
+ // The snapshot may have expired while the tag preserved its
content, so write the
+ // snapshot from the tag instead of copying a file that no
longer exists.
+ fileIO.writeFile(branchSnapshotPath, snapshot.toJson(), true);
+ }
copySchemasToBranch(branchName, snapshot.schemaId());
} catch (IOException e) {
throw new RuntimeException(
diff --git
a/paimon-core/src/test/java/org/apache/paimon/table/SimpleTableTestBase.java
b/paimon-core/src/test/java/org/apache/paimon/table/SimpleTableTestBase.java
index e02c2bae1b..8c7266939f 100644
--- a/paimon-core/src/test/java/org/apache/paimon/table/SimpleTableTestBase.java
+++ b/paimon-core/src/test/java/org/apache/paimon/table/SimpleTableTestBase.java
@@ -1105,6 +1105,42 @@ public abstract class SimpleTableTestBase {
assertThat(branchSchema.equals(schema0)).isTrue();
}
+ @Test
+ public void testCreateBranchFromTagAfterSnapshotExpired() throws Exception
{
+ FileStoreTable table = createFileStoreTable();
+ try (StreamTableWrite write = table.newWrite(commitUser);
+ StreamTableCommit commit = table.newCommit(commitUser)) {
+ write.write(rowData(1, 10, 100L));
+ commit.commit(0, write.prepareCommit(false, 1));
+ write.write(rowData(2, 20, 200L));
+ commit.commit(1, write.prepareCommit(false, 2));
+ write.write(rowData(3, 30, 300L));
+ commit.commit(2, write.prepareCommit(false, 3));
+ }
+
+ table.createTag("test-tag", 2);
+
+ Options expire = new Options();
+ expire.set(SNAPSHOT_NUM_RETAINED_MIN, 1);
+ expire.set(SNAPSHOT_NUM_RETAINED_MAX, 1);
+ table.copy(expire.toMap()).newCommit(commitUser).expireSnapshots();
+
+ SnapshotManager snapshotManager = newSnapshotManager(table.fileIO(),
table.location());
+ assertThat(snapshotManager.snapshotExists(2)).isFalse();
+ TagManager tagManager = new TagManager(table.fileIO(),
table.location());
+ assertThat(tagManager.tagExists("test-tag")).isTrue();
+
+ table.createBranch("test-branch", "test-tag");
+ assertThat(table.branchManager().branchExists("test-branch")).isTrue();
+
+ Snapshot tagged = tagManager.getOrThrow("test-tag").trimToSnapshot();
+ SnapshotManager branchSnapshotManager =
+ newSnapshotManager(table.fileIO(), table.location(),
"test-branch");
+ Snapshot branchSnapshot =
+ SnapshotManager.fromPath(table.fileIO(),
branchSnapshotManager.snapshotPath(2));
+ assertThat(branchSnapshot.equals(tagged)).isTrue();
+ }
+
@Test
public void testUnsupportedBranchName() throws Exception {
FileStoreTable table = createFileStoreTable();