You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@iceberg.apache.org by ze...@apache.org on 2026/08/07 15:52:40 UTC
(iceberg-go) branch main updated: fix(rest): accept legacy content enum values (#1660)
This is an automated email from the ASF dual-hosted git repository.
zeroshade 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 805bca98 fix(rest): accept legacy content enum values (#1660)
805bca98 is described below
commit 805bca98c2ae695c3ff6d4f0ad5a11f0cfb296b0
Author: Minh Vu <vu...@gmail.com>
AuthorDate: Fri Aug 7 17:52:34 2026 +0200
fix(rest): accept legacy content enum values (#1660)
---
catalog/rest/scan_task_decoder.go | 25 +++++++++++++++++--------
catalog/rest/scan_task_decoder_test.go | 32 ++++++++++++++++++++++++++++++++
2 files changed, 49 insertions(+), 8 deletions(-)
diff --git a/catalog/rest/scan_task_decoder.go b/catalog/rest/scan_task_decoder.go
index 680351b6..2549f220 100644
--- a/catalog/rest/scan_task_decoder.go
+++ b/catalog/rest/scan_task_decoder.go
@@ -305,13 +305,8 @@ func decodeRESTDeleteFile(
metadata table.ScanPlanningMetadata,
referencedDataFile string,
) (iceberg.DataFile, error) {
- var content iceberg.ManifestEntryContent
- switch wire.Content {
- case "position-deletes":
- content = iceberg.EntryContentPosDeletes
- case "equality-deletes":
- content = iceberg.EntryContentEqDeletes
- default:
+ content, ok := parseRESTFileContent(wire.Content)
+ if !ok || content == iceberg.EntryContentData {
return nil, fmt.Errorf("unknown delete content %q", wire.Content)
}
@@ -387,12 +382,13 @@ func contentFileBuilder(
expectedContent iceberg.ManifestEntryContent,
metadata table.ScanPlanningMetadata,
) (*iceberg.DataFileBuilder, iceberg.FileFormat, error) {
+ actualContent, ok := parseRESTFileContent(wire.Content)
wantContent := map[iceberg.ManifestEntryContent]string{
iceberg.EntryContentData: "data",
iceberg.EntryContentPosDeletes: "position-deletes",
iceberg.EntryContentEqDeletes: "equality-deletes",
}[expectedContent]
- if wire.Content != wantContent {
+ if !ok || actualContent != expectedContent {
return nil, "", fmt.Errorf("content is %q, want %q", wire.Content, wantContent)
}
if wire.RecordCount <= 0 {
@@ -458,6 +454,19 @@ func contentFileBuilder(
return builder, format, nil
}
+func parseRESTFileContent(value string) (iceberg.ManifestEntryContent, bool) {
+ switch value {
+ case "data", "DATA":
+ return iceberg.EntryContentData, true
+ case "position-deletes", "POSITION_DELETES":
+ return iceberg.EntryContentPosDeletes, true
+ case "equality-deletes", "EQUALITY_DELETES":
+ return iceberg.EntryContentEqDeletes, true
+ default:
+ return 0, false
+ }
+}
+
func decodePartition(
values []json.RawMessage,
spec *iceberg.PartitionSpec,
diff --git a/catalog/rest/scan_task_decoder_test.go b/catalog/rest/scan_task_decoder_test.go
index 0b0c82d1..0dcb8665 100644
--- a/catalog/rest/scan_task_decoder_test.go
+++ b/catalog/rest/scan_task_decoder_test.go
@@ -140,6 +140,31 @@ func TestDecodeScanTasksFullPayload(t *testing.T) {
assert.Equal(t, int64Ptr(50), dv.ContentSizeInBytes())
}
+func TestDecodeScanTasksAcceptsLegacyJavaContentValues(t *testing.T) {
+ t.Parallel()
+
+ metadata := newScanTaskDecoderMetadata()
+ for _, tt := range []struct {
+ name string
+ deleteType string
+ equalityID []int
+ }{
+ {name: "position deletes", deleteType: "POSITION_DELETES"},
+ {name: "equality deletes", deleteType: "EQUALITY_DELETES", equalityID: []int{1}},
+ } {
+ t.Run(tt.name, func(t *testing.T) {
+ wire := validScanTasksWire()
+ wire.FileScanTasks[0].DataFile.Content = "DATA"
+ wire.DeleteFiles[0].Content = tt.deleteType
+ wire.DeleteFiles[0].EqualityIDs = tt.equalityID
+
+ tasks, err := DecodeScanTasks(wire, metadata, metadata.schema, nil)
+ require.NoError(t, err)
+ require.Len(t, tasks, 1)
+ })
+ }
+}
+
func TestDecodeScanTasksUsesFallbackAndAcceptsSpecConstants(t *testing.T) {
t.Parallel()
@@ -307,6 +332,13 @@ func TestDecodeScanTasksRejectsMalformedPayloads(t *testing.T) {
},
want: "unknown partition spec ID 99",
},
+ {
+ name: "unknown content",
+ mutate: func(w *ScanTasks) {
+ w.FileScanTasks[0].DataFile.Content = "Data"
+ },
+ want: `content is "Data", want "data"`,
+ },
{
name: "wrong partition width",
mutate: func(w *ScanTasks) {