arr-ai / arrai

The ultimate data engine.
http://arr.ai
Apache License 2.0
20 stars 15 forks source link

//tuple fails for empty keys #571

Closed orlade-anz closed 4 years ago

orlade-anz commented 4 years ago

Please do not post any internal, closed source snippets on this public issue tracker!

Description

//tuple(dict) converts a dict to a tuple. However if one of the dict's keys is an empty string, it panics.

Steps to Reproduce

  1. arrai eval '//tuple({"": 1})'

Expected behavior

('': 1)

Actual behavior

panic: interface conversion: rel.Value is rel.GenericSet, not rel.String

goroutine 1 [running]:
github.com/arr-ai/arrai/syntax.StdScope.func1.2(0x19f14e0, 0xc000b185e0, 0x1, 0x101000005, 0x18b75e0, 0x1f8af64)
        /Users/ladeo/dev/arrai/syntax/std.go:55 +0x568
github.com/arr-ai/arrai/rel.(*NativeFunction).CallAll(0xc000a85fc0, 0x19f14e0, 0xc000b185e0, 0xc000af9930, 0x15fcdf9, 0x100b02b, 0xc000020000)
        /Users/ladeo/dev/arrai/rel/value_set_native_func.go:126 +0x42
github.com/arr-ai/arrai/rel.SetCall(0x19f53a0, 0xc000a85fc0, 0x19f14e0, 0xc000b185e0, 0xc000a85fc0, 0xc000548e01, 0x8, 0x7)
        /Users/ladeo/dev/arrai/rel/value.go:142 +0x63
github.com/arr-ai/arrai/rel.Call(0x19f11e0, 0xc000a85fc0, 0x19f14e0, 0xc000b185e0, 0x0, 0x0, 0x0, 0xc000548ea0, 0x18b70b5, 0x7ffeefbff5a3)
        /Users/ladeo/dev/arrai/rel/expr_binary.go:260 +0x107
github.com/arr-ai/arrai/rel.(*BinExpr).Eval(0xc000526070, 0x0, 0x0, 0x10, 0x19e3fe0, 0xc000526070, 0x0)
        /Users/ladeo/dev/arrai/rel/expr_binary.go:294 +0x12c
github.com/arr-ai/arrai/syntax.EvalWithScope(0x18b70b5, 0x1, 0x7ffeefbff5a3, 0x10, 0x0, 0x0, 0x17e1380, 0x100b349, 0xc000020000, 0x273aa20)
        /Users/ladeo/dev/arrai/syntax/eval.go:13 +0x88
github.com/arr-ai/arrai/syntax.EvaluateExpr(...)
        /Users/ladeo/dev/arrai/syntax/eval.go:22
main.evalExpr(0x19e7f20, 0xc0002336e0, 0x18b70b5, 0x1, 0x7ffeefbff5a3, 0x10, 0x19d59c0, 0xc000010018, 0x0, 0x0, ...)
        /Users/ladeo/dev/arrai/cmd/arrai/eval.go:52 +0x72
main.evalImpl(...)
        /Users/ladeo/dev/arrai/cmd/arrai/eval.go:48
main.eval(0xc0002b3640, 0x2, 0x2)
        /Users/ladeo/dev/arrai/cmd/arrai/eval.go:44 +0x2d5
github.com/urfave/cli/v2.(*Command).Run(0x1f51dc0, 0xc0002b3500, 0x0, 0x0)
        /Users/ladeo/go/pkg/mod/github.com/urfave/cli/v2@v2.2.0/command.go:164 +0x4e0
github.com/urfave/cli/v2.(*App).RunContext(0xc000603080, 0x19e7ea0, 0xc000038098, 0xc0000321b0, 0x3, 0x3, 0x0, 0x0)
        /Users/ladeo/go/pkg/mod/github.com/urfave/cli/v2@v2.2.0/app.go:306 +0x814
github.com/urfave/cli/v2.(*App).Run(...)
        /Users/ladeo/go/pkg/mod/github.com/urfave/cli/v2@v2.2.0/app.go:215
main.main()
        /Users/ladeo/dev/arrai/cmd/arrai/main.go:95 +0x155

Your Environment

$ arrai info
Version    : DIRTY-v0.128.0
Git commit : 81f302899df339eaefb70f32c77a7ef1c74fc67d
Date       : 2020-08-12T07:53:25Z
OS/arch    : darwin/amd64
Go version : go1.14.4 darwin/amd64
orlade-anz commented 4 years ago

Dumb workaround:

let safetuple = \d
    let empty = d('')?:{};
    let rest = //tuple(d without (@:'', @value:empty));
    cond {
        empty: rest +> ('': empty),
        _: rest,
    }
;
anzdaddy commented 4 years ago

The workaround doesn't handle dicts where the '' key holds a falsy value. Here's a safer version:

let safetuple = \d
    let rest = //tuple(d where .@ != '');
    cond d where .@ = '' {
        {(@:'', @value: value)}: rest +> (@: value),
        _: rest,
    };