Skip to content

Commit

Permalink
fix: decode in the case of field missing in both writer binary and re…
Browse files Browse the repository at this point in the history
…ader struct (#452)
  • Loading branch information
redaLaanait committed Sep 16, 2024
1 parent 84f98c7 commit 571d881
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 2 deletions.
12 changes: 10 additions & 2 deletions codec_record.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,17 @@ func decoderOfStruct(d *decoderContext, schema Schema, typ reflect2.Type) ValDec
}
}
}

// Skip field if it doesnt exist
// Skip field if it doesn't exist
if sf == nil {
// If the field value doesn't exist in the binary, ignore it instead of
// appending a 'SkipDecoder'.
//
// Note: 'SkipDecoder' performs a read and moves the cursor, which,
// in this case, will lead to a dirty read.
if field.action == FieldSetDefault {
continue
}

fields = append(fields, &structFieldDecoder{
decoder: createSkipDecoder(field.Type()),
})
Expand Down
41 changes: 41 additions & 0 deletions schema_compatibility_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -976,3 +976,44 @@ func TestSchemaCompatibility_ResolveWithComplexUnion(t *testing.T) {
want := map[string]any{"b": []byte("foo")}
assert.Equal(t, want, result)
}

func TestSchemaCompatibility_ResolveWithFieldMissingInWriterAndReaderStruct(t *testing.T) {
w := avro.MustParse(`{
"type":"record", "name":"test", "namespace": "org.hamba.avro",
"fields":[
{"name": "a", "type": "string"}
]
}`)

r := avro.MustParse(`{
"type":"record", "name":"test", "namespace": "org.hamba.avro",
"fields":[
{"name": "a", "type": "string"},
{"name": "b", "type": "int", "default": 10},
{"name": "c", "type": "string", "default": "foo"}
]
}`)

type TestW struct {
A string `avro:"a"`
}
value := TestW{A: "abc"}

b, err := avro.Marshal(w, value)
assert.NoError(t, err)

schema, err := avro.NewSchemaCompatibility().Resolve(r, w)
assert.NoError(t, err)

type TestR struct {
A string `avro:"a"`
C string `avro:"c"`
}
want := TestR{A: "abc", C: "foo"}

var result TestR
err = avro.Unmarshal(schema, b, &result)
assert.NoError(t, err)

assert.Equal(t, want, result)
}

0 comments on commit 571d881

Please sign in to comment.