zeroshade commented on code in PR #890:
URL: https://github.com/apache/iceberg-go/pull/890#discussion_r3089673911


##########
manifest.go:
##########
@@ -316,14 +243,14 @@ type manifestFile struct {
        SeqNumber          int64           `avro:"sequence_number"`
        MinSeqNumber       int64           `avro:"min_sequence_number"`
        AddedSnapshotID    int64           `avro:"added_snapshot_id"`
-       AddedFilesCount    int32           `avro:"added_files_count"`
-       ExistingFilesCount int32           `avro:"existing_files_count"`
-       DeletedFilesCount  int32           `avro:"deleted_files_count"`
+       AddedFilesCount    int32           
`avro:"added_files_count,alias=added_data_files_count"`
+       ExistingFilesCount int32           
`avro:"existing_files_count,alias=existing_data_files_count"`
+       DeletedFilesCount  int32           
`avro:"deleted_files_count,alias=deleted_data_files_count"`
        AddedRowsCount     int64           `avro:"added_rows_count"`
        ExistingRowsCount  int64           `avro:"existing_rows_count"`
        DeletedRowsCount   int64           `avro:"deleted_rows_count"`
-       PartitionList      *[]FieldSummary `avro:"partitions"`
-       Key                []byte          `avro:"key_metadata"`
+       PartitionList      *[]FieldSummary `avro:"partitions,type-alias=r508"`
+       Key                *[]byte         `avro:"key_metadata"`

Review Comment:
   why this change?



##########
manifest.go:
##########
@@ -384,15 +311,30 @@ func (m *manifestFile) Length() int64                    
{ return m.Len }
 func (m *manifestFile) PartitionSpecID() int32           { return m.SpecID }
 func (m *manifestFile) ManifestContent() ManifestContent { return m.Content }
 func (m *manifestFile) SnapshotID() int64                { return 
m.AddedSnapshotID }
-func (m *manifestFile) AddedDataFiles() int32            { return 
m.AddedFilesCount }
-func (m *manifestFile) ExistingDataFiles() int32         { return 
m.ExistingFilesCount }
-func (m *manifestFile) DeletedDataFiles() int32          { return 
m.DeletedFilesCount }
-func (m *manifestFile) AddedRows() int64                 { return 
m.AddedRowsCount }
-func (m *manifestFile) ExistingRows() int64              { return 
m.ExistingRowsCount }
-func (m *manifestFile) DeletedRows() int64               { return 
m.DeletedRowsCount }
-func (m *manifestFile) SequenceNum() int64               { return m.SeqNumber }
-func (m *manifestFile) MinSequenceNum() int64            { return 
m.MinSeqNumber }
-func (m *manifestFile) KeyMetadata() []byte              { return m.Key }
+func (m *manifestFile) AddedDataFiles() int32 {
+       return m.AddedFilesCount
+}
+
+func (m *manifestFile) ExistingDataFiles() int32 {
+       return m.ExistingFilesCount
+}
+
+func (m *manifestFile) DeletedDataFiles() int32 {
+       return m.DeletedFilesCount
+}

Review Comment:
   why change this formatting?



##########
manifest.go:
##########
@@ -401,8 +343,14 @@ func (m *manifestFile) Partitions() []FieldSummary {
        return *m.PartitionList
 }
 
-func (m *manifestFile) HasAddedFiles() bool    { return m.AddedFilesCount != 0 
}
-func (m *manifestFile) HasExistingFiles() bool { return m.ExistingFilesCount 
!= 0 }
+func (m *manifestFile) HasAddedFiles() bool {
+       return m.AddedFilesCount != 0
+}
+
+func (m *manifestFile) HasExistingFiles() bool {
+       return m.ExistingFilesCount != 0
+}
+

Review Comment:
   why change this formatting?



##########
manifest.go:
##########
@@ -158,154 +158,81 @@ func (b *ManifestBuilder) Build() ManifestFile {
        return b.m
 }
 
-type fallbackManifestFileV1 struct {
-       manifestFileV1
-       AddedSnapshotID *int64 `avro:"added_snapshot_id"`
-}
-
-func (f *fallbackManifestFileV1) toFile() *manifestFile {
-       if f.AddedSnapshotID == nil {
-               f.manifestFileV1.AddedSnapshotID = -1
-       }
-
-       return f.manifestFileV1.toFile()
-}
-
+// manifestFileV1 is a read/write struct for V1 manifest list entries.
+// Pointer fields handle nullable Avro types (["null", T] unions).
+// The three count fields carry aliases for pre-1.4 Java Iceberg legacy names
+// (apache/iceberg#5338) so that avro.Resolve maps them transparently.
 type manifestFileV1 struct {
-       manifestFile
-       AddedFilesCount    *int32 `avro:"added_files_count"`
-       ExistingFilesCount *int32 `avro:"existing_files_count"`
-       DeletedFilesCount  *int32 `avro:"deleted_files_count"`
-       AddedRowsCount     *int64 `avro:"added_rows_count"`
-       ExistingRowsCount  *int64 `avro:"existing_rows_count"`
-       DeletedRowsCount   *int64 `avro:"deleted_rows_count"`
+       Path               string          `avro:"manifest_path"`
+       Len                int64           `avro:"manifest_length"`
+       SpecID             int32           `avro:"partition_spec_id"`
+       AddedSnapshotID    *int64          `avro:"added_snapshot_id"`

Review Comment:
   Isn't `AddedSnapshotId` required in v1? Will this break if the avro schema 
has it as required vs optional? Previously we relied on embedding the 
`manifestFile` version that had it as required and then fell back if it was 
optional. But we don't want this to break on v1 manifests that have it as 
required.



##########
manifest.go:
##########
@@ -811,43 +753,46 @@ func ReadManifest(m ManifestFile, f io.Reader, 
discardDeleted bool) ([]ManifestE
 // "format-version" metadata key (only manifest files are). When the key is
 // absent, version 1 is assumed.
 func ReadManifestList(in io.Reader) ([]ManifestFile, error) {
-       rd, err := ocf.NewReader(in)
-       if err != nil {
-               return nil, err
-       }
+       var version int
+
+       rd, err := ocf.NewReader(in, ocf.WithReaderSchemaFunc(func(rd 
*ocf.Reader) (*avro.Schema, error) {
+               version = 1
+               if raw := rd.Metadata()["format-version"]; len(raw) > 0 {
+                       v, err := strconv.Atoi(string(raw))
+                       if err != nil {
+                               return nil, fmt.Errorf("invalid format-version: 
%w", err)
+                       }
 
-       sc, err := avro.Parse(string(rd.Metadata()["avro.schema"]))
-       if err != nil {
-               return nil, err
-       }
+                       version = v
+               }
 
-       version := 1
-       if raw := rd.Metadata()["format-version"]; len(raw) > 0 {
-               version, err = strconv.Atoi(string(raw))
-               if err != nil {
-                       return nil, fmt.Errorf("invalid format-version: %w", 
err)
+               if version == 1 {
+                       return manifestFileV1Reader, nil
                }
+
+               return manifestFileReader, nil
+       }))
+       if err != nil {
+               return nil, err
        }
 
        if version == 1 {
-               root := sc.Root()
-               for _, f := range root.Fields {
-                       if f.Name == "added_snapshot_id" {
-                               if f.Type.Type == "union" {
-                                       return 
decodeManifestsWithFallback[*fallbackManifestFileV1](rd)
+               results := make([]ManifestFile, 0)
+               for {
+                       tmp := new(manifestFileV1)
+                       if err := rd.Decode(tmp); err != nil {
+                               if errors.Is(err, io.EOF) {
+                                       return results, nil
                                }
 
-                               break
+                               return nil, err
                        }
+
+                       results = append(results, tmp.toFile())

Review Comment:
   Isn't this just `decodeManifestsWithFallback[*manifestFileV1](rd)`? Can't we 
just leave the switch we had below?



##########
manifest.go:
##########
@@ -811,43 +753,46 @@ func ReadManifest(m ManifestFile, f io.Reader, 
discardDeleted bool) ([]ManifestE
 // "format-version" metadata key (only manifest files are). When the key is
 // absent, version 1 is assumed.
 func ReadManifestList(in io.Reader) ([]ManifestFile, error) {
-       rd, err := ocf.NewReader(in)
-       if err != nil {
-               return nil, err
-       }
+       var version int
+
+       rd, err := ocf.NewReader(in, ocf.WithReaderSchemaFunc(func(rd 
*ocf.Reader) (*avro.Schema, error) {
+               version = 1
+               if raw := rd.Metadata()["format-version"]; len(raw) > 0 {
+                       v, err := strconv.Atoi(string(raw))
+                       if err != nil {
+                               return nil, fmt.Errorf("invalid format-version: 
%w", err)
+                       }
 
-       sc, err := avro.Parse(string(rd.Metadata()["avro.schema"]))
-       if err != nil {
-               return nil, err
-       }
+                       version = v
+               }
 
-       version := 1
-       if raw := rd.Metadata()["format-version"]; len(raw) > 0 {
-               version, err = strconv.Atoi(string(raw))
-               if err != nil {
-                       return nil, fmt.Errorf("invalid format-version: %w", 
err)
+               if version == 1 {
+                       return manifestFileV1Reader, nil
                }
+
+               return manifestFileReader, nil

Review Comment:
   are we going to have to do this for every version?



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to