diff --git a/table/metadata.go b/table/metadata.go index 35a2e3f68..e393214d6 100644 --- a/table/metadata.go +++ b/table/metadata.go @@ -902,13 +902,17 @@ func (b *MetadataBuilder) RemoveSnapshotRef(name string) error { return nil } -func (b *MetadataBuilder) SetUUID(uuid uuid.UUID) error { - if b.uuid == uuid { +func (b *MetadataBuilder) SetUUID(newUUID uuid.UUID) error { + if newUUID == uuid.Nil { + return fmt.Errorf("%w: cannot set uuid to nil", iceberg.ErrInvalidArgument) + } + + if b.uuid == newUUID { return nil } - b.updates = append(b.updates, NewAssignUUIDUpdate(uuid)) - b.uuid = uuid + b.updates = append(b.updates, NewAssignUUIDUpdate(newUUID)) + b.uuid = newUUID return nil } diff --git a/table/metadata_builder_internal_test.go b/table/metadata_builder_internal_test.go index 327d18077..a0ca6cda1 100644 --- a/table/metadata_builder_internal_test.go +++ b/table/metadata_builder_internal_test.go @@ -2317,6 +2317,30 @@ func TestSetFormatVersionPreservesExistingUUID(t *testing.T) { require.Equal(t, existingUUID, meta.TableUUID()) } +func TestSetUUIDRejectsNil(t *testing.T) { + builder := builderWithoutChanges(2) + originalUUID := builder.uuid + + err := builder.SetUUID(uuid.Nil) + require.ErrorIs(t, err, iceberg.ErrInvalidArgument) + require.False(t, builder.HasChanges()) + require.Equal(t, originalUUID, builder.uuid) + + meta, err := builder.Build() + require.NoError(t, err) + require.Equal(t, originalUUID, meta.TableUUID()) +} + +func TestNewMetadataWithUUIDGeneratesUUIDForNil(t *testing.T) { + tableSchema := schema() + partSpec := partitionSpec() + order := sortOrder() + + meta, err := NewMetadataWithUUID(&tableSchema, &partSpec, order, "s3://bucket/test/location", nil, uuid.Nil) + require.NoError(t, err) + require.NotEqual(t, uuid.Nil, meta.TableUUID()) +} + func TestSetFormatVersionDowngradeNotAllowed(t *testing.T) { builder := builderWithoutChanges(2) err := builder.SetFormatVersion(1) diff --git a/table/updates_test.go b/table/updates_test.go index 3273713b0..24a60e7e0 100644 --- a/table/updates_test.go +++ b/table/updates_test.go @@ -569,6 +569,19 @@ func buildFromBase(t *testing.T) *MetadataBuilder { return b } +func TestAssignUUIDUpdate_ApplyRejectsNilUUID(t *testing.T) { + b := buildFromBase(t) + originalUUID := b.uuid + + err := NewAssignUUIDUpdate(uuid.Nil).Apply(b) + require.ErrorIs(t, err, iceberg.ErrInvalidArgument) + require.False(t, b.HasChanges()) + + meta, err := b.Build() + require.NoError(t, err) + require.Equal(t, originalUUID, meta.TableUUID()) +} + func TestSetStatisticsUpdate_Unmarshal(t *testing.T) { data := []byte(`[{ "action": "set-statistics",