Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion book/src/super-sql/declarations/pragmas.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ values {
"bar"
[1,2,3]
# expected output
{a:"a",b:error("missing")}
{a:"a",b:error({message:"value cannot be indexed",on:"bar"})}
{a:[2],b:1}
```

Expand Down
14 changes: 7 additions & 7 deletions book/src/super-sql/expressions/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ value in the set of that index ordered by total order of values.
If `<entity>` is a map, then the `<index>` 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 `<entity>` is a string, then the `<index>` operand
must be coercible to an integer and the result is an integer representing
Expand Down Expand Up @@ -75,8 +75,8 @@ values a[2]
# expected output
3
3
error("missing")
error("missing")
error({message:"value cannot be indexed",on:"1234"})
error({message:"value cannot be indexed",on:0x01020304})
```

---
Expand All @@ -95,8 +95,8 @@ values a[2]
# expected output
2
2
error("missing")
error("missing")
error({message:"value cannot be indexed",on:"1234"})
error({message:"value cannot be indexed",on:0x01020304})
```

---
Expand All @@ -114,6 +114,6 @@ values a[-1]
# expected output
4
4
error("missing")
error("missing")
error({message:"value cannot be indexed",on:"1234"})
error({message:"value cannot be indexed",on:0x01020304})
```
4 changes: 2 additions & 2 deletions book/src/super-sql/functions/types/nameof.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -28,5 +28,5 @@ type port=int16
80
# expected output
"port"
error("missing")
error({message:"nameof: not a type",on:80})
```
6 changes: 3 additions & 3 deletions book/src/super-sql/functions/types/typename.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -48,13 +48,13 @@ 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
values typename("port")
# input
80
# expected output
error("missing")
error({message:"typename: unknown type name",on:"port"})
```
5 changes: 2 additions & 3 deletions compiler/rungen/op.go
Original file line number Diff line number Diff line change
Expand Up @@ -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))
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/semantic/op.go
Original file line number Diff line number Diff line change
Expand Up @@ -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}, ""
}
Expand Down
3 changes: 1 addition & 2 deletions runtime/vam/expr/dot.go
Original file line number Diff line number Diff line change
Expand Up @@ -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", sup.QuotedName(d.field)), typvals, val, errs)
}
return typvals
case *vector.Map:
Expand Down
6 changes: 3 additions & 3 deletions runtime/vam/expr/function/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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, "nameof: not a named type", out, vec, errs)
}
return out
}
Expand Down Expand Up @@ -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
}
Expand Down
20 changes: 10 additions & 10 deletions runtime/vam/expr/index.go
Original file line number Diff line number Diff line change
Expand Up @@ -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, "value cannot be indexed", container)
}
}

Expand Down Expand Up @@ -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
}
Expand Down Expand Up @@ -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)
Expand All @@ -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
Expand All @@ -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)
}
Expand All @@ -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
Expand All @@ -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
}
5 changes: 3 additions & 2 deletions runtime/vcache/bool.go
Original file line number Diff line number Diff line change
Expand Up @@ -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, "'.': applied to non-record", vec)
}
return vector.NewBool(b.load(loader))
return vec
}

func (b *bool_) load(loader *loader) bitvec.Bits {
Expand Down
12 changes: 7 additions & 5 deletions runtime/vcache/bytes.go
Original file line number Diff line number Diff line change
Expand Up @@ -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, "'.': applied to non-record", vec)
}
return vec
}

func (b *bytes) load(loader *loader) vector.BytesTable {
Expand Down
9 changes: 5 additions & 4 deletions runtime/vcache/const.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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, "'.': applied to non-record", vec)
}
return vec
}
7 changes: 4 additions & 3 deletions runtime/vcache/dict.go
Original file line number Diff line number Diff line change
Expand Up @@ -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, "'.': applied to 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) {
Expand Down
5 changes: 3 additions & 2 deletions runtime/vcache/float.go
Original file line number Diff line number Diff line change
Expand Up @@ -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, "'.': applied to non-record", vec)
}
return vector.NewFloat(f.meta.Typ, f.load(loader))
return vec
}

func (f *float) load(loader *loader) []float64 {
Expand Down
5 changes: 3 additions & 2 deletions runtime/vcache/int.go
Original file line number Diff line number Diff line change
Expand Up @@ -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, "'.': applied to non-record", vec)
}
return vector.NewInt(i.meta.Typ, i.load(loader))
return vec
}

func (i *int_) load(loader *loader) []int64 {
Expand Down
5 changes: 3 additions & 2 deletions runtime/vcache/ip.go
Original file line number Diff line number Diff line change
Expand Up @@ -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, "'.': applied to non-record", vec)
}
return vector.NewIP(i.load(loader))
return vec
}

func (i *ip) load(loader *loader) []netip.Addr {
Expand Down
5 changes: 3 additions & 2 deletions runtime/vcache/net.go
Original file line number Diff line number Diff line change
Expand Up @@ -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, "'.': applied to non-record", vec)
}
return vector.NewNet(n.load(loader))
return vec
}

func (n *net) load(loader *loader) []netip.Prefix {
Expand Down
5 changes: 3 additions & 2 deletions runtime/vcache/none.go
Original file line number Diff line number Diff line change
Expand Up @@ -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, "'.': applied to non-record", vec)
}
return vector.NewNone(n.meta.Count)
return vec
}
5 changes: 3 additions & 2 deletions runtime/vcache/null.go
Original file line number Diff line number Diff line change
Expand Up @@ -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, "'.': applied to non-record", vec)
}
return vector.NewNull(n.meta.Count)
return vec
}
Loading
Loading