diff --git a/runtime/vam/expr/function/flatten.go b/runtime/vam/expr/function/flatten.go index a4889612a0..c76c42e5dd 100644 --- a/runtime/vam/expr/function/flatten.go +++ b/runtime/vam/expr/function/flatten.go @@ -31,3 +31,25 @@ func (f *flatten) Call(args ...vector.Any) vector.Any { } return builder.Build() } + +type unflatten struct { + fn *samfunc.Unflatten +} + +func newUnflatten(zctx *super.Context) *unflatten { + return &unflatten{samfunc.NewUnflatten(zctx)} +} + +func (u *unflatten) Call(args ...vector.Any) vector.Any { + vec := vector.Under(args[0]) + typ := vec.Type() + builder := vector.NewDynamicBuilder() + var b zcode.Builder + for i := range vec.Len() { + b.Truncate() + vec.Serialize(&b, i) + val := u.fn.Call(nil, []super.Value{super.NewValue(typ, b.Bytes().Body())}) + builder.Write(val) + } + return builder.Build() +} diff --git a/runtime/vam/expr/function/function.go b/runtime/vam/expr/function/function.go index 84a25473d0..8bf03b4efd 100644 --- a/runtime/vam/expr/function/function.go +++ b/runtime/vam/expr/function/function.go @@ -113,10 +113,12 @@ func New(zctx *super.Context, name string, narg int) (expr.Function, field.Path, f = &TypeName{zctx: zctx} case "typeof": f = &TypeOf{zctx} - case "upper": - f = &ToUpper{zctx} case "under": f = &Under{zctx} + case "unflatten": + f = newUnflatten(zctx) + case "upper": + f = &ToUpper{zctx} default: return nil, nil, function.ErrNoSuchFunction } diff --git a/runtime/sam/expr/function/ztests/unflatten.yaml b/runtime/ztests/expr/function/unflatten.yaml similarity index 95% rename from runtime/sam/expr/function/ztests/unflatten.yaml rename to runtime/ztests/expr/function/unflatten.yaml index 40ada5f181..71bbab1662 100644 --- a/runtime/sam/expr/function/ztests/unflatten.yaml +++ b/runtime/ztests/expr/function/unflatten.yaml @@ -1,4 +1,6 @@ -zed: "yield unflatten(this)" +zed: yield unflatten(this) + +vector: true input: | [{key:["a","a"],value:1},{key:["a","b"],value:2},{key:["a","x","z"],value:"foo"},{key:["b"],value:2},{key:["c"],value:3}]