diff --git a/runtime/vam/expr/compare.go b/runtime/vam/expr/compare.go index da692793f2..47d78fae04 100644 --- a/runtime/vam/expr/compare.go +++ b/runtime/vam/expr/compare.go @@ -3,6 +3,8 @@ package expr //go:generate go run gencomparefuncs.go import ( + "bytes" + "github.com/brimdata/super" "github.com/brimdata/super/runtime/sam/expr/coerce" "github.com/brimdata/super/vector" @@ -43,6 +45,9 @@ func (c *Compare) eval(vecs ...vector.Any) vector.Any { if kind != vector.KindOf(rhs) { panic("vector kind mismatch after coerce") } + if kind == vector.KindType { + return c.compareTypeVals(lhs, rhs) + } lform, ok := vector.FormOf(lhs) if !ok { return vector.NewStringError(c.zctx, coerce.ErrIncompatibleTypes.Error(), lhs.Len()) @@ -60,6 +65,25 @@ func (c *Compare) eval(vecs ...vector.Any) vector.Any { return out } +func (c *Compare) compareTypeVals(lhs, rhs vector.Any) vector.Any { + if c.opCode == vector.CompLT || c.opCode == vector.CompGT { + return vector.NewConst(super.False, lhs.Len(), nil) + } + out := vector.NewBoolEmpty(lhs.Len(), nil) + for i := range lhs.Len() { + l, _ := vector.TypeValueValue(lhs, i) + r, _ := vector.TypeValueValue(rhs, i) + v := bytes.Equal(l, r) + if c.opCode == vector.CompNE { + v = !v + } + if v { + out.Set(i) + } + } + return out +} + type isNull struct { expr Evaluator } diff --git a/runtime/ztests/expr/compare-typevals.yaml b/runtime/ztests/expr/compare-typevals.yaml new file mode 100644 index 0000000000..dff80b0d20 --- /dev/null +++ b/runtime/ztests/expr/compare-typevals.yaml @@ -0,0 +1,16 @@ +zed: yield a == b, a != b + +vector: true + +input: | + {a:,b:} + {a:<{x:ip}>,b:<{x:ip}>} + {a:<{x:net}>,b:<{y:net}>} + +output: | + true + false + true + false + false + true diff --git a/vector/kind.go b/vector/kind.go index d906e98d9a..03bcf53884 100644 --- a/vector/kind.go +++ b/vector/kind.go @@ -40,6 +40,8 @@ func KindOf(v Any) Kind { return KindBytes case *String: return KindString + case *TypeValue: + return KindType case *Dict: return KindOf(v.Any) case *View: @@ -63,6 +65,8 @@ func KindFromString(v string) Kind { return KindBytes case "String": return KindString + case "TypeValue": + return KindType default: return KindInvalid }