From 091f91ef6fbfd39a28242ad6ad451d890fd55855 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20P=C3=BCtz?= Date: Tue, 12 Aug 2025 14:23:14 +0200 Subject: [PATCH 1/4] add test for removing main ref --- table/metadata_builder_internal_test.go | 19 +++ table/metadata_internal_test.go | 15 +++ test_table_metadata/TableMetadataV2Valid.json | 122 ++++++++++++++++++ 3 files changed, 156 insertions(+) create mode 100644 test_table_metadata/TableMetadataV2Valid.json diff --git a/table/metadata_builder_internal_test.go b/table/metadata_builder_internal_test.go index 41b7991d2..229eab04c 100644 --- a/table/metadata_builder_internal_test.go +++ b/table/metadata_builder_internal_test.go @@ -194,3 +194,22 @@ func TestCannotAddDuplicateSnapshotID(t *testing.T) { _, err = builder.AddSnapshot(&snapshot) require.ErrorContains(t, err, "can't add snapshot with id 2, already exists") } + +func TestRemoveMainSnapshotRef(t *testing.T) { + meta, err := getTestTableMetadata("TableMetadataV2Valid.json") + require.NoError(t, err) + require.NotNil(t, meta) + require.NotNil(t, meta.CurrentSnapshot()) + builder, err := MetadataBuilderFromBase(meta) + require.NoError(t, err) + require.NotNil(t, builder.currentSnapshotID) + if _, ok := builder.refs[MainBranch]; !ok { + t.Fatal("expected main branch to exist") + } + _, err = builder.RemoveSnapshotRef(MainBranch) + require.NoError(t, err) + require.Nil(t, builder.currentSnapshotID) + meta, err = builder.Build() + require.NoError(t, err) + require.NotNil(t, meta) +} diff --git a/table/metadata_internal_test.go b/table/metadata_internal_test.go index 6ca47a7ba..7f9c89a5b 100644 --- a/table/metadata_internal_test.go +++ b/table/metadata_internal_test.go @@ -19,6 +19,8 @@ package table import ( "encoding/json" + "os" + "path" "slices" "testing" @@ -949,3 +951,16 @@ func TestMetadataV2Validation(t *testing.T) { // Test case 3: Verify LastColumnId maintains 0 when explicitly set require.NoError(t, meta3.UnmarshalJSON([]byte(zeroColumnID))) } + +func getTestTableMetadata(fileName string) (Metadata, error) { + fCont, err := os.ReadFile(path.Join("../test_table_metadata", fileName)) + if err != nil { + return nil, err + } + meta, err := ParseMetadataBytes(fCont) + if err != nil { + return nil, err + } + + return meta, nil +} diff --git a/test_table_metadata/TableMetadataV2Valid.json b/test_table_metadata/TableMetadataV2Valid.json new file mode 100644 index 000000000..0dc89de58 --- /dev/null +++ b/test_table_metadata/TableMetadataV2Valid.json @@ -0,0 +1,122 @@ +{ + "format-version": 2, + "table-uuid": "9c12d441-03fe-4693-9a96-a0705ddf69c1", + "location": "s3://bucket/test/location", + "last-sequence-number": 34, + "last-updated-ms": 1602638573590, + "last-column-id": 3, + "current-schema-id": 1, + "schemas": [ + { + "type": "struct", + "schema-id": 0, + "fields": [ + { + "id": 1, + "name": "x", + "required": true, + "type": "long" + } + ] + }, + { + "type": "struct", + "schema-id": 1, + "identifier-field-ids": [ + 1, + 2 + ], + "fields": [ + { + "id": 1, + "name": "x", + "required": true, + "type": "long" + }, + { + "id": 2, + "name": "y", + "required": true, + "type": "long", + "doc": "comment" + }, + { + "id": 3, + "name": "z", + "required": true, + "type": "long" + } + ] + } + ], + "default-spec-id": 0, + "partition-specs": [ + { + "spec-id": 0, + "fields": [ + { + "name": "x", + "transform": "identity", + "source-id": 1, + "field-id": 1000 + } + ] + } + ], + "last-partition-id": 1000, + "default-sort-order-id": 3, + "sort-orders": [ + { + "order-id": 3, + "fields": [ + { + "transform": "identity", + "source-id": 2, + "direction": "asc", + "null-order": "nulls-first" + }, + { + "transform": "bucket[4]", + "source-id": 3, + "direction": "desc", + "null-order": "nulls-last" + } + ] + } + ], + "properties": {}, + "current-snapshot-id": 3055729675574597004, + "snapshots": [ + { + "snapshot-id": 3051729675574597004, + "timestamp-ms": 1515100955770, + "sequence-number": 0, + "summary": { + "operation": "append" + }, + "manifest-list": "s3://a/b/1.avro" + }, + { + "snapshot-id": 3055729675574597004, + "parent-snapshot-id": 3051729675574597004, + "timestamp-ms": 1555100955770, + "sequence-number": 1, + "summary": { + "operation": "append" + }, + "manifest-list": "s3://a/b/2.avro", + "schema-id": 1 + } + ], + "snapshot-log": [ + { + "snapshot-id": 3051729675574597004, + "timestamp-ms": 1515100955770 + }, + { + "snapshot-id": 3055729675574597004, + "timestamp-ms": 1555100955770 + } + ], + "metadata-log": [] +} \ No newline at end of file From 93980248e0997492816f768e5c49b8cdc8ef4c78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20P=C3=BCtz?= Date: Tue, 12 Aug 2025 14:19:20 +0200 Subject: [PATCH 2/4] fix remove snapshot ref --- table/metadata.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/table/metadata.go b/table/metadata.go index 5db953148..597e7cf71 100644 --- a/table/metadata.go +++ b/table/metadata.go @@ -623,7 +623,8 @@ func (b *MetadataBuilder) RemoveSnapshotRef(name string) (*MetadataBuilder, erro } if name == MainBranch { - return nil, errors.New("cannot remove main branch's snapshot ref") + b.currentSnapshotID = nil + b.snapshotLog = b.snapshotLog[:0] } delete(b.refs, name) From b81ceb3782602960ca3f59969ffe124227f52cfa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20P=C3=BCtz?= Date: Mon, 18 Aug 2025 10:05:33 +0200 Subject: [PATCH 3/4] move test files --- table/metadata_internal_test.go | 2 +- .../testdata}/TableMetadataV2Valid.json | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename {test_table_metadata => table/testdata}/TableMetadataV2Valid.json (100%) diff --git a/table/metadata_internal_test.go b/table/metadata_internal_test.go index 7f9c89a5b..e183fcf3d 100644 --- a/table/metadata_internal_test.go +++ b/table/metadata_internal_test.go @@ -953,7 +953,7 @@ func TestMetadataV2Validation(t *testing.T) { } func getTestTableMetadata(fileName string) (Metadata, error) { - fCont, err := os.ReadFile(path.Join("../test_table_metadata", fileName)) + fCont, err := os.ReadFile(path.Join("testdata", fileName)) if err != nil { return nil, err } diff --git a/test_table_metadata/TableMetadataV2Valid.json b/table/testdata/TableMetadataV2Valid.json similarity index 100% rename from test_table_metadata/TableMetadataV2Valid.json rename to table/testdata/TableMetadataV2Valid.json From 3d982914043b9f1a8053656de780c3bfad7cea5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20P=C3=BCtz?= Date: Mon, 18 Aug 2025 16:37:06 +0200 Subject: [PATCH 4/4] init null snapshotRefs --- table/metadata.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/table/metadata.go b/table/metadata.go index 597e7cf71..e47c8dbed 100644 --- a/table/metadata.go +++ b/table/metadata.go @@ -1038,6 +1038,10 @@ func (c *commonMetadata) preValidate() { c.CurrentSnapshotID = nil } + if c.SnapshotRefs == nil { + c.SnapshotRefs = map[string]SnapshotRef{} + } + if c.CurrentSnapshotID != nil { if _, ok := c.SnapshotRefs[MainBranch]; !ok { c.SnapshotRefs[MainBranch] = SnapshotRef{