Skip to content

Commit c2ac60e

Browse files
authored
fix: ref already seen schemas in deref walk (#438)
1 parent 917a77e commit c2ac60e

File tree

2 files changed

+55
-0
lines changed

2 files changed

+55
-0
lines changed

schema_parse.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -564,6 +564,13 @@ func derefSchema(schema Schema) Schema {
564564

565565
return walkSchema(schema, func(schema Schema) Schema {
566566
if ns, ok := schema.(NamedSchema); ok {
567+
if _, hasSeen := seen[ns.FullName()]; hasSeen {
568+
// This NamedSchema has been seen in this run, it needs
569+
// to be turned into a reference. It is possible it was
570+
// dereferenced in a previous run.
571+
return NewRefSchema(ns)
572+
}
573+
567574
seen[ns.FullName()] = struct{}{}
568575
return schema
569576
}

schema_test.go

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package avro_test
22

33
import (
44
"encoding/json"
5+
"strings"
56
"testing"
67

78
"github.com/hamba/avro/v2"
@@ -1480,3 +1481,50 @@ func TestSchema_ParseBackAndForth(t *testing.T) {
14801481
assert.NoError(t, err)
14811482
assert.Equal(t, schema, schema2)
14821483
}
1484+
1485+
func TestSchema_DereferencingRectifiesAlreadySeenSchema(t *testing.T) {
1486+
schmCache := &avro.SchemaCache{}
1487+
_, err := avro.ParseWithCache(`{
1488+
"type": "record",
1489+
"name": "test1",
1490+
"namespace": "org.hamba.avro",
1491+
"fields": [
1492+
{"name": "a", "type": "string"}
1493+
]
1494+
}`, "", schmCache)
1495+
require.NoError(t, err)
1496+
_, err = avro.ParseWithCache(`{
1497+
"type": "record",
1498+
"name": "test2",
1499+
"namespace": "org.hamba.avro",
1500+
"fields": [
1501+
{
1502+
"name": "inner",
1503+
"type": {
1504+
"name": "InnerRecord",
1505+
"type": "record",
1506+
"fields": [
1507+
{"name": "b", "type": "org.hamba.avro.test1"}
1508+
]
1509+
}
1510+
}
1511+
]
1512+
}`, "", schmCache)
1513+
require.NoError(t, err)
1514+
schm, err := avro.ParseWithCache(`{
1515+
"type": "record",
1516+
"name": "test3",
1517+
"namespace": "org.hamba.avro",
1518+
"fields": [
1519+
{"name": "c", "type": "org.hamba.avro.test1"},
1520+
{"name": "d", "type": "org.hamba.avro.test2"}
1521+
]
1522+
}
1523+
`, "", schmCache)
1524+
require.NoError(t, err)
1525+
1526+
strSchema := schm.String()
1527+
1528+
n := strings.Count(strSchema, `"name":"org.hamba.avro.test1"`)
1529+
assert.Equal(t, 1, n)
1530+
}

0 commit comments

Comments
 (0)