github.com/hamba/avro/v2@v2.22.1-0.20240518180522-aff3955acf7d/decoder_union_test.go (about)

     1  package avro_test
     2  
     3  import (
     4  	"bytes"
     5  	"math/big"
     6  	"testing"
     7  	"time"
     8  
     9  	"github.com/hamba/avro/v2"
    10  	"github.com/stretchr/testify/assert"
    11  	"github.com/stretchr/testify/require"
    12  )
    13  
    14  func TestDecoder_UnionInvalidType(t *testing.T) {
    15  	defer ConfigTeardown()
    16  
    17  	data := []byte{0x02, 0x06, 0x66, 0x6F, 0x6F}
    18  	schema := `["null", "string"]`
    19  	dec, err := avro.NewDecoder(schema, bytes.NewReader(data))
    20  	require.NoError(t, err)
    21  
    22  	var str string
    23  	err = dec.Decode(&str)
    24  
    25  	assert.Error(t, err)
    26  }
    27  
    28  func TestDecoder_UnionMap(t *testing.T) {
    29  	defer ConfigTeardown()
    30  
    31  	data := []byte{0x02, 0x06, 0x66, 0x6F, 0x6F}
    32  	schema := `["null", "string"]`
    33  	dec, _ := avro.NewDecoder(schema, bytes.NewReader(data))
    34  
    35  	var got map[string]any
    36  	err := dec.Decode(&got)
    37  
    38  	require.NoError(t, err)
    39  	assert.Equal(t, map[string]any{"string": "foo"}, got)
    40  }
    41  
    42  func TestDecoder_UnionMapNamed(t *testing.T) {
    43  	defer ConfigTeardown()
    44  
    45  	data := []byte{0x02, 0x02}
    46  	schema := `["null", {"type":"enum", "name": "test", "symbols": ["foo", "bar"]}]`
    47  	dec, _ := avro.NewDecoder(schema, bytes.NewReader(data))
    48  
    49  	var got map[string]any
    50  	err := dec.Decode(&got)
    51  
    52  	require.NoError(t, err)
    53  	assert.Equal(t, map[string]any{"test": "bar"}, got)
    54  }
    55  
    56  func TestDecoder_UnionMapNull(t *testing.T) {
    57  	defer ConfigTeardown()
    58  
    59  	data := []byte{0x00}
    60  	schema := `["null", "string"]`
    61  	dec, _ := avro.NewDecoder(schema, bytes.NewReader(data))
    62  
    63  	var got map[string]any
    64  	err := dec.Decode(&got)
    65  
    66  	require.NoError(t, err)
    67  	assert.Equal(t, map[string]any(nil), got)
    68  }
    69  
    70  func TestDecoder_UnionMapWithTime(t *testing.T) {
    71  	defer ConfigTeardown()
    72  
    73  	data := []byte{0x02, 0x80, 0xCD, 0xB7, 0xA2, 0xEE, 0xC7, 0xCD, 0x05}
    74  	schema := `["null", {"type": "long", "logicalType": "timestamp-micros"}]`
    75  	dec, _ := avro.NewDecoder(schema, bytes.NewReader(data))
    76  
    77  	var got map[string]any
    78  	err := dec.Decode(&got)
    79  
    80  	require.NoError(t, err)
    81  	assert.Equal(t, time.Date(2020, 1, 2, 3, 4, 5, 0, time.UTC), got["long.timestamp-micros"])
    82  }
    83  
    84  func TestDecoder_UnionMapWithDuration(t *testing.T) {
    85  	defer ConfigTeardown()
    86  
    87  	data := []byte{0x02, 0xAA, 0xB4, 0xDE, 0x75}
    88  	schema := `["null", {"type": "int", "logicalType": "time-millis"}]`
    89  	dec, _ := avro.NewDecoder(schema, bytes.NewReader(data))
    90  
    91  	var got map[string]any
    92  	err := dec.Decode(&got)
    93  
    94  	require.NoError(t, err)
    95  	assert.Equal(t, 123456789*time.Millisecond, got["int.time-millis"])
    96  }
    97  
    98  func TestDecoder_UnionMapWithDecimal(t *testing.T) {
    99  	defer ConfigTeardown()
   100  
   101  	t.Run("low scale", func(t *testing.T) {
   102  		data := []byte{0x02, 0x6, 0x00, 0x87, 0x78}
   103  		schema := `["null", {"type": "bytes", "logicalType": "decimal", "precision": 4, "scale": 2}]`
   104  		dec, _ := avro.NewDecoder(schema, bytes.NewReader(data))
   105  
   106  		var got map[string]any
   107  		err := dec.Decode(&got)
   108  
   109  		require.NoError(t, err)
   110  		assert.Equal(t, big.NewRat(1734, 5), got["bytes.decimal"])
   111  	})
   112  
   113  	t.Run("high scale", func(t *testing.T) {
   114  		data := []byte{0x2, 0x22, 0x65, 0xea, 0x55, 0xc, 0x11, 0x8, 0xf7, 0xc3, 0xb8, 0xec, 0x53, 0xff, 0x80, 0x0, 0x0, 0x0, 0x0}
   115  		schema := `["null", {"type": "bytes", "logicalType": "decimal", "precision": 77, "scale": 38}]`
   116  		dec, _ := avro.NewDecoder(schema, bytes.NewReader(data))
   117  
   118  		var got map[string]any
   119  		err := dec.Decode(&got)
   120  
   121  		require.NoError(t, err)
   122  		assert.Equal(t, big.NewRat(1734, 5), got["bytes.decimal"])
   123  	})
   124  }
   125  
   126  func TestDecoder_UnionMapInvalidSchema(t *testing.T) {
   127  	defer ConfigTeardown()
   128  
   129  	data := []byte{0x04}
   130  	schema := `["null", "string"]`
   131  	dec, _ := avro.NewDecoder(schema, bytes.NewReader(data))
   132  
   133  	var got map[string]any
   134  	err := dec.Decode(&got)
   135  
   136  	assert.Error(t, err)
   137  }
   138  
   139  func TestDecoder_UnionMapInvalidMap(t *testing.T) {
   140  	defer ConfigTeardown()
   141  
   142  	data := []byte{0x02, 0x06, 0x66, 0x6F, 0x6F}
   143  	schema := `["null", "string"]`
   144  	dec, _ := avro.NewDecoder(schema, bytes.NewReader(data))
   145  
   146  	var got map[string]string
   147  	err := dec.Decode(&got)
   148  
   149  	assert.Error(t, err)
   150  }
   151  
   152  func TestDecoder_UnionPtr(t *testing.T) {
   153  	defer ConfigTeardown()
   154  
   155  	data := []byte{0x02, 0x06, 0x66, 0x6F, 0x6F}
   156  	schema := `["null", "string"]`
   157  	dec, _ := avro.NewDecoder(schema, bytes.NewReader(data))
   158  
   159  	var got *string
   160  	err := dec.Decode(&got)
   161  
   162  	want := "foo"
   163  	require.NoError(t, err)
   164  	assert.Equal(t, &want, got)
   165  }
   166  
   167  func TestDecoder_UnionPtrReversed(t *testing.T) {
   168  	defer ConfigTeardown()
   169  
   170  	data := []byte{0x00, 0x06, 0x66, 0x6F, 0x6F}
   171  	schema := `["string", "null"]`
   172  	dec, _ := avro.NewDecoder(schema, bytes.NewReader(data))
   173  
   174  	var got *string
   175  	err := dec.Decode(&got)
   176  
   177  	want := "foo"
   178  	require.NoError(t, err)
   179  	assert.Equal(t, &want, got)
   180  }
   181  
   182  func TestDecoder_UnionPtrReuseInstance(t *testing.T) {
   183  	defer ConfigTeardown()
   184  
   185  	data := []byte{0x02, 0x36, 0x06, 0x66, 0x6F, 0x6F}
   186  	schema := `["null", {"type": "record", "name": "test", "fields" : [{"name": "a", "type": "long"}, {"name": "b", "type": "string"}]}]`
   187  	dec, _ := avro.NewDecoder(schema, bytes.NewReader(data))
   188  
   189  	var original TestRecord
   190  	got := &original
   191  	err := dec.Decode(&got)
   192  
   193  	require.NoError(t, err)
   194  	assert.IsType(t, &TestRecord{}, got)
   195  	assert.Same(t, &original, got)
   196  	assert.Equal(t, int64(27), got.A)
   197  	assert.Equal(t, "foo", got.B)
   198  }
   199  
   200  func TestDecoder_UnionPtrNull(t *testing.T) {
   201  	defer ConfigTeardown()
   202  
   203  	data := []byte{0x00}
   204  	schema := `["null", "string"]`
   205  	dec, _ := avro.NewDecoder(schema, bytes.NewReader(data))
   206  
   207  	var got *string
   208  	err := dec.Decode(&got)
   209  
   210  	require.NoError(t, err)
   211  	assert.Nil(t, got)
   212  }
   213  
   214  func TestDecoder_UnionPtrReversedNull(t *testing.T) {
   215  	defer ConfigTeardown()
   216  
   217  	data := []byte{0x02}
   218  	schema := `["string", "null"]`
   219  	dec, _ := avro.NewDecoder(schema, bytes.NewReader(data))
   220  
   221  	var got *string
   222  	err := dec.Decode(&got)
   223  
   224  	require.NoError(t, err)
   225  	assert.Nil(t, got)
   226  }
   227  
   228  func TestDecoder_UnionNullableSlice(t *testing.T) {
   229  	defer ConfigTeardown()
   230  
   231  	data := []byte{0x02, 0x06, 0x66, 0x6F, 0x6F}
   232  	schema := `["null", "bytes"]`
   233  	dec, _ := avro.NewDecoder(schema, bytes.NewReader(data))
   234  
   235  	var got []byte
   236  	err := dec.Decode(&got)
   237  
   238  	want := []byte("foo")
   239  	require.NoError(t, err)
   240  	assert.Equal(t, want, got)
   241  }
   242  
   243  func TestDecoder_UnionNullableSliceNull(t *testing.T) {
   244  	defer ConfigTeardown()
   245  
   246  	data := []byte{0x00}
   247  	schema := `["null", "bytes"]`
   248  	dec, _ := avro.NewDecoder(schema, bytes.NewReader(data))
   249  
   250  	var got []byte
   251  	err := dec.Decode(&got)
   252  
   253  	require.NoError(t, err)
   254  	assert.Nil(t, got)
   255  }
   256  
   257  func TestDecoder_UnionNullableSliceNotNullButEmpty(t *testing.T) {
   258  	defer ConfigTeardown()
   259  
   260  	data := []byte{0x02, 0x00}
   261  	schema := `["null", "bytes"]`
   262  	dec, _ := avro.NewDecoder(schema, bytes.NewReader(data))
   263  
   264  	var got []byte
   265  	err := dec.Decode(&got)
   266  
   267  	require.NoError(t, err)
   268  	assert.NotNil(t, got)
   269  	assert.Empty(t, got)
   270  }
   271  
   272  func TestDecoder_UnionPtrInvalidSchema(t *testing.T) {
   273  	defer ConfigTeardown()
   274  
   275  	data := []byte{0x04}
   276  	schema := `["null", "string"]`
   277  	dec, _ := avro.NewDecoder(schema, bytes.NewReader(data))
   278  
   279  	var got *string
   280  	err := dec.Decode(&got)
   281  
   282  	assert.Error(t, err)
   283  }
   284  
   285  func TestDecoder_UnionPtrNotNullable(t *testing.T) {
   286  	defer ConfigTeardown()
   287  
   288  	data := []byte{0x02, 0x06, 0x66, 0x6F, 0x6F}
   289  	schema := `["null", "string", "int"]`
   290  	dec, _ := avro.NewDecoder(schema, bytes.NewReader(data))
   291  
   292  	var got *string
   293  	err := dec.Decode(&got)
   294  
   295  	assert.Error(t, err)
   296  }
   297  
   298  func TestDecoder_UnionInterface(t *testing.T) {
   299  	defer ConfigTeardown()
   300  
   301  	data := []byte{0x02, 0x36}
   302  	schema := `["null", "int"]`
   303  	dec, _ := avro.NewDecoder(schema, bytes.NewReader(data))
   304  
   305  	var got any
   306  	err := dec.Decode(&got)
   307  
   308  	require.NoError(t, err)
   309  	assert.Equal(t, 27, got)
   310  }
   311  
   312  func TestDecoder_UnionInterfaceInRecord(t *testing.T) {
   313  	defer ConfigTeardown()
   314  
   315  	data := []byte{0x02, 0x36}
   316  	schema := `{
   317  	"type": "record",
   318  	"name": "test",
   319  	"fields" : [
   320  		{"name": "a", "type": ["null", "int"]}
   321  	]
   322  }`
   323  	dec, _ := avro.NewDecoder(schema, bytes.NewReader(data))
   324  
   325  	got := &TestUnion{}
   326  	err := dec.Decode(&got)
   327  
   328  	require.NoError(t, err)
   329  	assert.Equal(t, 27, got.A)
   330  }
   331  
   332  func TestDecoder_UnionInterfaceInMap(t *testing.T) {
   333  	defer ConfigTeardown()
   334  
   335  	avro.Register("map:int", map[string]int{})
   336  
   337  	data := []byte{0x01, 0x0c, 0x06, 0x66, 0x6f, 0x6f, 0x00, 0x36, 0x00}
   338  	schema := `{"type": "map", "values": ["int", "string"]}`
   339  	dec, _ := avro.NewDecoder(schema, bytes.NewReader(data))
   340  
   341  	var got map[string]any
   342  	err := dec.Decode(&got)
   343  
   344  	require.NoError(t, err)
   345  	assert.Equal(t, map[string]any{"foo": 27}, got)
   346  }
   347  
   348  func TestDecoder_UnionInterfaceInMapWithBool(t *testing.T) {
   349  	defer ConfigTeardown()
   350  
   351  	data := []byte{0x01, 0x0c, 0x06, 0x66, 0x6F, 0x6F, 0x02, 0x01, 0x00}
   352  	schema := `{"type":"map", "values": ["null", "boolean"]}`
   353  	dec, _ := avro.NewDecoder(schema, bytes.NewReader(data))
   354  
   355  	var got map[string]any
   356  	err := dec.Decode(&got)
   357  
   358  	require.NoError(t, err)
   359  	assert.Equal(t, map[string]any{"foo": true}, got)
   360  }
   361  
   362  func TestDecoder_UnionInterfaceMap(t *testing.T) {
   363  	defer ConfigTeardown()
   364  
   365  	avro.Register("map:int", map[string]int{})
   366  
   367  	data := []byte{0x02, 0x01, 0x0a, 0x06, 0x66, 0x6f, 0x6f, 0x36, 0x00}
   368  	schema := `["int", {"type": "map", "values": "int"}]`
   369  	dec, _ := avro.NewDecoder(schema, bytes.NewReader(data))
   370  
   371  	var got any
   372  	err := dec.Decode(&got)
   373  
   374  	require.NoError(t, err)
   375  	assert.Equal(t, map[string]int{"foo": 27}, got)
   376  }
   377  
   378  func TestDecoder_UnionInterfaceMapNamed(t *testing.T) {
   379  	defer ConfigTeardown()
   380  
   381  	avro.Register("map:test", map[string]string{})
   382  
   383  	data := []byte{0x02, 0x01, 0x0a, 0x06, 0x66, 0x6f, 0x6f, 0x02, 0x00}
   384  	schema := `["int", {"type": "map", "values": {"type":"enum", "name": "test", "symbols": ["A", "B"]}}]`
   385  	dec, _ := avro.NewDecoder(schema, bytes.NewReader(data))
   386  
   387  	var got any
   388  	err := dec.Decode(&got)
   389  
   390  	require.NoError(t, err)
   391  	assert.Equal(t, map[string]string{"foo": "B"}, got)
   392  }
   393  
   394  func TestDecoder_UnionInterfaceArray(t *testing.T) {
   395  	defer ConfigTeardown()
   396  
   397  	avro.Register("array:int", []int{})
   398  
   399  	data := []byte{0x02, 0x01, 0x02, 0x36, 0x00}
   400  	schema := `["int", {"type": "array", "items": "int"}]`
   401  	dec, _ := avro.NewDecoder(schema, bytes.NewReader(data))
   402  
   403  	var got any
   404  	err := dec.Decode(&got)
   405  
   406  	require.NoError(t, err)
   407  	assert.Equal(t, []int{27}, got)
   408  }
   409  
   410  func TestDecoder_UnionInterfaceArrayNamed(t *testing.T) {
   411  	defer ConfigTeardown()
   412  
   413  	avro.Register("array:test", []string{})
   414  
   415  	data := []byte{0x02, 0x01, 0x02, 0x02, 0x00}
   416  	schema := `["int", {"type": "array", "items": {"type":"enum", "name": "test", "symbols": ["A", "B"]}}]`
   417  	dec, _ := avro.NewDecoder(schema, bytes.NewReader(data))
   418  
   419  	var got any
   420  	err := dec.Decode(&got)
   421  
   422  	require.NoError(t, err)
   423  	assert.Equal(t, []string{"B"}, got)
   424  }
   425  
   426  func TestDecoder_UnionInterfaceNull(t *testing.T) {
   427  	defer ConfigTeardown()
   428  
   429  	data := []byte{0x00}
   430  	schema := `["null", "string"]`
   431  	dec, _ := avro.NewDecoder(schema, bytes.NewReader(data))
   432  
   433  	var got any
   434  	err := dec.Decode(&got)
   435  
   436  	require.NoError(t, err)
   437  	assert.Equal(t, nil, got)
   438  }
   439  
   440  func TestDecoder_UnionInterfaceNamed(t *testing.T) {
   441  	defer ConfigTeardown()
   442  
   443  	avro.Register("test", "")
   444  
   445  	data := []byte{0x02, 0x02}
   446  	schema := `["null", {"type":"enum", "name": "test", "symbols": ["A", "B"]}]`
   447  	dec, _ := avro.NewDecoder(schema, bytes.NewReader(data))
   448  
   449  	var got any
   450  	err := dec.Decode(&got)
   451  
   452  	require.NoError(t, err)
   453  	assert.Equal(t, "B", got)
   454  }
   455  
   456  func TestDecoder_UnionInterfaceRecord(t *testing.T) {
   457  	defer ConfigTeardown()
   458  
   459  	avro.Register("test", &TestRecord{})
   460  
   461  	data := []byte{0x02, 0x36, 0x06, 0x66, 0x6F, 0x6F}
   462  	schema := `["int", {"type": "record", "name": "test", "fields" : [{"name": "a", "type": "long"}, {"name": "b", "type": "string"}]}]`
   463  	dec, _ := avro.NewDecoder(schema, bytes.NewReader(data))
   464  
   465  	var got any
   466  	err := dec.Decode(&got)
   467  
   468  	require.NoError(t, err)
   469  	assert.IsType(t, &TestRecord{}, got)
   470  	rec := got.(*TestRecord)
   471  	assert.Equal(t, int64(27), rec.A)
   472  	assert.Equal(t, "foo", rec.B)
   473  }
   474  
   475  func TestDecoder_UnionInterfaceRecordNotReused(t *testing.T) {
   476  	defer ConfigTeardown()
   477  
   478  	avro.Register("test", &TestRecord{})
   479  
   480  	data := []byte{0x02, 0x36, 0x06, 0x66, 0x6F, 0x6F}
   481  	schema := `["int", {"type": "record", "name": "test", "fields" : [{"name": "a", "type": "long"}, {"name": "b", "type": "string"}]}]`
   482  	dec, _ := avro.NewDecoder(schema, bytes.NewReader(data))
   483  
   484  	var got any = ""
   485  	err := dec.Decode(&got)
   486  
   487  	require.NoError(t, err)
   488  	assert.IsType(t, &TestRecord{}, got)
   489  	rec := got.(*TestRecord)
   490  	assert.Equal(t, int64(27), rec.A)
   491  	assert.Equal(t, "foo", rec.B)
   492  }
   493  
   494  func TestDecoder_UnionInterfaceUnresolvableType(t *testing.T) {
   495  	defer ConfigTeardown()
   496  
   497  	data := []byte{0x02, 0x36, 0x06, 0x66, 0x6F, 0x6F}
   498  	schema := `["int", {"type": "record", "name": "test", "fields" : [{"name": "a", "type": "long"}, {"name": "b", "type": "string"}]}]`
   499  	dec, _ := avro.NewDecoder(schema, bytes.NewReader(data))
   500  
   501  	var got any
   502  	err := dec.Decode(&got)
   503  
   504  	require.NoError(t, err)
   505  	assert.IsType(t, map[string]any{}, got)
   506  	m := got.(map[string]any)
   507  	assert.IsType(t, map[string]any{}, m["test"])
   508  	assert.Equal(t, int64(27), m["test"].(map[string]any)["a"])
   509  	assert.Equal(t, "foo", m["test"].(map[string]any)["b"])
   510  }
   511  
   512  func TestDecoder_UnionInterfaceDualRecords(t *testing.T) {
   513  	defer ConfigTeardown()
   514  
   515  	avro.Register("test", &TestRecord{})
   516  	avro.Register("otherTest", &TestRecord{})
   517  
   518  	data := []byte{0x02, 0x36, 0x06, 0x66, 0x6F, 0x6F}
   519  	schema := `[
   520  		"int", 
   521  		{"type": "record", "name": "test", "fields" : [{"name": "a", "type": "long"}, {"name": "b", "type": "string"}]},
   522  		{"type": "record", "name": "otherTest", "fields" : [{"name": "a", "type": "long"}, {"name": "b", "type": "string"}]}
   523  	]`
   524  	dec, _ := avro.NewDecoder(schema, bytes.NewReader(data))
   525  
   526  	var got any
   527  	err := dec.Decode(&got)
   528  
   529  	require.NoError(t, err)
   530  	assert.IsType(t, &TestRecord{}, got)
   531  	rec := got.(*TestRecord)
   532  	assert.Equal(t, int64(27), rec.A)
   533  	assert.Equal(t, "foo", rec.B)
   534  }
   535  
   536  func TestDecoder_UnionInterfaceDualRecordsUnresolvableType(t *testing.T) {
   537  	defer ConfigTeardown()
   538  
   539  	avro.Register("test", &TestRecord{})
   540  
   541  	data := []byte{0x02, 0x36, 0x06, 0x66, 0x6F, 0x6F}
   542  	schema := `[
   543  		"int", 
   544  		{"type": "record", "name": "test", "fields" : [{"name": "a", "type": "long"}, {"name": "b", "type": "string"}]},
   545  		{"type": "record", "name": "otherTest", "fields" : [{"name": "a", "type": "long"}, {"name": "b", "type": "string"}]}
   546  	]`
   547  	dec, _ := avro.NewDecoder(schema, bytes.NewReader(data))
   548  
   549  	var got any
   550  	err := dec.Decode(&got)
   551  
   552  	require.NoError(t, err)
   553  	assert.IsType(t, map[string]any{}, got)
   554  	m := got.(map[string]any)
   555  	assert.IsType(t, map[string]any{}, m["test"])
   556  	assert.Equal(t, int64(27), m["test"].(map[string]any)["a"])
   557  	assert.Equal(t, "foo", m["test"].(map[string]any)["b"])
   558  }
   559  
   560  func TestDecoder_UnionInterfaceDualRecordsPartialResolution(t *testing.T) {
   561  	defer ConfigTeardown()
   562  
   563  	avro.DefaultConfig = avro.Config{PartialUnionTypeResolution: true}.Freeze()
   564  
   565  	avro.Register("test", &TestRecord{})
   566  
   567  	data := []byte{0x02, 0x36, 0x06, 0x66, 0x6F, 0x6F}
   568  	schema := `[
   569  		"int", 
   570  		{"type": "record", "name": "test", "fields" : [{"name": "a", "type": "long"}, {"name": "b", "type": "string"}]},
   571  		{"type": "record", "name": "otherTest", "fields" : [{"name": "a", "type": "long"}, {"name": "b", "type": "string"}]}
   572  	]`
   573  	dec, _ := avro.NewDecoder(schema, bytes.NewReader(data))
   574  
   575  	var got any
   576  	err := dec.Decode(&got)
   577  
   578  	require.NoError(t, err)
   579  	assert.IsType(t, &TestRecord{}, got)
   580  	rec := got.(*TestRecord)
   581  	assert.Equal(t, int64(27), rec.A)
   582  	assert.Equal(t, "foo", rec.B)
   583  }
   584  
   585  func TestDecoder_UnionInterfaceWithTime(t *testing.T) {
   586  	defer ConfigTeardown()
   587  
   588  	data := []byte{0x02, 0x80, 0xCD, 0xB7, 0xA2, 0xEE, 0xC7, 0xCD, 0x05}
   589  	schema := `["null", {"type": "long", "logicalType": "timestamp-micros"}]`
   590  	dec, _ := avro.NewDecoder(schema, bytes.NewReader(data))
   591  
   592  	var got any
   593  	err := dec.Decode(&got)
   594  
   595  	require.NoError(t, err)
   596  	assert.Equal(t, time.Date(2020, 1, 2, 3, 4, 5, 0, time.UTC), got)
   597  }
   598  
   599  func TestDecoder_UnionInterfaceWithDuration(t *testing.T) {
   600  	defer ConfigTeardown()
   601  
   602  	data := []byte{0x02, 0xAA, 0xB4, 0xDE, 0x75}
   603  	schema := `["null", {"type": "int", "logicalType": "time-millis"}]`
   604  	dec, _ := avro.NewDecoder(schema, bytes.NewReader(data))
   605  
   606  	var got any
   607  	err := dec.Decode(&got)
   608  
   609  	require.NoError(t, err)
   610  	assert.Equal(t, 123456789*time.Millisecond, got)
   611  }
   612  
   613  func TestDecoder_UnionInterfaceWithDecimal(t *testing.T) {
   614  	defer ConfigTeardown()
   615  
   616  	t.Run("low scale", func(t *testing.T) {
   617  		data := []byte{0x02, 0x6, 0x00, 0x87, 0x78}
   618  		schema := `["null", {"type": "bytes", "logicalType": "decimal", "precision": 4, "scale": 2}]`
   619  		dec, _ := avro.NewDecoder(schema, bytes.NewReader(data))
   620  
   621  		var got any
   622  		err := dec.Decode(&got)
   623  
   624  		require.NoError(t, err)
   625  		assert.Equal(t, big.NewRat(1734, 5), got)
   626  	})
   627  
   628  	t.Run("high scale", func(t *testing.T) {
   629  		data := []byte{0x2, 0x22, 0x65, 0xea, 0x55, 0xc, 0x11, 0x8, 0xf7, 0xc3, 0xb8, 0xec, 0x53, 0xff, 0x80, 0x0, 0x0, 0x0, 0x0}
   630  		schema := `["null", {"type": "bytes", "logicalType": "decimal", "precision": 77, "scale": 38}]`
   631  		dec, _ := avro.NewDecoder(schema, bytes.NewReader(data))
   632  
   633  		var got any
   634  		err := dec.Decode(&got)
   635  
   636  		require.NoError(t, err)
   637  		assert.Equal(t, big.NewRat(1734, 5), got)
   638  	})
   639  }
   640  
   641  func TestDecoder_UnionInterfaceWithDecimal_Negative(t *testing.T) {
   642  	defer ConfigTeardown()
   643  
   644  	t.Run("low scale", func(t *testing.T) {
   645  		data := []byte{0x02, 0x6, 0xFF, 0x78, 0x88}
   646  		schema := `["null", {"type": "bytes", "logicalType": "decimal", "precision": 4, "scale": 2}]`
   647  		dec, _ := avro.NewDecoder(schema, bytes.NewReader(data))
   648  
   649  		var got any
   650  		err := dec.Decode(&got)
   651  
   652  		require.NoError(t, err)
   653  		assert.Equal(t, big.NewRat(-1734, 5), got)
   654  	})
   655  	t.Run("high scale", func(t *testing.T) {
   656  		data := []byte{0x2, 0x22, 0x9a, 0x15, 0xaa, 0xf3, 0xee, 0xf7, 0x8, 0x3c, 0x47, 0x13, 0xac, 0x0, 0x80, 0x0, 0x0, 0x0, 0x0}
   657  		schema := `["null", {"type": "bytes", "logicalType": "decimal", "precision": 77, "scale": 38}]`
   658  		dec, _ := avro.NewDecoder(schema, bytes.NewReader(data))
   659  
   660  		var got any
   661  		err := dec.Decode(&got)
   662  
   663  		require.NoError(t, err)
   664  		assert.Equal(t, big.NewRat(-1734, 5), got)
   665  	})
   666  }
   667  
   668  func TestDecoder_UnionInterfaceWithUUID(t *testing.T) {
   669  	defer ConfigTeardown()
   670  
   671  	data := []byte{0x2, 0x48, 0x66, 0x33, 0x36, 0x65, 0x35, 0x38, 0x39, 0x61, 0x2d, 0x33, 0x61, 0x35, 0x32, 0x2d, 0x34, 0x39, 0x32, 0x62, 0x2d, 0x62, 0x39, 0x35, 0x63, 0x2d, 0x64, 0x61, 0x64, 0x33, 0x34, 0x35, 0x65, 0x38, 0x64, 0x32, 0x61, 0x63}
   672  	schema := `["null", {"type": "string", "logicalType": "uuid"}]`
   673  	dec, _ := avro.NewDecoder(schema, bytes.NewReader(data))
   674  
   675  	var got any
   676  	err := dec.Decode(&got)
   677  
   678  	require.NoError(t, err)
   679  	assert.Equal(t, "f36e589a-3a52-492b-b95c-dad345e8d2ac", got)
   680  }
   681  
   682  func TestDecoder_UnionInterfaceUnresolvableTypeWithError(t *testing.T) {
   683  	defer ConfigTeardown()
   684  
   685  	avro.DefaultConfig = avro.Config{UnionResolutionError: true}.Freeze()
   686  
   687  	data := []byte{0x02, 0x36, 0x06, 0x66, 0x6F, 0x6F}
   688  	schema := `["int", {"type": "record", "name": "test", "fields" : [{"name": "a", "type": "long"}, {"name": "b", "type": "string"}]}]`
   689  	dec, _ := avro.NewDecoder(schema, bytes.NewReader(data))
   690  
   691  	var got any
   692  	err := dec.Decode(&got)
   693  
   694  	assert.EqualError(t, err, "avro: problem resolving decoder for Avro union: avro: unable to resolve type with name test")
   695  }
   696  
   697  func TestDecoder_UnionInterfaceInvalidSchema(t *testing.T) {
   698  	defer ConfigTeardown()
   699  
   700  	data := []byte{0x04}
   701  	schema := `["null", "int"]`
   702  	dec, _ := avro.NewDecoder(schema, bytes.NewReader(data))
   703  
   704  	var got any
   705  	err := dec.Decode(&got)
   706  
   707  	assert.Error(t, err)
   708  }