This is an automated email from the ASF dual-hosted git repository.
laskoviymishka pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/iceberg-go.git
The following commit(s) were added to refs/heads/main by this push:
new 488fb35ef fix(dv): validate metadata before writing Puffin files
(#1589)
488fb35ef is described below
commit 488fb35efd984803439e54e92245014503e6c15e
Author: Minh Vu <[email protected]>
AuthorDate: Thu Jul 30 09:40:43 2026 +0200
fix(dv): validate metadata before writing Puffin files (#1589)
## What changed
Construct and validate all deletion-vector `DataFile` metadata before
writing the completed Puffin object. Extend the unknown-spec regression
test to verify that no file is created.
## Why
`Flush` previously persisted the Puffin file before resolving partition
specs and building manifest metadata. A metadata error could therefore
return failure while leaving an unreferenced object in storage.
## Testing
- `go test ./table/dv`
Signed-off-by: Minh Vu <[email protected]>
---
table/dv/dv_writer.go | 8 ++++----
table/dv/dv_writer_test.go | 7 ++++++-
2 files changed, 10 insertions(+), 5 deletions(-)
diff --git a/table/dv/dv_writer.go b/table/dv/dv_writer.go
index 682b2b8c2..7bb9cae2d 100644
--- a/table/dv/dv_writer.go
+++ b/table/dv/dv_writer.go
@@ -223,10 +223,6 @@ func (w *DVWriter) Flush(_ context.Context, location
string) ([]iceberg.DataFile
}
fileBytes := buf.Bytes()
- if err := w.fs.WriteFile(location, fileBytes); err != nil {
- return nil, fmt.Errorf("write DV puffin file: %w", err)
- }
-
fileSize := int64(len(fileBytes))
dataFiles := make([]iceberg.DataFile, 0, len(results))
@@ -260,6 +256,10 @@ func (w *DVWriter) Flush(_ context.Context, location
string) ([]iceberg.DataFile
dataFiles = append(dataFiles, df)
}
+ if err := w.fs.WriteFile(location, fileBytes); err != nil {
+ return nil, fmt.Errorf("write DV puffin file: %w", err)
+ }
+
w.entries = make(map[string]*dvEntry)
w.order = nil
diff --git a/table/dv/dv_writer_test.go b/table/dv/dv_writer_test.go
index 66aaf79a8..dca90f5b2 100644
--- a/table/dv/dv_writer_test.go
+++ b/table/dv/dv_writer_test.go
@@ -19,6 +19,7 @@ package dv
import (
"context"
+ stdfs "io/fs"
"testing"
"github.com/apache/iceberg-go"
@@ -452,13 +453,17 @@ func TestDVWriterFlushMixedSpecIDs(t *testing.T) {
func TestDVWriterFlushUnknownSpecID(t *testing.T) {
fs := newTestFS()
w := NewDVWriter(fs, unpartitionedResolver())
+ location := "mem://test/unknown-spec.puffin"
// specID 99 is not registered with the resolver.
require.NoError(t, w.Add("s3://bucket/file.parquet", []int64{1}, 99,
nil))
- _, err := w.Flush(context.Background(),
"mem://test/unknown-spec.puffin")
+ _, err := w.Flush(context.Background(), location)
require.Error(t, err)
assert.Contains(t, err.Error(), "unknown partition spec id 99")
+
+ _, openErr := fs.Open(location)
+ assert.ErrorIs(t, openErr, stdfs.ErrNotExist)
}
func verifyDVReadBack(t *testing.T, fs iceio.IO, df iceberg.DataFile) {