diff --git a/runtime/sam/expr/function/cast.go b/runtime/sam/expr/function/cast.go index 18158b652..996e25e75 100644 --- a/runtime/sam/expr/function/cast.go +++ b/runtime/sam/expr/function/cast.go @@ -24,6 +24,7 @@ func NewCaster(sctx *super.Context) Caster { func (c *cast) Call(args []super.Value) super.Value { from, to := args[0], args[1] + from = from.SuperDeunion() if from.IsError() { return from } diff --git a/runtime/vam/expr/cast.go b/runtime/vam/expr/cast.go index 4ffaf158c..408d29939 100644 --- a/runtime/vam/expr/cast.go +++ b/runtime/vam/expr/cast.go @@ -39,7 +39,7 @@ type casterPrimitive struct { } func (c *casterPrimitive) Eval(this vector.Any) vector.Any { - return vector.Apply(vector.ApplyRipUnions, func(vecs ...vector.Any) vector.Any { + return vector.Apply(vector.ApplyRipFusions|vector.ApplyRipUnions, func(vecs ...vector.Any) vector.Any { return cast.To(c.sctx, vecs[0], c.typ) }, c.expr.Eval(this)) } @@ -51,7 +51,7 @@ type casterNamedType struct { } func (c *casterNamedType) Eval(this vector.Any) vector.Any { - return vector.Apply(vector.ApplyNone, c.eval, c.expr.Eval(this)) + return vector.Apply(vector.ApplyRipFusions|vector.ApplyRipUnions, c.eval, c.expr.Eval(this)) } func (c *casterNamedType) eval(vecs ...vector.Any) vector.Any { diff --git a/runtime/ztests/expr/cast/bool.yaml b/runtime/ztests/expr/cast/bool.yaml index 98386fecd..5af096966 100644 --- a/runtime/ztests/expr/cast/bool.yaml +++ b/runtime/ztests/expr/cast/bool.yaml @@ -14,6 +14,7 @@ input: | "true" "F" "false" + fusion("false"::(string|null),) "blah" null null::({}|null) @@ -38,6 +39,7 @@ output: | true false false + false error({message:"cannot cast to bool",on:"blah"}) null::(bool|null) null::(bool|null) diff --git a/runtime/ztests/expr/cast/bytes.yaml b/runtime/ztests/expr/cast/bytes.yaml index 8178f385a..7d6c6992f 100644 --- a/runtime/ztests/expr/cast/bytes.yaml +++ b/runtime/ztests/expr/cast/bytes.yaml @@ -6,6 +6,7 @@ input: | type named=string "bar"::named "" + fusion("a"::(string|null),) null null::({}|null) {x:"foo"} @@ -17,6 +18,7 @@ output: | 0x666f6f 0x626172 0x + 0x61 null::(bytes|null) null::(bytes|null) error({message:"cannot cast to bytes",on:{x:"foo"}}) diff --git a/runtime/ztests/expr/cast/duration.yaml b/runtime/ztests/expr/cast/duration.yaml index 69bf23713..3e5a28968 100644 --- a/runtime/ztests/expr/cast/duration.yaml +++ b/runtime/ztests/expr/cast/duration.yaml @@ -8,6 +8,7 @@ input: | -1.5e12 type named=int64 1::named + fusion(2::named::(named|null),) 1e+19 null null::({}|null) @@ -25,6 +26,7 @@ output: | error({message:"cannot cast to duration",on:""}) -25m 1ns + 2ns error({message:"cannot cast to duration",on:1e+19}) null::(duration|null) null::(duration|null) diff --git a/runtime/ztests/expr/cast/enum.yaml b/runtime/ztests/expr/cast/enum.yaml index cc0ea77cb..8fd222a8d 100644 --- a/runtime/ztests/expr/cast/enum.yaml +++ b/runtime/ztests/expr/cast/enum.yaml @@ -1,7 +1,8 @@ spq: this::enum(e1,e2) input: | - "e2" + "e1" + fusion("e2"::(string|null),) "e3" 0 null @@ -9,6 +10,7 @@ input: | error("bad") output: | + "e1"::enum(e1,e2) "e2"::enum(e1,e2) error({message:"no such symbol in enum(e1,e2)",on:"e3"}) error({message:"cannot cast to enum",on:0}) diff --git a/runtime/ztests/expr/cast/float.yaml b/runtime/ztests/expr/cast/float.yaml index a754b032e..bbfe4d918 100644 --- a/runtime/ztests/expr/cast/float.yaml +++ b/runtime/ztests/expr/cast/float.yaml @@ -10,6 +10,7 @@ input: | 2::named false true + fusion("2"::(string|null),) null null::({}|null) @@ -38,6 +39,9 @@ output: | 1.::float16 1.::float32 1. + 2.::float16 + 2.::float32 + 2. null::(float16|null) null::(float32|null) null::(float64|null) diff --git a/runtime/ztests/expr/cast/int.yaml b/runtime/ztests/expr/cast/int.yaml index 80d8b8eb3..0a436921c 100644 --- a/runtime/ztests/expr/cast/int.yaml +++ b/runtime/ztests/expr/cast/int.yaml @@ -12,6 +12,7 @@ input: | 1e8 false true + fusion("2"::(string|null),) null null::({}|null) @@ -52,6 +53,10 @@ output: | 1::int16 1::int32 1 + 2::int8 + 2::int16 + 2::int32 + 2 null::(int8|null) null::(int16|null) null::(int32|null) diff --git a/runtime/ztests/expr/cast/ip.yaml b/runtime/ztests/expr/cast/ip.yaml index a7eb86c4b..e51fe452f 100644 --- a/runtime/ztests/expr/cast/ip.yaml +++ b/runtime/ztests/expr/cast/ip.yaml @@ -4,6 +4,7 @@ input: | "foo" "127.0.0.1" "2001:0000:130F:0000:0000:09C0:876A:130B" + fusion("3000::"::(string|null),) null null::({}|null) 1.1.1.1 @@ -18,6 +19,7 @@ output: | error({message:"cannot cast to ip",on:"foo"}) 127.0.0.1 2001:0:130f::9c0:876a:130b + 3000:: null::(ip|null) null::(ip|null) 1.1.1.1 diff --git a/runtime/ztests/expr/cast/map.yaml b/runtime/ztests/expr/cast/map.yaml index ae7fc1cb3..6e1e284f7 100644 --- a/runtime/ztests/expr/cast/map.yaml +++ b/runtime/ztests/expr/cast/map.yaml @@ -3,6 +3,7 @@ spq: | input: | map{} + fusion(map{1:map{2:3}}::(null|map{int64:map{int64:int64}}),) map{1:map{"2":3,4:"5"},"7":8,"9":map{10:[],[]:11,null:null}} null null::({}|null) @@ -12,6 +13,7 @@ input: | output: | map{} + map{1:map{"2":3}} map{1:map{"2":3,"4":5},7:error({message:"cannot cast to map{string:int64}",on:8}),9:map{null:null,"10":error({message:"cannot cast to int64",on:[]}),"[]":11}} null::(null|map{int64:map{string:int64}}) null::(null|map{int64:map{string:int64}}) diff --git a/runtime/ztests/expr/cast/named.yaml b/runtime/ztests/expr/cast/named.yaml index 6b5ead2f3..752647908 100644 --- a/runtime/ztests/expr/cast/named.yaml +++ b/runtime/ztests/expr/cast/named.yaml @@ -5,6 +5,7 @@ spq: | input: | {x:1} {x:2} + fusion({x:3}::(null|{x:int64}),<{x:int64}>) "foo" "bar" type a=string @@ -18,6 +19,7 @@ output: | type named={x:int64} {x:1}::named {x:2}::named + {x:3}::named error("type \"named\" redefined") error("type \"named\" redefined") error("type \"named\" redefined") @@ -41,3 +43,4 @@ output: | type foo=int64 {str:1::foo,named:1::foo} {str:2::foo,named:2::foo} + diff --git a/runtime/ztests/expr/cast/net.yaml b/runtime/ztests/expr/cast/net.yaml index d4d1d09e7..0891fb408 100644 --- a/runtime/ztests/expr/cast/net.yaml +++ b/runtime/ztests/expr/cast/net.yaml @@ -3,6 +3,7 @@ spq: this::net input: | "192.168.1.0/24" "2001:db8::/32" + fusion("2001:db8::/33"::(string|null),) null null::({}|null) 10.0.0.0/8 @@ -16,6 +17,7 @@ input: | output: | 192.168.1.0/24 2001:db8::/32 + 2001:db8::/33 null::(net|null) null::(net|null) 10.0.0.0/8 diff --git a/runtime/ztests/expr/cast/record.yaml b/runtime/ztests/expr/cast/record.yaml index 01c2f2939..3b3e98643 100644 --- a/runtime/ztests/expr/cast/record.yaml +++ b/runtime/ztests/expr/cast/record.yaml @@ -7,6 +7,7 @@ input: | {b:1,c:2} {a:"1",b:2,c:{cc:3},d:[{e:4,f:"5"},{f:6,e:"7"},8]} {d:[{e:1,f:"2"},{f:3,e:"4"},5],c:null,b:6,a:"7"} + fusion({a:1,b:2,c:{},d:[]}::(null|{a:int64,b:int64,c:{},d:[none]}),<{a:int64,b:int64,c:{},d:[none]}>) null null::({}|null) 1 @@ -19,6 +20,7 @@ output: | {a:error("missing"),b:"1",c:error({message:"cannot cast to {}",on:2}),d:error("missing")} {a:1,b:"2",c:{},d:[{e:"4",f:5},{e:"7",f:6},error({message:"cannot cast to {e:string,f:int64}",on:8})]} {a:7,b:"6",c:null::(null|{}),d:[{e:"1",f:2},{e:"4",f:3},error({message:"cannot cast to {e:string,f:int64}",on:5})]} + {a:1,b:"2",c:{},d:[]::[{e:string,f:int64}]} null::(null|{a:int64,b:string,c:{},d:[{e:string,f:int64}]}) null::(null|{a:int64,b:string,c:{},d:[{e:string,f:int64}]}) error({message:"cannot cast to {a:int64,b:string,c:{},d:[{e:string,f:int64}]}",on:1}) diff --git a/runtime/ztests/expr/cast/string.yaml b/runtime/ztests/expr/cast/string.yaml index d15bfc460..68267d989 100644 --- a/runtime/ztests/expr/cast/string.yaml +++ b/runtime/ztests/expr/cast/string.yaml @@ -30,6 +30,7 @@ input: | {foo:"bar"} [1,2,3] "e2"::enum(e1,e2) + fusion(1::(int64|null),) error("bad") output: | @@ -61,4 +62,5 @@ output: | "{foo:\"bar\"}" "[1,2,3]" "e2" + "1" error("bad") diff --git a/runtime/ztests/expr/cast/time.yaml b/runtime/ztests/expr/cast/time.yaml index e3f6086d8..7865d6c6b 100644 --- a/runtime/ztests/expr/cast/time.yaml +++ b/runtime/ztests/expr/cast/time.yaml @@ -11,6 +11,7 @@ input: | "foo" -1e9 1 + fusion(1::(int64|null),) null null::({}|null) 1e200 @@ -31,6 +32,7 @@ output: | error({message:"cannot cast to time",on:"foo"}) 1969-12-31T23:59:59Z 1970-01-01T00:00:00.000000001Z + 1970-01-01T00:00:00.000000001Z null::(time|null) null::(time|null) error({message:"cannot cast to time",on:1e+200}) diff --git a/runtime/ztests/expr/cast/type.yaml b/runtime/ztests/expr/cast/type.yaml index 463e88bdd..86508c539 100644 --- a/runtime/ztests/expr/cast/type.yaml +++ b/runtime/ztests/expr/cast/type.yaml @@ -4,6 +4,7 @@ input: | "" "<{x:string}>" + fusion("<{x:string}>"::(string|null),) "{x:\"foo\"}" "" 1 @@ -11,11 +12,13 @@ input: | null null::({}|null) error("bad") + fusion(error(1)::(error(int64)|int64),) output: | <{x:string}> + <{x:string}> error({message:"cannot cast to type",on:"{x:\"foo\"}"}) error({message:"cannot cast to type",on:""}) error({message:"cannot cast to type",on:1}) @@ -23,3 +26,4 @@ output: | null::(type|null) null::(type|null) error("bad") + error(1) diff --git a/runtime/ztests/expr/cast/uint.yaml b/runtime/ztests/expr/cast/uint.yaml index 99d174593..0544c46f2 100644 --- a/runtime/ztests/expr/cast/uint.yaml +++ b/runtime/ztests/expr/cast/uint.yaml @@ -4,6 +4,7 @@ spq: | input: | false true + fusion(true::(bool|null),) -1 null null::({}|null) @@ -18,6 +19,10 @@ output: | 1::uint16 1::uint32 1::uint64 + 1::uint8 + 1::uint16 + 1::uint32 + 1::uint64 error({message:"cannot cast to uint8",on:-1}) error({message:"cannot cast to uint16",on:-1}) error({message:"cannot cast to uint32",on:-1})