-
Notifications
You must be signed in to change notification settings - Fork 67
/
lval.go
90 lines (77 loc) · 1.86 KB
/
lval.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
package expr
import (
"errors"
"github.com/brimdata/zed"
"github.com/brimdata/zed/pkg/field"
"github.com/brimdata/zed/zson"
)
type Lval struct {
Elems []LvalElem
cache field.Path
}
func NewLval(evals []LvalElem) *Lval {
return &Lval{Elems: evals}
}
// Eval returns the path of the lval.
func (l *Lval) Eval(ectx Context, this zed.Value) (field.Path, error) {
l.cache = l.cache[:0]
for _, e := range l.Elems {
name, err := e.Eval(ectx, this)
if err != nil {
return nil, err
}
l.cache = append(l.cache, name)
}
return l.cache, nil
}
// Path returns the receiver's path. Path returns false when the receiver
// contains a dynamic element.
func (l *Lval) Path() (field.Path, bool) {
var path field.Path
for _, e := range l.Elems {
s, ok := e.(*StaticLvalElem)
if !ok {
return nil, false
}
path = append(path, s.Name)
}
return path, true
}
type LvalElem interface {
Eval(ectx Context, this zed.Value) (string, error)
}
type StaticLvalElem struct {
Name string
}
func (l *StaticLvalElem) Eval(_ Context, _ zed.Value) (string, error) {
return l.Name, nil
}
type ExprLvalElem struct {
caster Evaluator
eval Evaluator
}
func NewExprLvalElem(zctx *zed.Context, e Evaluator) *ExprLvalElem {
return &ExprLvalElem{
eval: e,
caster: LookupPrimitiveCaster(zctx, zed.TypeString),
}
}
func (l *ExprLvalElem) Eval(ectx Context, this zed.Value) (string, error) {
val := l.eval.Eval(ectx, this)
if val.IsError() {
return "", lvalErr(ectx, val)
}
if !val.IsString() {
if val = l.caster.Eval(ectx, val); val.IsError() {
return "", errors.New("field reference is not a string")
}
}
return val.AsString(), nil
}
func lvalErr(ectx Context, errVal zed.Value) error {
val := zed.NewValue(errVal.Type().(*zed.TypeError).Type, errVal.Bytes())
if val.IsString() {
return errors.New(val.AsString())
}
return errors.New(zson.FormatValue(val))
}