Skip to content

Commit 846cc25

Browse files
bug fix
1 parent 6bc3a00 commit 846cc25

2 files changed

Lines changed: 116 additions & 90 deletions

File tree

schema/schema.go

Lines changed: 92 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -414,7 +414,7 @@ func (s SchemaMap) Decode(seq *access.SeqGetAccess) (any, error) {
414414

415415
// Encode writes an OrderedMapAny into the sequence according to the SchemaMap.
416416
func (s SchemaMap) Encode(put *access.PutAccess, val any) error {
417-
if s.IsNullable() && val == nil && len(s.Schemas) < 1 {
417+
if s.IsNullable() && val == nil || len(s.Schemas) < 1 {
418418
put.AddMapAny(nil, true)
419419
return nil
420420
}
@@ -1393,15 +1393,15 @@ func (s SchemaMapUnordered) IsNullable() bool {
13931393

13941394
func (s SchemaMapUnordered) Validate(seq *access.SeqGetAccess) error {
13951395
pos := seq.CurrentIndex()
1396-
typ, _, err := seq.PeekTypeWidth()
1396+
typ, w, err := seq.PeekTypeWidth()
13971397
if err != nil {
13981398
return NewSchemaError(ErrInvalidFormat, SchemaMapUnorderedName, "", pos, err)
13991399
}
14001400
if typ != typetags.TypeMap {
14011401
return NewSchemaError(ErrConstraintViolated, SchemaMapUnorderedName, "", pos, ErrUnsupportedType)
14021402
}
14031403

1404-
if len(s.Fields) > 0 {
1404+
if w != 0 && len(s.Fields) > 0 {
14051405
subseq, err := seq.PeekNestedSeq()
14061406
if err != nil {
14071407
return NewSchemaError(ErrInvalidFormat, SchemaMapUnorderedName, "", pos, err)
@@ -1452,7 +1452,7 @@ func (s SchemaMapUnordered) Validate(seq *access.SeqGetAccess) error {
14521452

14531453
func (s SchemaMapUnordered) Decode(seq *access.SeqGetAccess) (any, error) {
14541454
pos := seq.CurrentIndex()
1455-
typ, _, err := seq.PeekTypeWidth()
1455+
typ, w, err := seq.PeekTypeWidth()
14561456
if err != nil {
14571457
return nil, NewSchemaError(ErrInvalidFormat, SchemaMapUnorderedName, "", pos, err)
14581458
}
@@ -1461,7 +1461,7 @@ func (s SchemaMapUnordered) Decode(seq *access.SeqGetAccess) (any, error) {
14611461
}
14621462

14631463
var out map[string]any
1464-
if len(s.Fields) > 0 {
1464+
if w != 0 && len(s.Fields) > 0 {
14651465
subseq, err := seq.PeekNestedSeq()
14661466
if err != nil {
14671467
return nil, NewSchemaError(ErrInvalidFormat, SchemaMapUnorderedName, "", pos, err)
@@ -1506,6 +1506,9 @@ func (s SchemaMapUnordered) Decode(seq *access.SeqGetAccess) (any, error) {
15061506
if err := seq.Advance(); err != nil {
15071507
return nil, NewSchemaError(ErrUnexpectedEOF, SchemaMapUnorderedName, "", pos, err)
15081508
}
1509+
if out == nil {
1510+
return nil, nil
1511+
}
15091512
return out, nil
15101513
}
15111514

@@ -1563,18 +1566,18 @@ func (s TupleSchema) IsNullable() bool {
15631566

15641567
func (s TupleSchema) Validate(seq *access.SeqGetAccess) error {
15651568
pos := seq.CurrentIndex()
1566-
_, err := precheck(TupleSchemaName, pos, seq, typetags.TypeTuple, -1, s.IsNullable())
1569+
w, err := precheck(TupleSchemaName, pos, seq, typetags.TypeTuple, -1, s.IsNullable())
15671570
if err != nil {
15681571
return err
15691572
}
1570-
w := len(s.Schemas)
1573+
argCount := len(s.Schemas)
15711574
if w != 0 {
15721575
sub, err := seq.PeekNestedSeq()
15731576
if err != nil {
15741577
return NewSchemaError(ErrInvalidFormat, TupleSchemaName, "", pos, err)
15751578
}
1576-
if w > 0 && sub.ArgCount() != w && !s.VariableLength {
1577-
return NewSchemaError(ErrConstraintViolated, TupleSchemaName, "", pos, SizeExact{Actual: w, Exact: sub.ArgCount()})
1579+
if argCount > 0 && sub.ArgCount() != argCount && !s.VariableLength {
1580+
return NewSchemaError(ErrConstraintViolated, TupleSchemaName, "", pos, SizeExact{Actual: argCount, Exact: sub.ArgCount()})
15781581
}
15791582
for _, sch := range s.Schemas {
15801583
if err := sch.Validate(sub); err != nil {
@@ -1590,19 +1593,19 @@ func (s TupleSchema) Validate(seq *access.SeqGetAccess) error {
15901593

15911594
func (s TupleSchema) Decode(seq *access.SeqGetAccess) (any, error) {
15921595
pos := seq.CurrentIndex()
1593-
_, err := precheck(TupleSchemaName, pos, seq, typetags.TypeTuple, -1, s.IsNullable())
1596+
w, err := precheck(TupleSchemaName, pos, seq, typetags.TypeTuple, -1, s.IsNullable())
15941597
if err != nil {
15951598
return nil, err
15961599
}
15971600
var out []any
1598-
w := len(s.Schemas)
1601+
argCount := len(s.Schemas)
15991602
if w != 0 {
16001603
sub, err := seq.PeekNestedSeq()
16011604
if err != nil {
16021605
return nil, NewSchemaError(ErrInvalidFormat, TupleSchemaName, "", pos, err)
16031606
}
1604-
if w > 0 && sub.ArgCount() != w && !s.VariableLength {
1605-
return nil, NewSchemaError(ErrConstraintViolated, TupleSchemaName, "", pos, SizeExact{Actual: w, Exact: sub.ArgCount()})
1607+
if argCount > 0 && sub.ArgCount() != argCount && !s.VariableLength {
1608+
return nil, NewSchemaError(ErrConstraintViolated, TupleSchemaName, "", pos, SizeExact{Actual: argCount, Exact: sub.ArgCount()})
16061609
}
16071610
out = make([]any, 0, sub.ArgCount())
16081611
for _, sch := range s.Schemas {
@@ -1624,6 +1627,9 @@ func (s TupleSchema) Decode(seq *access.SeqGetAccess) (any, error) {
16241627
if err := seq.Advance(); err != nil {
16251628
return nil, NewSchemaError(ErrUnexpectedEOF, TupleSchemaName, "", pos, err)
16261629
}
1630+
if out == nil {
1631+
return nil, nil
1632+
}
16271633
return out, nil
16281634
}
16291635

@@ -1721,18 +1727,18 @@ func (s TupleSchemaNamed) Validate(seq *access.SeqGetAccess) error {
17211727
return NewSchemaError(ErrConstraintViolated, TupleSchemaNamedName, "", 0, SizeExact{Actual: len(s.FieldNames), Exact: len(s.Schemas)})
17221728
}
17231729
pos := seq.CurrentIndex()
1724-
_, err := precheck(TupleSchemaNamedName, pos, seq, typetags.TypeTuple, -1, s.IsNullable())
1730+
w, err := precheck(TupleSchemaNamedName, pos, seq, typetags.TypeTuple, -1, s.IsNullable())
17251731
if err != nil {
17261732
return err
17271733
}
1728-
w := len(s.Schemas)
1734+
argCount := len(s.Schemas)
17291735
if w != 0 {
17301736
sub, err := seq.PeekNestedSeq()
17311737
if err != nil {
17321738
return NewSchemaError(ErrInvalidFormat, TupleSchemaNamedName, "", pos, err)
17331739
}
1734-
if w > 0 && sub.ArgCount() != w {
1735-
return NewSchemaError(ErrConstraintViolated, TupleSchemaNamedName, "", pos, SizeExact{Actual: w, Exact: sub.ArgCount()})
1740+
if !s.VariableLength && sub.ArgCount() != argCount {
1741+
return NewSchemaError(ErrConstraintViolated, TupleSchemaNamedName, "", pos, SizeExact{Actual: argCount, Exact: sub.ArgCount()})
17361742
}
17371743
for _, sch := range s.Schemas {
17381744
if err := sch.Validate(sub); err != nil {
@@ -1751,20 +1757,21 @@ func (s TupleSchemaNamed) Decode(seq *access.SeqGetAccess) (any, error) {
17511757
return nil, NewSchemaError(ErrConstraintViolated, TupleSchemaNamedName, "", 0, SizeExact{Actual: len(s.FieldNames), Exact: len(s.Schemas)})
17521758
}
17531759
pos := seq.CurrentIndex()
1754-
_, err := precheck(TupleSchemaNamedName, pos, seq, typetags.TypeTuple, -1, s.IsNullable())
1760+
w, err := precheck(TupleSchemaNamedName, pos, seq, typetags.TypeTuple, -1, s.IsNullable())
17551761
if err != nil {
17561762
return nil, err
17571763
}
17581764

1759-
out := make(map[string]any)
1760-
w := len(s.Schemas)
1761-
if w > 0 {
1765+
var out map[string]any = nil
1766+
argCount := len(s.Schemas)
1767+
if w != 0 {
1768+
out = make(map[string]any, argCount)
17621769
sub, err := seq.PeekNestedSeq()
17631770
if err != nil {
17641771
return nil, NewSchemaError(ErrInvalidFormat, TupleSchemaNamedName, "", pos, err)
17651772
}
1766-
if !s.VariableLength && sub.ArgCount() != w {
1767-
return nil, NewSchemaError(ErrConstraintViolated, TupleSchemaNamedName, "", pos, SizeExact{Actual: w, Exact: sub.ArgCount()})
1773+
if !s.VariableLength && sub.ArgCount() != argCount {
1774+
return nil, NewSchemaError(ErrConstraintViolated, TupleSchemaNamedName, "", pos, SizeExact{Actual: argCount, Exact: sub.ArgCount()})
17681775
}
17691776
for i, sch := range s.Schemas {
17701777
v, err := sch.Decode(sub)
@@ -1787,6 +1794,9 @@ func (s TupleSchemaNamed) Decode(seq *access.SeqGetAccess) (any, error) {
17871794
if err := seq.Advance(); err != nil {
17881795
return nil, NewSchemaError(ErrUnexpectedEOF, TupleSchemaNamedName, "", pos, err)
17891796
}
1797+
if out == nil {
1798+
return nil, nil
1799+
}
17901800
return out, nil
17911801
}
17921802

@@ -2364,34 +2374,34 @@ func (s SchemaMapRepeat) Validate(seq *access.SeqGetAccess) error {
23642374
if err != nil {
23652375
return err
23662376
}
2367-
if w == 0 && s.IsNullable() {
2368-
return nil
2369-
}
2370-
subseq, err := seq.PeekNestedSeq()
2371-
if err != nil {
2372-
return NewSchemaError(ErrInvalidFormat, SchemaMapRepeatName, "", pos, err)
2373-
}
2374-
pairCount := subseq.ArgCount() / 2
2375-
maxIter := pairCount
2376-
if s.max != -1 && s.max < pairCount {
2377-
maxIter = s.max
2378-
}
2379-
if s.min != -1 && pairCount < s.min {
2380-
return NewSchemaError(ErrConstraintViolated, SchemaMapRepeatName, "", pos,
2381-
RangeErrorDetails[int64]{
2382-
Min: PtrToInt64(s.min),
2383-
Max: PtrToInt64(s.max),
2384-
Actual: int64(pairCount),
2385-
})
2386-
}
2387-
2388-
for i := 0; i < maxIter; i++ {
2377+
if w != 0 {
23892378

2390-
if err := s.Key.Validate(subseq); err != nil {
2379+
subseq, err := seq.PeekNestedSeq()
2380+
if err != nil {
23912381
return NewSchemaError(ErrInvalidFormat, SchemaMapRepeatName, "", pos, err)
23922382
}
2393-
if err := s.Value.Validate(subseq); err != nil {
2394-
return NewSchemaError(ErrInvalidFormat, SchemaMapRepeatName, "", pos, err)
2383+
pairCount := subseq.ArgCount() / 2
2384+
maxIter := pairCount
2385+
if s.max != -1 && s.max < pairCount {
2386+
maxIter = s.max
2387+
}
2388+
if s.min != -1 && pairCount < s.min {
2389+
return NewSchemaError(ErrConstraintViolated, SchemaMapRepeatName, "", pos,
2390+
RangeErrorDetails[int64]{
2391+
Min: PtrToInt64(s.min),
2392+
Max: PtrToInt64(s.max),
2393+
Actual: int64(pairCount),
2394+
})
2395+
}
2396+
2397+
for i := 0; i < maxIter; i++ {
2398+
2399+
if err := s.Key.Validate(subseq); err != nil {
2400+
return NewSchemaError(ErrInvalidFormat, SchemaMapRepeatName, "", pos, err)
2401+
}
2402+
if err := s.Value.Validate(subseq); err != nil {
2403+
return NewSchemaError(ErrInvalidFormat, SchemaMapRepeatName, "", pos, err)
2404+
}
23952405
}
23962406
}
23972407

@@ -2407,46 +2417,48 @@ func (s SchemaMapRepeat) Decode(seq *access.SeqGetAccess) (any, error) {
24072417
if err != nil {
24082418
return nil, err
24092419
}
2410-
if w == 0 && s.IsNullable() {
2411-
return nil, nil
2412-
}
2413-
subseq, err := seq.PeekNestedSeq()
2414-
if err != nil {
2415-
return nil, NewSchemaError(ErrInvalidFormat, SchemaMapRepeatName, "", pos, err)
2416-
}
2417-
pairCount := subseq.ArgCount() / 2
2418-
maxIter := pairCount
2419-
if s.max != -1 && s.max < pairCount {
2420-
maxIter = s.max
2421-
}
2422-
if s.min != -1 && pairCount < s.min {
2423-
return nil, NewSchemaError(ErrConstraintViolated, SchemaMapRepeatName, "", pos,
2424-
RangeErrorDetails[int64]{
2425-
Min: PtrToInt64(s.min),
2426-
Max: PtrToInt64(s.max),
2427-
Actual: int64(pairCount),
2428-
})
2429-
}
2430-
out := make(map[string]any)
2431-
for i := 0; i < maxIter; i++ {
2432-
k, err := s.Key.Decode(subseq)
2433-
if err != nil {
2434-
return nil, NewSchemaError(ErrInvalidFormat, SchemaMapRepeatName, "", pos, err)
2435-
}
2436-
v, err := s.Value.Decode(subseq)
2420+
var out map[string]any = nil
2421+
if w != 0 {
2422+
subseq, err := seq.PeekNestedSeq()
24372423
if err != nil {
24382424
return nil, NewSchemaError(ErrInvalidFormat, SchemaMapRepeatName, "", pos, err)
24392425
}
2440-
if keyStr, ok := k.(string); ok {
2441-
out[keyStr] = v
2442-
} else {
2443-
return nil, NewSchemaError(ErrInvalidFormat, SchemaMapRepeatName, "", pos-1, ErrUnsupportedType)
2426+
pairCount := subseq.ArgCount() / 2
2427+
maxIter := pairCount
2428+
if s.max != -1 && s.max < pairCount {
2429+
maxIter = s.max
2430+
}
2431+
if s.min != -1 && pairCount < s.min {
2432+
return nil, NewSchemaError(ErrConstraintViolated, SchemaMapRepeatName, "", pos,
2433+
RangeErrorDetails[int64]{
2434+
Min: PtrToInt64(s.min),
2435+
Max: PtrToInt64(s.max),
2436+
Actual: int64(pairCount),
2437+
})
2438+
}
2439+
out = make(map[string]any, pairCount)
2440+
for i := 0; i < maxIter; i++ {
2441+
k, err := s.Key.Decode(subseq)
2442+
if err != nil {
2443+
return nil, NewSchemaError(ErrInvalidFormat, SchemaMapRepeatName, "", pos, err)
2444+
}
2445+
v, err := s.Value.Decode(subseq)
2446+
if err != nil {
2447+
return nil, NewSchemaError(ErrInvalidFormat, SchemaMapRepeatName, "", pos, err)
2448+
}
2449+
if keyStr, ok := k.(string); ok {
2450+
out[keyStr] = v
2451+
} else {
2452+
return nil, NewSchemaError(ErrInvalidFormat, SchemaMapRepeatName, "", pos-1, ErrUnsupportedType)
2453+
}
24442454
}
24452455
}
2446-
24472456
if err := seq.Advance(); err != nil {
24482457
return nil, NewSchemaError(ErrUnexpectedEOF, SchemaMapRepeatName, "", pos, err)
24492458
}
2459+
if out == nil {
2460+
return nil, nil
2461+
}
24502462
return out, nil
24512463
}
24522464

schema/schema_test.go

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -841,23 +841,31 @@ func TestEncodePackedEmptyTuples2(t *testing.T) {
841841
pack.PackInt16(5),
842842
pack.PackTuple(),
843843
pack.PackTuple(),
844+
pack.PackTuple(),
845+
pack.PackTuple(),
844846
pack.PackInt16(5),
845847
)
846848

847849
chain := SChain(
848850
SInt16,
851+
STuple(SString, SString, SString),
849852
STuple(),
850-
STuple(),
853+
STupleNamed([]string{"ok"}, SString),
854+
STupleNamed(nil),
851855
SInt16,
852856
)
853857

854-
val := []any{int16(5), nil, nil, int16(5)}
858+
val := []any{int16(5), nil, nil, nil, nil, int16(5)}
855859

856860
actual, err := EncodeValue(val, chain)
857861
if err != nil {
858862
t.Log(err)
859863
}
860-
assert.Equal(t, expected, actual)
864+
require.Equal(t, expected, actual)
865+
866+
decoded, err := DecodeBuffer(actual, chain)
867+
require.NoError(t, err)
868+
assert.EqualValues(t, val, decoded)
861869
}
862870
func TestEncodeDecodePackedEmptyMap(t *testing.T) {
863871
expected := pack.Pack(
@@ -868,21 +876,27 @@ func TestEncodeDecodePackedEmptyMap(t *testing.T) {
868876
pack.PackMap{},
869877
pack.PackMapStrInt32{},
870878
pack.PackMapStrInt64{},
879+
pack.PackMap{},
880+
pack.PackMap{},
881+
pack.PackMap{},
871882
pack.PackInt16(5),
872883
)
873884

874885
chain := SChain(
875886
SInt16,
876-
SMap(),
877-
SMap(),
878-
SMap(),
879-
SMap(),
880-
SMap(),
881-
SMap(),
887+
SMap(SString, SString),
888+
SMap(SString, SString),
889+
SMap(SString, SString),
890+
SMap(SString, SString),
891+
SMap(SString, SString),
892+
SMap(SString, SString),
893+
SMapRepeat(SString, SString),
894+
SMapRepeat(SString, SString),
895+
SMapUnorderedOptional(map[string]Schema{"ok": SString}),
882896
SInt16,
883897
)
884898

885-
val := []any{int16(5), nil, nil, nil, nil, nil, nil, int16(5)}
899+
val := []any{int16(5), nil, nil, nil, nil, nil, nil, nil, nil, nil, int16(5)}
886900

887901
actual, err := EncodeValue(val, chain)
888902
if err != nil {

0 commit comments

Comments
 (0)