From 84f98c78fa27bc88a3467a37111c816f5d6f973b Mon Sep 17 00:00:00 2001 From: Reda Laanait Date: Mon, 16 Sep 2024 06:19:43 +0100 Subject: [PATCH] fix: record MarshalJSON in case of default record with nullable field (#451) --- schema.go | 8 +++++++- schema_test.go | 17 ++++++++++++++++- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/schema.go b/schema.go index d2b93df..a153768 100644 --- a/schema.go +++ b/schema.go @@ -16,7 +16,13 @@ import ( jsoniter "github.com/json-iterator/go" ) -var nullDefault = struct{}{} +type nullDefaultType struct{} + +func (nullDefaultType) MarshalJSON() ([]byte, error) { + return []byte("null"), nil +} + +var nullDefault nullDefaultType = struct{}{} var ( schemaReserved = []string{ diff --git a/schema_test.go b/schema_test.go index 1fa1461..6e0cb65 100644 --- a/schema_test.go +++ b/schema_test.go @@ -416,6 +416,11 @@ func TestRecordSchema_ValidatesDefault(t *testing.T) { schema: `{"type":"record", "name":"test", "namespace": "org.hamba.avro", "fields":[{"name": "a", "type": {"type":"record", "name": "test2", "fields":[{"name": "b", "type": "int"},{"name": "c", "type": "int", "default": 1}]}, "default": {"b": 1}}]}`, wantErr: assert.NoError, }, + { + name: "Record With Nullable Field", + schema: `{"type":"record", "name":"test", "namespace": "org.hamba.avro", "fields":[{"name": "a", "type": {"type":"record", "name": "test2", "fields":[{"name": "b", "type": "int"},{"name": "c", "type": ["null","int"]}]}, "default": {"b": 1, "c": null}}]}`, + wantErr: assert.NoError, + }, { name: "Record Not Map", schema: `{"type":"record", "name":"test", "namespace": "org.hamba.avro", "fields":[{"name": "a", "type": {"type":"record", "name": "test2", "fields":[{"name": "b", "type": "int"},{"name": "c", "type": "int", "default": 1}]}, "default": "test"}]}`, @@ -438,9 +443,19 @@ func TestRecordSchema_ValidatesDefault(t *testing.T) { t.Run(test.name, func(t *testing.T) { t.Parallel() - _, err := avro.ParseWithCache(test.schema, "", &avro.SchemaCache{}) + schema, err := avro.ParseWithCache(test.schema, "", &avro.SchemaCache{}) test.wantErr(t, err) + if err != nil { + return + } + + // Ensure MarshalJSON Generate the same schema as it considers default values + b, err := schema.(*avro.RecordSchema).MarshalJSON() + assert.NoError(t, err) + schema2, err := avro.ParseWithCache(string(b), "", &avro.SchemaCache{}) + assert.NoError(t, err) + assert.Equal(t, schema, schema2) }) } }