Skip to content

Commit

Permalink
move zio/zngio.Validate to zed.(*Value).Validate (#4291)
Browse files Browse the repository at this point in the history
This function lives in zio/zngio for historical reasons but is more
accessible as a method on zed.Value.
  • Loading branch information
nwt authored Jan 3, 2023
1 parent 5ee342c commit a6ad61f
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 77 deletions.
58 changes: 58 additions & 0 deletions value.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"bytes"
"errors"
"fmt"
"runtime/debug"

"github.com/brimdata/zed/pkg/field"
"github.com/brimdata/zed/pkg/nano"
Expand Down Expand Up @@ -320,3 +321,60 @@ func (v *Value) Under() *Value {
typ, bytes = union.Untag(bytes)
}
}

// Validate checks that v.Bytes is structurally consistent
// with v.Type. It does not check that the actual leaf
// values when parsed are type compatible with the leaf types.
func (v *Value) Validate() (err error) {
defer func() {
if r := recover(); r != nil {
err = fmt.Errorf("panic: %+v\n%s", r, debug.Stack())
}
}()
return v.Walk(func(typ Type, body zcode.Bytes) error {
if typset, ok := typ.(*TypeSet); ok {
if err := checkSet(typset, body); err != nil {
return err
}
return SkipContainer
}
if typ, ok := typ.(*TypeEnum); ok {
if err := checkEnum(typ, body); err != nil {
return err
}
return SkipContainer
}
return nil
})
}

func checkSet(typ *TypeSet, body zcode.Bytes) error {
if body == nil {
return nil
}
it := body.Iter()
var prev zcode.Bytes
for !it.Done() {
tagAndBody := it.NextTagAndBody()
if prev != nil {
switch bytes.Compare(prev, tagAndBody) {
case 0:
return errors.New("invalid ZNG: duplicate set element")
case 1:
return errors.New("invalid ZNG: set elements not sorted")
}
}
prev = tagAndBody
}
return nil
}

func checkEnum(typ *TypeEnum, body zcode.Bytes) error {
if body == nil {
return nil
}
if selector := DecodeUint(body); int(selector) >= len(typ.Symbols) {
return errors.New("enum selector out of range")
}
return nil
}
12 changes: 6 additions & 6 deletions zio/zngio/validate_test.go → value_test.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package zngio
package zed_test

import (
"testing"
Expand All @@ -8,7 +8,7 @@ import (
"github.com/stretchr/testify/assert"
)

func TestValidate(t *testing.T) {
func TestValueValidate(t *testing.T) {
r := zed.NewValue(
zed.NewTypeRecord(0, []zed.Column{
zed.NewColumn("f", zed.NewTypeSet(0, zed.TypeString)),
Expand All @@ -22,7 +22,7 @@ func TestValidate(t *testing.T) {
// Don't normalize.
b.EndContainer()
r.Bytes = b.Bytes()
assert.EqualError(t, Validate(r), "invalid ZNG: duplicate set element")
assert.EqualError(t, r.Validate(), "invalid ZNG: duplicate set element")
})
t.Run("set/error/unsorted-elements", func(t *testing.T) {
var b zcode.Builder
Expand All @@ -33,7 +33,7 @@ func TestValidate(t *testing.T) {
// Don't normalize.
b.EndContainer()
r.Bytes = b.Bytes()
assert.EqualError(t, Validate(r), "invalid ZNG: set elements not sorted")
assert.EqualError(t, r.Validate(), "invalid ZNG: set elements not sorted")
})
t.Run("set/primitive-elements", func(t *testing.T) {
var b zcode.Builder
Expand All @@ -45,7 +45,7 @@ func TestValidate(t *testing.T) {
b.TransformContainer(zed.NormalizeSet)
b.EndContainer()
r.Bytes = b.Bytes()
assert.NoError(t, Validate(r))
assert.NoError(t, r.Validate())
})
t.Run("set/complex-elements", func(t *testing.T) {
var b zcode.Builder
Expand All @@ -64,6 +64,6 @@ func TestValidate(t *testing.T) {
}))),
}),
b.Bytes())
assert.NoError(t, Validate(r))
assert.NoError(t, r.Validate())
})
}
3 changes: 1 addition & 2 deletions zio/zeekio/parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (

"github.com/brimdata/zed"
"github.com/brimdata/zed/pkg/nano"
"github.com/brimdata/zed/zio/zngio"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
Expand Down Expand Up @@ -130,7 +129,7 @@ func TestNestedRecords(t *testing.T) {
parser := startLegacyTest(t, fields, types, "")
record, err := sendLegacyValues(parser, vals)
require.NoError(t, err)
require.NoError(t, zngio.Validate(record))
require.NoError(t, record.Validate())

// First check that the descriptor was created correctly
cols := zed.TypeRecordOf(record.Type).Columns
Expand Down
2 changes: 1 addition & 1 deletion zio/zngio/scanner.go
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,7 @@ func (w *worker) decodeVal(buf *buffer, valRef *zed.Value) error {
valRef.Type = typ
valRef.Bytes = b
if w.validate {
if err := Validate(valRef); err != nil {
if err := valRef.Validate(); err != nil {
return err
}
}
Expand Down
68 changes: 0 additions & 68 deletions zio/zngio/validate.go

This file was deleted.

0 comments on commit a6ad61f

Please sign in to comment.