From c502b41c2555a458561004003a6396d2dd327afa Mon Sep 17 00:00:00 2001 From: Steven McCanne Date: Mon, 7 Sep 2026 09:38:26 -0700 Subject: [PATCH 1/2] get rid of more error("missing") This commit deletes vector.NewMissing and replaces all the instances of its use with errors. The vcache projection logic produces a string error instead of a structured error because projection shouldn't involve reading this for the "on" field of such errors. I think this variation in no-such-field errors is ok to live with. Down the road when we have lazy vectors, we can load dynamically load the needed info to compute the complete structured errors. There are still lots of references to error("missing") throughout the docs. These will be addressed in a future PR. --- book/src/super-sql/declarations/pragmas.md | 2 +- book/src/super-sql/expressions/index.md | 14 +++--- book/src/super-sql/functions/types/nameof.md | 4 +- .../src/super-sql/functions/types/typename.md | 6 +-- compiler/rungen/op.go | 5 +-- compiler/semantic/op.go | 2 +- runtime/vam/expr/dot.go | 3 +- runtime/vam/expr/function/types.go | 6 +-- runtime/vam/expr/index.go | 20 ++++----- runtime/vcache/bool.go | 5 ++- runtime/vcache/bytes.go | 12 +++--- runtime/vcache/const.go | 9 ++-- runtime/vcache/dict.go | 7 +-- runtime/vcache/float.go | 5 ++- runtime/vcache/int.go | 5 ++- runtime/vcache/ip.go | 5 ++- runtime/vcache/net.go | 5 ++- runtime/vcache/none.go | 5 ++- runtime/vcache/null.go | 5 ++- runtime/vcache/record.go | 3 +- runtime/vcache/type.go | 5 ++- runtime/vcache/uint.go | 5 ++- runtime/vcache/ztests/projection.yaml | 43 +++++++++++-------- runtime/ztests/expr/dot-record-type.yaml | 6 +-- runtime/ztests/expr/function/nameof.yaml | 14 +++--- runtime/ztests/expr/function/typename.yaml | 2 +- runtime/ztests/expr/index.yaml | 18 ++++---- runtime/ztests/expr/optional-fields.yaml | 4 +- runtime/ztests/expr/slice.yaml | 8 ++-- runtime/ztests/op/aggregate/missing.yaml | 4 +- vector/error.go | 8 ++-- 31 files changed, 131 insertions(+), 114 deletions(-) diff --git a/book/src/super-sql/declarations/pragmas.md b/book/src/super-sql/declarations/pragmas.md index 2e5762c6ed..875dcfb3dd 100644 --- a/book/src/super-sql/declarations/pragmas.md +++ b/book/src/super-sql/declarations/pragmas.md @@ -46,7 +46,7 @@ values { "bar" [1,2,3] # expected output -{a:"a",b:error("missing")} +{a:"a",b:error({message:"entity cannot be indexed",on:"bar"})} {a:[2],b:1} ``` diff --git a/book/src/super-sql/expressions/index.md b/book/src/super-sql/expressions/index.md index 699fd9deb1..ec93a85100 100644 --- a/book/src/super-sql/expressions/index.md +++ b/book/src/super-sql/expressions/index.md @@ -32,7 +32,7 @@ value in the set of that index ordered by total order of values. If `` is a map, then the `` operand is presumed to be a key and the corresponding value for that key is the result of the operation. If no such key exists in the map, then -the result is `error("missing")`. +the result is `none`. If `` is a string, then the `` operand must be coercible to an integer and the result is an integer representing @@ -75,8 +75,8 @@ values a[2] # expected output 3 3 -error("missing") -error("missing") +error({message:"entity cannot be indexed",on:"1234"}) +error({message:"entity cannot be indexed",on:0x01020304}) ``` --- @@ -95,8 +95,8 @@ values a[2] # expected output 2 2 -error("missing") -error("missing") +error({message:"entity cannot be indexed",on:"1234"}) +error({message:"entity cannot be indexed",on:0x01020304}) ``` --- @@ -114,6 +114,6 @@ values a[-1] # expected output 4 4 -error("missing") -error("missing") +error({message:"entity cannot be indexed",on:"1234"}) +error({message:"entity cannot be indexed",on:0x01020304}) ``` diff --git a/book/src/super-sql/functions/types/nameof.md b/book/src/super-sql/functions/types/nameof.md index ce2b3111d9..37387f55be 100644 --- a/book/src/super-sql/functions/types/nameof.md +++ b/book/src/super-sql/functions/types/nameof.md @@ -11,7 +11,7 @@ nameof(val: any) -> string ## Description The `nameof` function returns the type name of `val` as a string if `val` is a named type. -Otherwise, it returns `error("missing")`. +Otherwise, it returns an error. ## Examples @@ -28,5 +28,5 @@ type port=int16 80 # expected output "port" -error("missing") +error({message:"nameof: not a type",on:80}) ``` diff --git a/book/src/super-sql/functions/types/typename.md b/book/src/super-sql/functions/types/typename.md index c11cbcea68..2945147907 100644 --- a/book/src/super-sql/functions/types/typename.md +++ b/book/src/super-sql/functions/types/typename.md @@ -12,7 +12,7 @@ typename(name: string) -> type The `typename` function returns the [type](../../types/intro.md) of the [named type](../../types/named.md) given by `name` if it exists. Otherwise, -`error("missing")` is returned. +an error is returned. ## Examples @@ -48,7 +48,7 @@ type port=int16 --- -_The result is `error("missing")` if the type name does not exist_ +_The result is an error if the type name does not exist_ ```mdtest-spq # spq @@ -56,5 +56,5 @@ values typename("port") # input 80 # expected output -error("missing") +error({message:"typename: unknown type name",on:"port"}) ``` diff --git a/compiler/rungen/op.go b/compiler/rungen/op.go index e371fe606a..88ee710adf 100644 --- a/compiler/rungen/op.go +++ b/compiler/rungen/op.go @@ -306,11 +306,10 @@ func (b *Builder) evalAtCompileTime(in dag.Expr) (val super.Value, err error) { // reference to a var not in scope, a field access null this, etc. defer func() { if recover() != nil { - val = b.sctx().Missing() + val = b.sctx().NewErrorf("evalAtCompileTime") } }() - missingVec := vector.NewMissing(b.sctx(), 1) - vec := e.Eval(missingVec) + vec := e.Eval(vector.NewStringError(b.sctx(), "evalAtCompileTime", 1)) if vec.Len() != 1 { panic(vector.Format(vec)) } diff --git a/compiler/semantic/op.go b/compiler/semantic/op.go index dc62c1ccc2..1894e22b91 100644 --- a/compiler/semantic/op.go +++ b/compiler/semantic/op.go @@ -241,7 +241,7 @@ func (t *translator) fromConst(val super.Value, entity *ast.FromEval, args []ast } names := make([]string, 0, len(vals)) for _, val := range vals { - if super.TypeUnder(val.Type()) != super.TypeString { + if !hasString(val.Type()) { t.error(entity.Expr, fmt.Errorf("from expression requires a string but encountered %s", sup.String(val))) return sem.Seq{badOp}, "" } diff --git a/runtime/vam/expr/dot.go b/runtime/vam/expr/dot.go index 6db9cb32b1..d21f4a3a52 100644 --- a/runtime/vam/expr/dot.go +++ b/runtime/vam/expr/dot.go @@ -70,8 +70,7 @@ func (d *DotExpr) eval(vecs ...vector.Any) vector.Any { errs = append(errs, i) } if len(errs) > 0 { - //XXX need to build error vector above with each field-missing message - return vector.Combine(typvals, errs, vector.NewMissing(d.sctx, uint32(len(errs)))) + return vector.NewCombinedError(d.sctx, fmt.Sprintf("no such field %s", d.field), typvals, val, errs) } return typvals case *vector.Map: diff --git a/runtime/vam/expr/function/types.go b/runtime/vam/expr/function/types.go index 695c7b9535..5e2989d650 100644 --- a/runtime/vam/expr/function/types.go +++ b/runtime/vam/expr/function/types.go @@ -132,7 +132,7 @@ func (n *NameOf) Call(args ...vector.Any) vector.Any { return vector.NewConstString(named.Name, vec.Len()) } if typ.ID() != super.IDType { - return vector.NewMissing(n.sctx, vec.Len()) + return vector.NewWrappedError(n.sctx, "nameof: not a type", vec) } out := vector.NewStringEmpty(vec.Len()) var errs []uint32 @@ -145,7 +145,7 @@ func (n *NameOf) Call(args ...vector.Any) vector.Any { } } if len(errs) > 0 { - return vector.Combine(out, errs, vector.NewMissing(n.sctx, uint32(len(errs)))) + return vector.NewCombinedError(n.sctx, "not a named type", out, vec, errs) } return out } @@ -180,7 +180,7 @@ func (t *TypeName) Call(args ...vector.Any) vector.Any { } } if len(errs) > 0 { - return vector.Combine(out, errs, vector.NewMissing(t.sctx, uint32(len(errs)))) + return vector.NewCombinedError(t.sctx, "typename: unknown type name", out, vec, errs) } return out } diff --git a/runtime/vam/expr/index.go b/runtime/vam/expr/index.go index 058cf9a24d..0660b44a6d 100644 --- a/runtime/vam/expr/index.go +++ b/runtime/vam/expr/index.go @@ -35,7 +35,7 @@ func (i *Index) eval(args ...vector.Any) vector.Any { case vector.KindMap: return indexMap(i.sctx, container, index) default: - return vector.NewMissing(i.sctx, container.Len()) + return vector.NewWrappedError(i.sctx, "entity cannot be indexed", container) } } @@ -78,7 +78,7 @@ func indexArrayOrSet(sctx *super.Context, vec, indexVec vector.Any, base1 bool) } out := vector.Pick(vector.Deunion(vals), viewIndexes) if len(errs) > 0 { - return vector.Combine(out, errs, vector.NewMissing(sctx, uint32(len(errs)))) + return vector.NewCombinedError(sctx, "index out of range", out, indexVec, errs) } return out } @@ -109,7 +109,7 @@ func indexRecord(sctx *super.Context, vec, indexVec vector.Any, base1 bool) vect default: panic(vec) } - var errcnt uint32 + var errs []uint32 tags := make([]uint32, vec.Len()) n := len(rec.Typ.Fields) viewIndexes := make([][]uint32, n) @@ -131,7 +131,7 @@ func indexRecord(sctx *super.Context, vec, indexVec vector.Any, base1 bool) vect } if k < 0 || k >= n { tags[i] = uint32(n) - errcnt++ + errs = append(errs, i) continue } idx := i @@ -142,9 +142,9 @@ func indexRecord(sctx *super.Context, vec, indexVec vector.Any, base1 bool) vect viewIndexes[k] = append(viewIndexes[k], idx) } out := make([]vector.Any, n+1) - out[n] = vector.NewMissing(sctx, errcnt) + out[n] = vector.NewWrappedError(sctx, "invalid record index", vector.NewView(indexVec, errs)) for i, field := range rec.Fields { - out[i] = vector.DeoptionWithNone(sctx, vector.Pick(field, viewIndexes[i])) + out[i] = vector.Pick(field, viewIndexes[i]) } return vector.NewDynamic(tags, out) } @@ -161,7 +161,7 @@ func indexMap(sctx *super.Context, vec, indexVec vector.Any) vector.Any { pick = append(pick, i) } } - var valIndexes, errs []uint32 + var valIndexes, nones []uint32 cmp := NewCompare(sctx, "==", nil, nil).eval hits := vector.Apply(vector.ApplyRipFusions|vector.ApplyRipUnions, cmp, vector.Pick(indexVec, pick), m.Keys) bits := FlattenBool(hits).Bits @@ -176,12 +176,12 @@ func indexMap(sctx *super.Context, vec, indexVec vector.Any) vector.Any { if selected != -1 { valIndexes = append(valIndexes, uint32(selected)) } else { - errs = append(errs, i) + nones = append(nones, i) } } vals := vector.Pick(vector.Deunion(m.Values), valIndexes) - if len(errs) > 0 { - return vector.Combine(vals, errs, vector.NewMissing(sctx, uint32(len(errs)))) + if len(nones) > 0 { + return vector.Combine(vals, nones, vector.NewNone(uint32(len(nones)))) } return vals } diff --git a/runtime/vcache/bool.go b/runtime/vcache/bool.go index a734c860c4..aef9539965 100644 --- a/runtime/vcache/bool.go +++ b/runtime/vcache/bool.go @@ -27,10 +27,11 @@ func (b *bool_) length() uint32 { func (*bool_) unmarshal(*csup.Context, field.Projection) {} func (b *bool_) project(loader *loader, projection field.Projection) vector.Any { + vec := vector.NewBool(b.load(loader)) if len(projection) > 0 { - return vector.NewMissing(loader.sctx, b.length()) + return vector.NewWrappedError(loader.sctx, "dot operator on non-record", vec) } - return vector.NewBool(b.load(loader)) + return vec } func (b *bool_) load(loader *loader) bitvec.Bits { diff --git a/runtime/vcache/bytes.go b/runtime/vcache/bytes.go index 80b1dd02ba..2f9ffa03bf 100644 --- a/runtime/vcache/bytes.go +++ b/runtime/vcache/bytes.go @@ -27,18 +27,20 @@ func (b *bytes) length() uint32 { func (*bytes) unmarshal(*csup.Context, field.Projection) {} func (b *bytes) project(loader *loader, projection field.Projection) vector.Any { - if len(projection) > 0 { - return vector.NewMissing(loader.sctx, b.length()) - } + var vec vector.Any table := b.load(loader) switch b.meta.Typ.ID() { case super.IDString: - return vector.NewString(table) + vec = vector.NewString(table) case super.IDBytes: - return vector.NewBytes(table) + vec = vector.NewBytes(table) default: panic(b.meta.Typ) } + if len(projection) > 0 { + return vector.NewWrappedError(loader.sctx, "dot operator on non-record", vec) + } + return vec } func (b *bytes) load(loader *loader) vector.BytesTable { diff --git a/runtime/vcache/const.go b/runtime/vcache/const.go index c3933f6160..b9c7aa1805 100644 --- a/runtime/vcache/const.go +++ b/runtime/vcache/const.go @@ -23,9 +23,6 @@ func (c *const_) length() uint32 { func (*const_) unmarshal(*csup.Context, field.Projection) {} func (c *const_) project(loader *loader, projection field.Projection) vector.Any { - if len(projection) > 0 { - return vector.NewMissing(loader.sctx, c.length()) - } // Map the const super.Value in the csup's type context to // a new one in the query type context. val := c.meta.Value @@ -36,5 +33,9 @@ func (c *const_) project(loader *loader, projection field.Projection) vector.Any if err != nil { panic(err) } - return vector.NewConstFromValue(loader.sctx, super.NewValue(typ, val.Bytes()), c.length()) + vec := vector.NewConstFromValue(loader.sctx, super.NewValue(typ, val.Bytes()), c.length()) + if len(projection) > 0 { + return vector.NewWrappedError(loader.sctx, "dot operator on non-record", vec) + } + return vec } diff --git a/runtime/vcache/dict.go b/runtime/vcache/dict.go index 3bef2d7968..67474c5580 100644 --- a/runtime/vcache/dict.go +++ b/runtime/vcache/dict.go @@ -35,11 +35,12 @@ func (d *dict) unmarshal(cctx *csup.Context, projection field.Projection) { } func (d *dict) project(loader *loader, projection field.Projection) vector.Any { + index, counts := d.load(loader) + vec := vector.NewDict(d.values.project(loader, projection), index, counts) if len(projection) > 0 { - return vector.NewMissing(loader.sctx, d.length()) + return vector.NewWrappedError(loader.sctx, "dot operator on non-record", vec) } - index, counts := d.load(loader) - return vector.NewDict(d.values.project(loader, projection), index, counts) + return vec } func (d *dict) load(loader *loader) ([]byte, []uint32) { diff --git a/runtime/vcache/float.go b/runtime/vcache/float.go index d5e10b52aa..80aad4127b 100644 --- a/runtime/vcache/float.go +++ b/runtime/vcache/float.go @@ -27,10 +27,11 @@ func (f *float) length() uint32 { func (*float) unmarshal(*csup.Context, field.Projection) {} func (f *float) project(loader *loader, projection field.Projection) vector.Any { + vec := vector.NewFloat(f.meta.Typ, f.load(loader)) if len(projection) > 0 { - return vector.NewMissing(loader.sctx, f.length()) + return vector.NewWrappedError(loader.sctx, "dot operator on non-record", vec) } - return vector.NewFloat(f.meta.Typ, f.load(loader)) + return vec } func (f *float) load(loader *loader) []float64 { diff --git a/runtime/vcache/int.go b/runtime/vcache/int.go index 2ab8509d5d..fd12d0310c 100644 --- a/runtime/vcache/int.go +++ b/runtime/vcache/int.go @@ -28,10 +28,11 @@ func (i *int_) length() uint32 { func (*int_) unmarshal(*csup.Context, field.Projection) {} func (i *int_) project(loader *loader, projection field.Projection) vector.Any { + vec := vector.NewInt(i.meta.Typ, i.load(loader)) if len(projection) > 0 { - return vector.NewMissing(loader.sctx, i.length()) + return vector.NewWrappedError(loader.sctx, "dot operator on non-record", vec) } - return vector.NewInt(i.meta.Typ, i.load(loader)) + return vec } func (i *int_) load(loader *loader) []int64 { diff --git a/runtime/vcache/ip.go b/runtime/vcache/ip.go index aaafb1d034..e9ee6d2f63 100644 --- a/runtime/vcache/ip.go +++ b/runtime/vcache/ip.go @@ -26,10 +26,11 @@ func (i *ip) length() uint32 { func (*ip) unmarshal(*csup.Context, field.Projection) {} func (i *ip) project(loader *loader, projection field.Projection) vector.Any { + vec := vector.NewIP(i.load(loader)) if len(projection) > 0 { - return vector.NewMissing(loader.sctx, i.length()) + return vector.NewWrappedError(loader.sctx, "dot operator on non-record", vec) } - return vector.NewIP(i.load(loader)) + return vec } func (i *ip) load(loader *loader) []netip.Addr { diff --git a/runtime/vcache/net.go b/runtime/vcache/net.go index 52af85a28e..235c0294af 100644 --- a/runtime/vcache/net.go +++ b/runtime/vcache/net.go @@ -26,10 +26,11 @@ func (n *net) length() uint32 { func (*net) unmarshal(*csup.Context, field.Projection) {} func (n *net) project(loader *loader, projection field.Projection) vector.Any { + vec := vector.NewNet(n.load(loader)) if len(projection) > 0 { - return vector.NewMissing(loader.sctx, n.length()) + return vector.NewWrappedError(loader.sctx, "dot operator on non-record", vec) } - return vector.NewNet(n.load(loader)) + return vec } func (n *net) load(loader *loader) []netip.Prefix { diff --git a/runtime/vcache/none.go b/runtime/vcache/none.go index 513ea4c4db..4fecebe142 100644 --- a/runtime/vcache/none.go +++ b/runtime/vcache/none.go @@ -21,8 +21,9 @@ func (n *none) length() uint32 { func (*none) unmarshal(*csup.Context, field.Projection) {} func (n *none) project(loader *loader, projection field.Projection) vector.Any { + vec := vector.NewNone(n.meta.Count) if len(projection) > 0 { - return vector.NewMissing(loader.sctx, n.length()) + return vector.NewWrappedError(loader.sctx, "dot operator on non-record", vec) } - return vector.NewNone(n.meta.Count) + return vec } diff --git a/runtime/vcache/null.go b/runtime/vcache/null.go index b4f05bc79c..7d5c7e540f 100644 --- a/runtime/vcache/null.go +++ b/runtime/vcache/null.go @@ -21,8 +21,9 @@ func (n *null) length() uint32 { func (*null) unmarshal(*csup.Context, field.Projection) {} func (n *null) project(loader *loader, projection field.Projection) vector.Any { + vec := vector.NewNull(n.meta.Count) if len(projection) > 0 { - return vector.NewMissing(loader.sctx, n.length()) + return vector.NewWrappedError(loader.sctx, "dot operator on non-record", vec) } - return vector.NewNull(n.meta.Count) + return vec } diff --git a/runtime/vcache/record.go b/runtime/vcache/record.go index d895a44c0d..6a1273cfc7 100644 --- a/runtime/vcache/record.go +++ b/runtime/vcache/record.go @@ -1,6 +1,7 @@ package vcache import ( + "fmt" "slices" "sync" @@ -74,7 +75,7 @@ func (r *record) project(loader *loader, projection field.Projection) vector.Any if k := indexOfField(node.Name, r.meta); k >= 0 && r.fields[k] != nil { val = r.fields[k].project(loader, node.Proj) } else { - val = vector.NewMissing(loader.sctx, r.length()) + val = vector.NewStringError(loader.sctx, fmt.Sprintf("no such field %s", node.Name), r.length()) } valFields = append(valFields, val) fields = append(fields, super.NewField(node.Name, val.Type())) diff --git a/runtime/vcache/type.go b/runtime/vcache/type.go index 9b6c5aed38..65c0dcd016 100644 --- a/runtime/vcache/type.go +++ b/runtime/vcache/type.go @@ -33,10 +33,11 @@ func (t *typevalue) length() uint32 { func (*typevalue) unmarshal(*csup.Context, field.Projection) {} func (t *typevalue) project(loader *loader, projection field.Projection) vector.Any { + vec := vector.NewTypeValueWithLoader(loader.sctx, t.newLoader(loader)) if len(projection) > 0 { - return vector.NewMissing(loader.sctx, t.length()) + return vector.NewWrappedError(loader.sctx, "dot operator on non-record", vec) } - return vector.NewTypeValueWithLoader(loader.sctx, t.newLoader(loader)) + return vec } func (t *typevalue) newLoader(loader *loader) *typesLoader { diff --git a/runtime/vcache/uint.go b/runtime/vcache/uint.go index 910fbcf128..aa872eeedb 100644 --- a/runtime/vcache/uint.go +++ b/runtime/vcache/uint.go @@ -28,10 +28,11 @@ func (u *uint_) length() uint32 { func (*uint_) unmarshal(*csup.Context, field.Projection) {} func (u *uint_) project(loader *loader, projection field.Projection) vector.Any { + vec := vector.NewUint(u.meta.Typ, u.load(loader)) if len(projection) > 0 { - return vector.NewMissing(loader.sctx, u.length()) + return vector.NewWrappedError(loader.sctx, "dot operator on non-record", vec) } - return vector.NewUint(u.meta.Typ, u.load(loader)) + return vec } func (u *uint_) load(loader *loader) []uint64 { diff --git a/runtime/vcache/ztests/projection.yaml b/runtime/vcache/ztests/projection.yaml index 3b63ac4d8a..337242e009 100644 --- a/runtime/vcache/ztests/projection.yaml +++ b/runtime/vcache/ztests/projection.yaml @@ -9,6 +9,9 @@ script: | super dev vector project -s test.csup s x echo === super dev vector project -s test.csup y w.y + echo === + echo '1 2 3' | super -f csup -o test2.csup - + super dev vector project -s test2.csup x inputs: - name: stdin data: | @@ -20,32 +23,36 @@ inputs: outputs: - name: stdout data: | - {x:1,y:2,z:error("missing")} - {x:3,y:4,z:error("missing")} - {x:3,y:4,z:error("missing")} - {x:3,y:4,z:error("missing")} - {x:error("missing"),y:error("missing"),z:error("missing")} + {x:1,y:2,z:error("no such field z")} + {x:3,y:4,z:error("no such field z")} + {x:3,y:4,z:error("no such field z")} + {x:3,y:4,z:error("no such field z")} + {x:error("no such field x"),y:error("no such field y"),z:error("no such field z")} === {s:"foo"} - {s:error("missing")} + {s:error("no such field s")} {s:"bar"} - {s:error("missing")} + {s:error("no such field s")} {s:"baz"} === {x:1,s:"foo"} - {x:3,s:error("missing")} + {x:3,s:error("no such field s")} {x:3,s:"bar"} - {x:3,s:error("missing")} - {x:error("missing"),s:"baz"} + {x:3,s:error("no such field s")} + {x:error("no such field x"),s:"baz"} === {s:"foo",x:1} - {s:error("missing"),x:3} + {s:error("no such field s"),x:3} {s:"bar",x:3} - {s:error("missing"),x:3} - {s:"baz",x:error("missing")} + {s:error("no such field s"),x:3} + {s:"baz",x:error("no such field x")} + === + {y:2,w:error("no such field w")} + {y:4,w:error("no such field w")} + {y:4,w:error("no such field w")} + {y:4,w:error("no such field w")} + {y:error("no such field y"),w:{y:5}} === - {y:2,w:error("missing")} - {y:4,w:error("missing")} - {y:4,w:error("missing")} - {y:4,w:error("missing")} - {y:error("missing"),w:{y:5}} + error({message:"dot operator on non-record",on:1}) + error({message:"dot operator on non-record",on:2}) + error({message:"dot operator on non-record",on:3}) diff --git a/runtime/ztests/expr/dot-record-type.yaml b/runtime/ztests/expr/dot-record-type.yaml index 0a56b53b0c..24e0cb5ed0 100644 --- a/runtime/ztests/expr/dot-record-type.yaml +++ b/runtime/ztests/expr/dot-record-type.yaml @@ -9,9 +9,9 @@ input: | output: | <{bar:int64}> - error("missing") - error({message:"'.': applied to non-record",on:error("missing")}) + error({message:"no such field foo",on:}) + error({message:"'.': applied to non-record",on:error({message:"no such field foo",on:})}) - error("missing") + error({message:"no such field bar",on:}) error({message:"'.': applied to non-record",on:null}) error({message:"'.': applied to non-record",on:error({message:"'.': applied to non-record",on:null})}) diff --git a/runtime/ztests/expr/function/nameof.yaml b/runtime/ztests/expr/function/nameof.yaml index eda05c4d44..f1d7e47840 100644 --- a/runtime/ztests/expr/function/nameof.yaml +++ b/runtime/ztests/expr/function/nameof.yaml @@ -20,15 +20,15 @@ input: | null::(int64|null) output: | - error("missing") + error({message:"nameof: not a type",on:{x:1}}) "foo1" "foo2" "foo3" "bar1" - error("missing") - error("missing") + error({message:"nameof: not a type",on:{y:1}}) + error({message:"nameof: not a type",on:{x:"foo",y:1,z:2}}) "bar2" - error("missing") - error("missing") - error("missing") - error("missing") + error({message:"not a named type",on:<{x:string,y:int64,z:int64}>}) + error({message:"nameof: not a type",on:null}) + error({message:"nameof: not a type",on:1}) + error({message:"nameof: not a type",on:null}) diff --git a/runtime/ztests/expr/function/typename.yaml b/runtime/ztests/expr/function/typename.yaml index 4a4d0574bf..c5876fc9b4 100644 --- a/runtime/ztests/expr/function/typename.yaml +++ b/runtime/ztests/expr/function/typename.yaml @@ -9,5 +9,5 @@ input: | output: | type port=int16 - error("missing") + error({message:"typename: unknown type name",on:"doesnotexit"}) error({message:"typename: argument must be a string",on:1}) diff --git a/runtime/ztests/expr/index.yaml b/runtime/ztests/expr/index.yaml index 44acea3f59..e677ee95c2 100644 --- a/runtime/ztests/expr/index.yaml +++ b/runtime/ztests/expr/index.yaml @@ -38,8 +38,8 @@ output: | 2 1 null - error("missing") - error("missing") + error({message:"index out of range",on:-5}) + error({message:"entity cannot be indexed",on:null}) error({message:"index is not an integer",on:null}) error({message:"index is not an integer",on:"hi"}) error({message:"cannot cast to int64",on:9223372036854775808::uint64}) @@ -47,7 +47,7 @@ output: | 2 1 null - error("missing") + error({message:"index out of range",on:-5}) error({message:"index is not an integer",on:"hi"}) "foo" "baz" @@ -55,11 +55,11 @@ output: | "foo" "bar" error({message:"invalid value for record index",on:1.}) - error("missing") + error({message:"invalid record index",on:"doesnotexist"}) 1 2 1 - error("missing") + none 127.0.0.1 --- @@ -107,8 +107,8 @@ output: | type bar=set[int64] error({message:"'.': applied to non-record",on:set[4,5,6]::bar}) "foo" - error("missing") - error("missing") + none + error({message:"invalid record index",on:1}) 123 --- @@ -120,8 +120,6 @@ input: | {val:fusion(2::(int64|[int64|{r:int64}]),)} {val:fusion([1,{r:3}]::(int64|[int64|{r:int64}]),<[int64|{r:int64}]>)} -# XXX fix this should not be error missing... should be structured - output: | - error({message:"'.': applied to non-record",on:error("missing")}) + error({message:"'.': applied to non-record",on:error({message:"entity cannot be indexed",on:2})}) 3 diff --git a/runtime/ztests/expr/optional-fields.yaml b/runtime/ztests/expr/optional-fields.yaml index 6c07f48395..83d5e37162 100644 --- a/runtime/ztests/expr/optional-fields.yaml +++ b/runtime/ztests/expr/optional-fields.yaml @@ -80,8 +80,8 @@ output: | 1 2 3 - "foo" - none + "foo"::(string|none) + none::(string|none) --- diff --git a/runtime/ztests/expr/slice.yaml b/runtime/ztests/expr/slice.yaml index 962cd8ab37..10714cde10 100644 --- a/runtime/ztests/expr/slice.yaml +++ b/runtime/ztests/expr/slice.yaml @@ -17,10 +17,10 @@ output: | {a1:0x,a2:0x,a3:0x,a4:0x,a5:0x,a6:0x,a7:0x,a8:null} {a1:"",a2:"",a3:"",a4:"",a5:"",a6:"",a7:"",a8:null} {a1:[]::[int32],a2:[]::[int32],a3:[]::[int32],a4:[]::[int32],a5:[]::[int32],a6:[]::[int32],a7:[]::[int32],a8:null} - {a1:0x1122,a2:0x112233,a3:0x00,a4:0x001122,a5:0x,a6:0x33,a7:0x22,a8:error({message:"slice expression: error value encountered",on:error({message:"-: error value encountered",on:error("missing")})})} - {a1:"12",a2:"123",a3:"0",a4:"012",a5:"",a6:"3",a7:"2",a8:error({message:"slice expression: error value encountered",on:error({message:"-: error value encountered",on:error("missing")})})} - {a1:"ⁱ⁲",a2:"ⁱ⁲3",a3:"0",a4:"0ⁱ⁲",a5:"",a6:"3",a7:"⁲",a8:error({message:"slice expression: error value encountered",on:error({message:"-: error value encountered",on:error("missing")})})} - {a1:"ⁱ⁲",a2:"ⁱ⁲⁳",a3:"⁰",a4:"⁰ⁱ⁲",a5:"",a6:"⁳",a7:"⁲",a8:error({message:"slice expression: error value encountered",on:error({message:"-: error value encountered",on:error("missing")})})} + {a1:0x1122,a2:0x112233,a3:0x00,a4:0x001122,a5:0x,a6:0x33,a7:0x22,a8:error({message:"slice expression: error value encountered",on:error({message:"-: error value encountered",on:error({message:"entity cannot be indexed",on:0x00112233})})})} + {a1:"12",a2:"123",a3:"0",a4:"012",a5:"",a6:"3",a7:"2",a8:error({message:"slice expression: error value encountered",on:error({message:"-: error value encountered",on:error({message:"entity cannot be indexed",on:"0123"})})})} + {a1:"ⁱ⁲",a2:"ⁱ⁲3",a3:"0",a4:"0ⁱ⁲",a5:"",a6:"3",a7:"⁲",a8:error({message:"slice expression: error value encountered",on:error({message:"-: error value encountered",on:error({message:"entity cannot be indexed",on:"0ⁱ⁲3"})})})} + {a1:"ⁱ⁲",a2:"ⁱ⁲⁳",a3:"⁰",a4:"⁰ⁱ⁲",a5:"",a6:"⁳",a7:"⁲",a8:error({message:"slice expression: error value encountered",on:error({message:"-: error value encountered",on:error({message:"entity cannot be indexed",on:"⁰ⁱ⁲⁳"})})})} {a1:[11::int32,12::int32],a2:[11::int32,12::int32,13::int32],a3:[10::int32],a4:[10::int32,11::int32,12::int32],a5:[]::[int32],a6:[13::int32],a7:[12::int32],a8:[10::int32,11::int32]} {a1:set[11::int32,12::int32],a2:set[11::int32,12::int32,13::int32],a3:set[10::int32],a4:set[10::int32,11::int32,12::int32],a5:set[]::set[int32],a6:set[13::int32],a7:set[12::int32],a8:set[10::int32,11::int32]} diff --git a/runtime/ztests/op/aggregate/missing.yaml b/runtime/ztests/op/aggregate/missing.yaml index 4a05e40142..dfff5dcb03 100644 --- a/runtime/ztests/op/aggregate/missing.yaml +++ b/runtime/ztests/op/aggregate/missing.yaml @@ -8,5 +8,5 @@ input: | output: | {a:0,b:1} - {a:error("missing"),b:1} - {a:error("missing"),b:error({message:"'.': applied to non-record",on:"b"})} + {a:error({message:"index out of range",on:0}),b:1} + {a:error({message:"entity cannot be indexed",on:"a"}),b:error({message:"'.': applied to non-record",on:"b"})} diff --git a/vector/error.go b/vector/error.go index 180bbe96b0..24b1775c4d 100644 --- a/vector/error.go +++ b/vector/error.go @@ -39,15 +39,15 @@ func NewStringError(sctx *super.Context, msg string, len uint32) *Error { return &Error{Typ: sctx.LookupTypeError(super.TypeString), Vals: vals} } -func NewMissing(sctx *super.Context, len uint32) *Error { - return NewStringError(sctx, "missing", len) -} - func NewWrappedError(sctx *super.Context, msg string, val Any) *Error { msgVec := NewConstString(msg, val.Len()) return NewVecWrappedError(sctx, msgVec, val) } +func NewCombinedError(sctx *super.Context, msg string, vec, on Any, index []uint32) Any { + return Combine(vec, index, NewWrappedError(sctx, msg, NewView(on, index))) +} + func NewVecWrappedError(sctx *super.Context, msg Any, val Any) *Error { recType := sctx.MustLookupTypeRecord([]super.Field{ {Name: "message", Type: msg.Type()}, From 7068389030fa90bb5ba7876dbaa88788be660ce7 Mon Sep 17 00:00:00 2001 From: Steven McCanne Date: Tue, 8 Sep 2026 13:49:19 -0700 Subject: [PATCH 2/2] address PR feedback --- book/src/super-sql/declarations/pragmas.md | 2 +- book/src/super-sql/expressions/index.md | 12 ++++++------ runtime/vam/expr/dot.go | 2 +- runtime/vam/expr/function/types.go | 2 +- runtime/vam/expr/index.go | 2 +- runtime/vcache/bool.go | 2 +- runtime/vcache/bytes.go | 2 +- runtime/vcache/const.go | 2 +- runtime/vcache/dict.go | 2 +- runtime/vcache/float.go | 2 +- runtime/vcache/int.go | 2 +- runtime/vcache/ip.go | 2 +- runtime/vcache/net.go | 2 +- runtime/vcache/none.go | 2 +- runtime/vcache/null.go | 2 +- runtime/vcache/record.go | 3 ++- runtime/vcache/type.go | 2 +- runtime/vcache/uint.go | 2 +- runtime/vcache/ztests/projection.yaml | 6 +++--- runtime/ztests/expr/function/nameof.yaml | 2 +- runtime/ztests/expr/index.yaml | 4 ++-- runtime/ztests/expr/slice.yaml | 8 ++++---- runtime/ztests/op/aggregate/missing.yaml | 2 +- 23 files changed, 35 insertions(+), 34 deletions(-) diff --git a/book/src/super-sql/declarations/pragmas.md b/book/src/super-sql/declarations/pragmas.md index 875dcfb3dd..94da860103 100644 --- a/book/src/super-sql/declarations/pragmas.md +++ b/book/src/super-sql/declarations/pragmas.md @@ -46,7 +46,7 @@ values { "bar" [1,2,3] # expected output -{a:"a",b:error({message:"entity cannot be indexed",on:"bar"})} +{a:"a",b:error({message:"value cannot be indexed",on:"bar"})} {a:[2],b:1} ``` diff --git a/book/src/super-sql/expressions/index.md b/book/src/super-sql/expressions/index.md index ec93a85100..d5c87330f9 100644 --- a/book/src/super-sql/expressions/index.md +++ b/book/src/super-sql/expressions/index.md @@ -75,8 +75,8 @@ values a[2] # expected output 3 3 -error({message:"entity cannot be indexed",on:"1234"}) -error({message:"entity cannot be indexed",on:0x01020304}) +error({message:"value cannot be indexed",on:"1234"}) +error({message:"value cannot be indexed",on:0x01020304}) ``` --- @@ -95,8 +95,8 @@ values a[2] # expected output 2 2 -error({message:"entity cannot be indexed",on:"1234"}) -error({message:"entity cannot be indexed",on:0x01020304}) +error({message:"value cannot be indexed",on:"1234"}) +error({message:"value cannot be indexed",on:0x01020304}) ``` --- @@ -114,6 +114,6 @@ values a[-1] # expected output 4 4 -error({message:"entity cannot be indexed",on:"1234"}) -error({message:"entity cannot be indexed",on:0x01020304}) +error({message:"value cannot be indexed",on:"1234"}) +error({message:"value cannot be indexed",on:0x01020304}) ``` diff --git a/runtime/vam/expr/dot.go b/runtime/vam/expr/dot.go index d21f4a3a52..0c53fdb8de 100644 --- a/runtime/vam/expr/dot.go +++ b/runtime/vam/expr/dot.go @@ -70,7 +70,7 @@ func (d *DotExpr) eval(vecs ...vector.Any) vector.Any { errs = append(errs, i) } if len(errs) > 0 { - return vector.NewCombinedError(d.sctx, fmt.Sprintf("no such field %s", d.field), typvals, val, errs) + return vector.NewCombinedError(d.sctx, fmt.Sprintf("no such field %s", sup.QuotedName(d.field)), typvals, val, errs) } return typvals case *vector.Map: diff --git a/runtime/vam/expr/function/types.go b/runtime/vam/expr/function/types.go index 5e2989d650..2eb9699ce2 100644 --- a/runtime/vam/expr/function/types.go +++ b/runtime/vam/expr/function/types.go @@ -145,7 +145,7 @@ func (n *NameOf) Call(args ...vector.Any) vector.Any { } } if len(errs) > 0 { - return vector.NewCombinedError(n.sctx, "not a named type", out, vec, errs) + return vector.NewCombinedError(n.sctx, "nameof: not a named type", out, vec, errs) } return out } diff --git a/runtime/vam/expr/index.go b/runtime/vam/expr/index.go index 0660b44a6d..241f221b0d 100644 --- a/runtime/vam/expr/index.go +++ b/runtime/vam/expr/index.go @@ -35,7 +35,7 @@ func (i *Index) eval(args ...vector.Any) vector.Any { case vector.KindMap: return indexMap(i.sctx, container, index) default: - return vector.NewWrappedError(i.sctx, "entity cannot be indexed", container) + return vector.NewWrappedError(i.sctx, "value cannot be indexed", container) } } diff --git a/runtime/vcache/bool.go b/runtime/vcache/bool.go index aef9539965..f2657e8265 100644 --- a/runtime/vcache/bool.go +++ b/runtime/vcache/bool.go @@ -29,7 +29,7 @@ func (*bool_) unmarshal(*csup.Context, field.Projection) {} func (b *bool_) project(loader *loader, projection field.Projection) vector.Any { vec := vector.NewBool(b.load(loader)) if len(projection) > 0 { - return vector.NewWrappedError(loader.sctx, "dot operator on non-record", vec) + return vector.NewWrappedError(loader.sctx, "'.': applied to non-record", vec) } return vec } diff --git a/runtime/vcache/bytes.go b/runtime/vcache/bytes.go index 2f9ffa03bf..72603b8b1d 100644 --- a/runtime/vcache/bytes.go +++ b/runtime/vcache/bytes.go @@ -38,7 +38,7 @@ func (b *bytes) project(loader *loader, projection field.Projection) vector.Any panic(b.meta.Typ) } if len(projection) > 0 { - return vector.NewWrappedError(loader.sctx, "dot operator on non-record", vec) + return vector.NewWrappedError(loader.sctx, "'.': applied to non-record", vec) } return vec } diff --git a/runtime/vcache/const.go b/runtime/vcache/const.go index b9c7aa1805..a46c78f936 100644 --- a/runtime/vcache/const.go +++ b/runtime/vcache/const.go @@ -35,7 +35,7 @@ func (c *const_) project(loader *loader, projection field.Projection) vector.Any } vec := vector.NewConstFromValue(loader.sctx, super.NewValue(typ, val.Bytes()), c.length()) if len(projection) > 0 { - return vector.NewWrappedError(loader.sctx, "dot operator on non-record", vec) + return vector.NewWrappedError(loader.sctx, "'.': applied to non-record", vec) } return vec } diff --git a/runtime/vcache/dict.go b/runtime/vcache/dict.go index 67474c5580..06cc57f6a3 100644 --- a/runtime/vcache/dict.go +++ b/runtime/vcache/dict.go @@ -38,7 +38,7 @@ func (d *dict) project(loader *loader, projection field.Projection) vector.Any { index, counts := d.load(loader) vec := vector.NewDict(d.values.project(loader, projection), index, counts) if len(projection) > 0 { - return vector.NewWrappedError(loader.sctx, "dot operator on non-record", vec) + return vector.NewWrappedError(loader.sctx, "'.': applied to non-record", vec) } return vec } diff --git a/runtime/vcache/float.go b/runtime/vcache/float.go index 80aad4127b..e3a6aa2fe8 100644 --- a/runtime/vcache/float.go +++ b/runtime/vcache/float.go @@ -29,7 +29,7 @@ func (*float) unmarshal(*csup.Context, field.Projection) {} func (f *float) project(loader *loader, projection field.Projection) vector.Any { vec := vector.NewFloat(f.meta.Typ, f.load(loader)) if len(projection) > 0 { - return vector.NewWrappedError(loader.sctx, "dot operator on non-record", vec) + return vector.NewWrappedError(loader.sctx, "'.': applied to non-record", vec) } return vec } diff --git a/runtime/vcache/int.go b/runtime/vcache/int.go index fd12d0310c..c68b3fd989 100644 --- a/runtime/vcache/int.go +++ b/runtime/vcache/int.go @@ -30,7 +30,7 @@ func (*int_) unmarshal(*csup.Context, field.Projection) {} func (i *int_) project(loader *loader, projection field.Projection) vector.Any { vec := vector.NewInt(i.meta.Typ, i.load(loader)) if len(projection) > 0 { - return vector.NewWrappedError(loader.sctx, "dot operator on non-record", vec) + return vector.NewWrappedError(loader.sctx, "'.': applied to non-record", vec) } return vec } diff --git a/runtime/vcache/ip.go b/runtime/vcache/ip.go index e9ee6d2f63..8bbc82eeeb 100644 --- a/runtime/vcache/ip.go +++ b/runtime/vcache/ip.go @@ -28,7 +28,7 @@ func (*ip) unmarshal(*csup.Context, field.Projection) {} func (i *ip) project(loader *loader, projection field.Projection) vector.Any { vec := vector.NewIP(i.load(loader)) if len(projection) > 0 { - return vector.NewWrappedError(loader.sctx, "dot operator on non-record", vec) + return vector.NewWrappedError(loader.sctx, "'.': applied to non-record", vec) } return vec } diff --git a/runtime/vcache/net.go b/runtime/vcache/net.go index 235c0294af..0361f3a0d6 100644 --- a/runtime/vcache/net.go +++ b/runtime/vcache/net.go @@ -28,7 +28,7 @@ func (*net) unmarshal(*csup.Context, field.Projection) {} func (n *net) project(loader *loader, projection field.Projection) vector.Any { vec := vector.NewNet(n.load(loader)) if len(projection) > 0 { - return vector.NewWrappedError(loader.sctx, "dot operator on non-record", vec) + return vector.NewWrappedError(loader.sctx, "'.': applied to non-record", vec) } return vec } diff --git a/runtime/vcache/none.go b/runtime/vcache/none.go index 4fecebe142..4a9e80161d 100644 --- a/runtime/vcache/none.go +++ b/runtime/vcache/none.go @@ -23,7 +23,7 @@ func (*none) unmarshal(*csup.Context, field.Projection) {} func (n *none) project(loader *loader, projection field.Projection) vector.Any { vec := vector.NewNone(n.meta.Count) if len(projection) > 0 { - return vector.NewWrappedError(loader.sctx, "dot operator on non-record", vec) + return vector.NewWrappedError(loader.sctx, "'.': applied to non-record", vec) } return vec } diff --git a/runtime/vcache/null.go b/runtime/vcache/null.go index 7d5c7e540f..661ab6c6d7 100644 --- a/runtime/vcache/null.go +++ b/runtime/vcache/null.go @@ -23,7 +23,7 @@ func (*null) unmarshal(*csup.Context, field.Projection) {} func (n *null) project(loader *loader, projection field.Projection) vector.Any { vec := vector.NewNull(n.meta.Count) if len(projection) > 0 { - return vector.NewWrappedError(loader.sctx, "dot operator on non-record", vec) + return vector.NewWrappedError(loader.sctx, "'.': applied to non-record", vec) } return vec } diff --git a/runtime/vcache/record.go b/runtime/vcache/record.go index 6a1273cfc7..e284d0ccc0 100644 --- a/runtime/vcache/record.go +++ b/runtime/vcache/record.go @@ -8,6 +8,7 @@ import ( "github.com/brimdata/super" "github.com/brimdata/super/csup" "github.com/brimdata/super/pkg/field" + "github.com/brimdata/super/sup" "github.com/brimdata/super/vector" ) @@ -75,7 +76,7 @@ func (r *record) project(loader *loader, projection field.Projection) vector.Any if k := indexOfField(node.Name, r.meta); k >= 0 && r.fields[k] != nil { val = r.fields[k].project(loader, node.Proj) } else { - val = vector.NewStringError(loader.sctx, fmt.Sprintf("no such field %s", node.Name), r.length()) + val = vector.NewStringError(loader.sctx, fmt.Sprintf("no such field %s", sup.QuotedName(node.Name)), r.length()) } valFields = append(valFields, val) fields = append(fields, super.NewField(node.Name, val.Type())) diff --git a/runtime/vcache/type.go b/runtime/vcache/type.go index 65c0dcd016..7853ca0625 100644 --- a/runtime/vcache/type.go +++ b/runtime/vcache/type.go @@ -35,7 +35,7 @@ func (*typevalue) unmarshal(*csup.Context, field.Projection) {} func (t *typevalue) project(loader *loader, projection field.Projection) vector.Any { vec := vector.NewTypeValueWithLoader(loader.sctx, t.newLoader(loader)) if len(projection) > 0 { - return vector.NewWrappedError(loader.sctx, "dot operator on non-record", vec) + return vector.NewWrappedError(loader.sctx, "'.': applied to non-record", vec) } return vec } diff --git a/runtime/vcache/uint.go b/runtime/vcache/uint.go index aa872eeedb..b64d7faca9 100644 --- a/runtime/vcache/uint.go +++ b/runtime/vcache/uint.go @@ -30,7 +30,7 @@ func (*uint_) unmarshal(*csup.Context, field.Projection) {} func (u *uint_) project(loader *loader, projection field.Projection) vector.Any { vec := vector.NewUint(u.meta.Typ, u.load(loader)) if len(projection) > 0 { - return vector.NewWrappedError(loader.sctx, "dot operator on non-record", vec) + return vector.NewWrappedError(loader.sctx, "'.': applied to non-record", vec) } return vec } diff --git a/runtime/vcache/ztests/projection.yaml b/runtime/vcache/ztests/projection.yaml index 337242e009..2294e05b9d 100644 --- a/runtime/vcache/ztests/projection.yaml +++ b/runtime/vcache/ztests/projection.yaml @@ -53,6 +53,6 @@ outputs: {y:4,w:error("no such field w")} {y:error("no such field y"),w:{y:5}} === - error({message:"dot operator on non-record",on:1}) - error({message:"dot operator on non-record",on:2}) - error({message:"dot operator on non-record",on:3}) + error({message:"'.': applied to non-record",on:1}) + error({message:"'.': applied to non-record",on:2}) + error({message:"'.': applied to non-record",on:3}) diff --git a/runtime/ztests/expr/function/nameof.yaml b/runtime/ztests/expr/function/nameof.yaml index f1d7e47840..6e971161aa 100644 --- a/runtime/ztests/expr/function/nameof.yaml +++ b/runtime/ztests/expr/function/nameof.yaml @@ -28,7 +28,7 @@ output: | error({message:"nameof: not a type",on:{y:1}}) error({message:"nameof: not a type",on:{x:"foo",y:1,z:2}}) "bar2" - error({message:"not a named type",on:<{x:string,y:int64,z:int64}>}) + error({message:"nameof: not a named type",on:<{x:string,y:int64,z:int64}>}) error({message:"nameof: not a type",on:null}) error({message:"nameof: not a type",on:1}) error({message:"nameof: not a type",on:null}) diff --git a/runtime/ztests/expr/index.yaml b/runtime/ztests/expr/index.yaml index e677ee95c2..0c34afd208 100644 --- a/runtime/ztests/expr/index.yaml +++ b/runtime/ztests/expr/index.yaml @@ -39,7 +39,7 @@ output: | 1 null error({message:"index out of range",on:-5}) - error({message:"entity cannot be indexed",on:null}) + error({message:"value cannot be indexed",on:null}) error({message:"index is not an integer",on:null}) error({message:"index is not an integer",on:"hi"}) error({message:"cannot cast to int64",on:9223372036854775808::uint64}) @@ -121,5 +121,5 @@ input: | {val:fusion([1,{r:3}]::(int64|[int64|{r:int64}]),<[int64|{r:int64}]>)} output: | - error({message:"'.': applied to non-record",on:error({message:"entity cannot be indexed",on:2})}) + error({message:"'.': applied to non-record",on:error({message:"value cannot be indexed",on:2})}) 3 diff --git a/runtime/ztests/expr/slice.yaml b/runtime/ztests/expr/slice.yaml index 10714cde10..1dc6e665b0 100644 --- a/runtime/ztests/expr/slice.yaml +++ b/runtime/ztests/expr/slice.yaml @@ -17,10 +17,10 @@ output: | {a1:0x,a2:0x,a3:0x,a4:0x,a5:0x,a6:0x,a7:0x,a8:null} {a1:"",a2:"",a3:"",a4:"",a5:"",a6:"",a7:"",a8:null} {a1:[]::[int32],a2:[]::[int32],a3:[]::[int32],a4:[]::[int32],a5:[]::[int32],a6:[]::[int32],a7:[]::[int32],a8:null} - {a1:0x1122,a2:0x112233,a3:0x00,a4:0x001122,a5:0x,a6:0x33,a7:0x22,a8:error({message:"slice expression: error value encountered",on:error({message:"-: error value encountered",on:error({message:"entity cannot be indexed",on:0x00112233})})})} - {a1:"12",a2:"123",a3:"0",a4:"012",a5:"",a6:"3",a7:"2",a8:error({message:"slice expression: error value encountered",on:error({message:"-: error value encountered",on:error({message:"entity cannot be indexed",on:"0123"})})})} - {a1:"ⁱ⁲",a2:"ⁱ⁲3",a3:"0",a4:"0ⁱ⁲",a5:"",a6:"3",a7:"⁲",a8:error({message:"slice expression: error value encountered",on:error({message:"-: error value encountered",on:error({message:"entity cannot be indexed",on:"0ⁱ⁲3"})})})} - {a1:"ⁱ⁲",a2:"ⁱ⁲⁳",a3:"⁰",a4:"⁰ⁱ⁲",a5:"",a6:"⁳",a7:"⁲",a8:error({message:"slice expression: error value encountered",on:error({message:"-: error value encountered",on:error({message:"entity cannot be indexed",on:"⁰ⁱ⁲⁳"})})})} + {a1:0x1122,a2:0x112233,a3:0x00,a4:0x001122,a5:0x,a6:0x33,a7:0x22,a8:error({message:"slice expression: error value encountered",on:error({message:"-: error value encountered",on:error({message:"value cannot be indexed",on:0x00112233})})})} + {a1:"12",a2:"123",a3:"0",a4:"012",a5:"",a6:"3",a7:"2",a8:error({message:"slice expression: error value encountered",on:error({message:"-: error value encountered",on:error({message:"value cannot be indexed",on:"0123"})})})} + {a1:"ⁱ⁲",a2:"ⁱ⁲3",a3:"0",a4:"0ⁱ⁲",a5:"",a6:"3",a7:"⁲",a8:error({message:"slice expression: error value encountered",on:error({message:"-: error value encountered",on:error({message:"value cannot be indexed",on:"0ⁱ⁲3"})})})} + {a1:"ⁱ⁲",a2:"ⁱ⁲⁳",a3:"⁰",a4:"⁰ⁱ⁲",a5:"",a6:"⁳",a7:"⁲",a8:error({message:"slice expression: error value encountered",on:error({message:"-: error value encountered",on:error({message:"value cannot be indexed",on:"⁰ⁱ⁲⁳"})})})} {a1:[11::int32,12::int32],a2:[11::int32,12::int32,13::int32],a3:[10::int32],a4:[10::int32,11::int32,12::int32],a5:[]::[int32],a6:[13::int32],a7:[12::int32],a8:[10::int32,11::int32]} {a1:set[11::int32,12::int32],a2:set[11::int32,12::int32,13::int32],a3:set[10::int32],a4:set[10::int32,11::int32,12::int32],a5:set[]::set[int32],a6:set[13::int32],a7:set[12::int32],a8:set[10::int32,11::int32]} diff --git a/runtime/ztests/op/aggregate/missing.yaml b/runtime/ztests/op/aggregate/missing.yaml index dfff5dcb03..f29681945f 100644 --- a/runtime/ztests/op/aggregate/missing.yaml +++ b/runtime/ztests/op/aggregate/missing.yaml @@ -9,4 +9,4 @@ input: | output: | {a:0,b:1} {a:error({message:"index out of range",on:0}),b:1} - {a:error({message:"entity cannot be indexed",on:"a"}),b:error({message:"'.': applied to non-record",on:"b"})} + {a:error({message:"value cannot be indexed",on:"a"}),b:error({message:"'.': applied to non-record",on:"b"})}