build-scalar
1
----
const: 1 [type=int]

build-scalar
1 + 2
----
plus [type=int]
 ├── const: 1 [type=int]
 └── const: 2 [type=int]

build-scalar vars=(string)
@1
----
variable: @1 [type=string]

build-scalar vars=(int)
@1 + 2
----
plus [type=int]
 ├── variable: @1 [type=int]
 └── const: 2 [type=int]

build-scalar vars=(int, int)
@1 >= 5 AND @1 <= 10 AND @2 < 4
----
and [type=bool]
 ├── and [type=bool]
 │    ├── ge [type=bool]
 │    │    ├── variable: @1 [type=int]
 │    │    └── const: 5 [type=int]
 │    └── le [type=bool]
 │         ├── variable: @1 [type=int]
 │         └── const: 10 [type=int]
 └── lt [type=bool]
      ├── variable: @2 [type=int]
      └── const: 4 [type=int]

build-scalar vars=(int, int)
(@1, @2) = (1, 2)
----
eq [type=bool]
 ├── tuple [type=tuple{int, int}]
 │    ├── variable: @1 [type=int]
 │    └── variable: @2 [type=int]
 └── tuple [type=tuple{int, int}]
      ├── const: 1 [type=int]
      └── const: 2 [type=int]

build-scalar vars=(int)
@1 IN (1, 2)
----
in [type=bool]
 ├── variable: @1 [type=int]
 └── tuple [type=tuple{int, int}]
      ├── const: 1 [type=int]
      └── const: 2 [type=int]

build-scalar vars=(int, int)
(@1, @2) IN ((1, 2), (3, 4))
----
in [type=bool]
 ├── tuple [type=tuple{int, int}]
 │    ├── variable: @1 [type=int]
 │    └── variable: @2 [type=int]
 └── tuple [type=tuple{tuple{int, int}, tuple{int, int}}]
      ├── tuple [type=tuple{int, int}]
      │    ├── const: 1 [type=int]
      │    └── const: 2 [type=int]
      └── tuple [type=tuple{int, int}]
           ├── const: 3 [type=int]
           └── const: 4 [type=int]

build-scalar vars=(int, int, int, int)
(@1, @2 + @3, 5 + @4 * 2) = (@2 + @3, 8, @1 - @4)
----
eq [type=bool]
 ├── tuple [type=tuple{int, int, int}]
 │    ├── variable: @1 [type=int]
 │    ├── plus [type=int]
 │    │    ├── variable: @2 [type=int]
 │    │    └── variable: @3 [type=int]
 │    └── plus [type=int]
 │         ├── const: 5 [type=int]
 │         └── mult [type=int]
 │              ├── variable: @4 [type=int]
 │              └── const: 2 [type=int]
 └── tuple [type=tuple{int, int, int}]
      ├── plus [type=int]
      │    ├── variable: @2 [type=int]
      │    └── variable: @3 [type=int]
      ├── const: 8 [type=int]
      └── minus [type=int]
           ├── variable: @1 [type=int]
           └── variable: @4 [type=int]

build-scalar vars=(int, int, int, int)
((@1, @2), (@3, @4)) = ((1, 2), (3, 4))
----
eq [type=bool]
 ├── tuple [type=tuple{tuple{int, int}, tuple{int, int}}]
 │    ├── tuple [type=tuple{int, int}]
 │    │    ├── variable: @1 [type=int]
 │    │    └── variable: @2 [type=int]
 │    └── tuple [type=tuple{int, int}]
 │         ├── variable: @3 [type=int]
 │         └── variable: @4 [type=int]
 └── tuple [type=tuple{tuple{int, int}, tuple{int, int}}]
      ├── tuple [type=tuple{int, int}]
      │    ├── const: 1 [type=int]
      │    └── const: 2 [type=int]
      └── tuple [type=tuple{int, int}]
           ├── const: 3 [type=int]
           └── const: 4 [type=int]

build-scalar vars=(int, int, int, string)
(@1, (@2, 'a'), (@3, 'b', 5)) = (9, (@1 + @3, @4), (5, @4, @1))
----
eq [type=bool]
 ├── tuple [type=tuple{int, tuple{int, string}, tuple{int, string, int}}]
 │    ├── variable: @1 [type=int]
 │    ├── tuple [type=tuple{int, string}]
 │    │    ├── variable: @2 [type=int]
 │    │    └── const: 'a' [type=string]
 │    └── tuple [type=tuple{int, string, int}]
 │         ├── variable: @3 [type=int]
 │         ├── const: 'b' [type=string]
 │         └── const: 5 [type=int]
 └── tuple [type=tuple{int, tuple{int, string}, tuple{int, string, int}}]
      ├── const: 9 [type=int]
      ├── tuple [type=tuple{int, string}]
      │    ├── plus [type=int]
      │    │    ├── variable: @1 [type=int]
      │    │    └── variable: @3 [type=int]
      │    └── variable: @4 [type=string]
      └── tuple [type=tuple{int, string, int}]
           ├── const: 5 [type=int]
           ├── variable: @4 [type=string]
           └── variable: @1 [type=int]

build-scalar vars=(int, int)
@1 IS NULL
----
is [type=bool]
 ├── variable: @1 [type=int]
 └── null [type=unknown]

build-scalar vars=(int, int)
@1 IS NOT DISTINCT FROM NULL
----
is [type=bool]
 ├── variable: @1 [type=int]
 └── null [type=unknown]

build-scalar vars=(int, int)
@1 IS NOT DISTINCT FROM @2
----
is [type=bool]
 ├── variable: @1 [type=int]
 └── variable: @2 [type=int]

build-scalar vars=(int, int)
@1 IS NOT NULL
----
is-not [type=bool]
 ├── variable: @1 [type=int]
 └── null [type=unknown]

build-scalar vars=(int, int)
@1 IS DISTINCT FROM NULL
----
is-not [type=bool]
 ├── variable: @1 [type=int]
 └── null [type=unknown]

build-scalar vars=(int, int)
@1 IS DISTINCT FROM @2
----
is-not [type=bool]
 ├── variable: @1 [type=int]
 └── variable: @2 [type=int]

build-scalar vars=(int, int)
+ @1 + (- @2)
----
plus [type=int]
 ├── variable: @1 [type=int]
 └── unary-minus [type=int]
      └── variable: @2 [type=int]

build-scalar vars=(int, int)
CASE WHEN @1 = 2 THEN 1 ELSE 2 END
----
case [type=int]
 ├── true [type=bool]
 ├── when [type=int]
 │    ├── eq [type=bool]
 │    │    ├── variable: @1 [type=int]
 │    │    └── const: 2 [type=int]
 │    └── const: 1 [type=int]
 └── const: 2 [type=int]

build-scalar
if(true, 1, 2)
----
case [type=int]
 ├── true [type=bool]
 ├── when [type=int]
 │    ├── true [type=bool]
 │    └── const: 1 [type=int]
 └── const: 2 [type=int]

build-scalar
if(false, null, 1)
----
case [type=int]
 ├── false [type=bool]
 ├── when [type=unknown]
 │    ├── true [type=bool]
 │    └── null [type=unknown]
 └── const: 1 [type=int]

build-scalar
nullif(1, 2)
----
case [type=int]
 ├── const: 1 [type=int]
 ├── when [type=unknown]
 │    ├── const: 2 [type=int]
 │    └── null [type=unknown]
 └── const: 1 [type=int]

build-scalar vars=(string)
length(@1) = 2
----
eq [type=bool]
 ├── function: length [type=int]
 │    └── variable: @1 [type=string]
 └── const: 2 [type=int]


build-scalar vars=(jsonb)
@1 @> '{"a":1}'
----
contains [type=bool]
 ├── variable: @1 [type=jsonb]
 └── const: '{"a": 1}' [type=jsonb]

build-scalar vars=(jsonb)
'{"a":1}' <@ @1
----
contains [type=bool]
 ├── variable: @1 [type=jsonb]
 └── const: '{"a": 1}' [type=jsonb]

build-scalar vars=(jsonb)
@1 ? 'a'
----
json-exists [type=bool]
 ├── variable: @1 [type=jsonb]
 └── const: 'a' [type=string]

build-scalar vars=(jsonb)
@1 ?| ARRAY['a', 'b', 'c']
----
json-some-exists [type=bool]
 ├── variable: @1 [type=jsonb]
 └── array: [type=string[]]
      ├── const: 'a' [type=string]
      ├── const: 'b' [type=string]
      └── const: 'c' [type=string]

build-scalar vars=(jsonb)
@1 ?& ARRAY['a', 'b', 'c']
----
json-all-exists [type=bool]
 ├── variable: @1 [type=jsonb]
 └── array: [type=string[]]
      ├── const: 'a' [type=string]
      ├── const: 'b' [type=string]
      └── const: 'c' [type=string]

build-scalar
TRUE
----
true [type=bool]


build-scalar
FALSE
----
false [type=bool]

build-scalar
1::decimal
----
cast: DECIMAL [type=decimal]
 └── const: 1 [type=decimal]

build-scalar
1::float
----
cast: FLOAT8 [type=float]
 └── const: 1.0 [type=float]

build-scalar
1.1::int
----
cast: INT [type=int]
 └── const: 1.1 [type=decimal]

build-scalar
'2010-05-12'::timestamp
----
const: '2010-05-12 00:00:00+00:00' [type=timestamp]

build-scalar
'123'::int
----
cast: INT [type=int]
 └── const: 123 [type=int]

build-scalar vars=(int, int)
IFNULL(@1, @2)
----
coalesce [type=int]
 ├── variable: @1 [type=int]
 └── variable: @2 [type=int]

build-scalar vars=(int, int, int)
COALESCE(@1, @2, @3)
----
coalesce [type=int]
 ├── variable: @1 [type=int]
 ├── variable: @2 [type=int]
 └── variable: @3 [type=int]

build-scalar vars=(int)
CASE WHEN @1 > 5 THEN 1 ELSE -1 END
----
case [type=int]
 ├── true [type=bool]
 ├── when [type=int]
 │    ├── gt [type=bool]
 │    │    ├── variable: @1 [type=int]
 │    │    └── const: 5 [type=int]
 │    └── const: 1 [type=int]
 └── const: -1 [type=int]

build-scalar vars=(int)
CASE WHEN @1 > 5 THEN 1 WHEN @1 < 0 THEN 2 ELSE -1 END
----
case [type=int]
 ├── true [type=bool]
 ├── when [type=int]
 │    ├── gt [type=bool]
 │    │    ├── variable: @1 [type=int]
 │    │    └── const: 5 [type=int]
 │    └── const: 1 [type=int]
 ├── when [type=int]
 │    ├── lt [type=bool]
 │    │    ├── variable: @1 [type=int]
 │    │    └── const: 0 [type=int]
 │    └── const: 2 [type=int]
 └── const: -1 [type=int]

build-scalar vars=(int)
CASE @1 WHEN 5 THEN 1 ELSE -1 END
----
case [type=int]
 ├── variable: @1 [type=int]
 ├── when [type=int]
 │    ├── const: 5 [type=int]
 │    └── const: 1 [type=int]
 └── const: -1 [type=int]

build-scalar vars=(int, int)
CASE @1 + 3 WHEN 5 * @2 THEN 1 % @2 WHEN 6 THEN 2 ELSE -1 END
----
case [type=int]
 ├── plus [type=int]
 │    ├── variable: @1 [type=int]
 │    └── const: 3 [type=int]
 ├── when [type=int]
 │    ├── mult [type=int]
 │    │    ├── const: 5 [type=int]
 │    │    └── variable: @2 [type=int]
 │    └── mod [type=int]
 │         ├── const: 1 [type=int]
 │         └── variable: @2 [type=int]
 ├── when [type=int]
 │    ├── const: 6 [type=int]
 │    └── const: 2 [type=int]
 └── const: -1 [type=int]

# Tests for CASE with no ELSE statement
build-scalar vars=(int)
CASE WHEN @1 > 5 THEN 1 END
----
case [type=int]
 ├── true [type=bool]
 ├── when [type=int]
 │    ├── gt [type=bool]
 │    │    ├── variable: @1 [type=int]
 │    │    └── const: 5 [type=int]
 │    └── const: 1 [type=int]
 └── null [type=unknown]

build-scalar vars=(int)
CASE @1 WHEN 5 THEN 1 END
----
case [type=int]
 ├── variable: @1 [type=int]
 ├── when [type=int]
 │    ├── const: 5 [type=int]
 │    └── const: 1 [type=int]
 └── null [type=unknown]

build-scalar vars=(int)
@1 BETWEEN 1 AND 4
----
and [type=bool]
 ├── ge [type=bool]
 │    ├── variable: @1 [type=int]
 │    └── const: 1 [type=int]
 └── le [type=bool]
      ├── variable: @1 [type=int]
      └── const: 4 [type=int]

build-scalar vars=(int)
@1 NOT BETWEEN 1 AND 4
----
not [type=bool]
 └── and [type=bool]
      ├── ge [type=bool]
      │    ├── variable: @1 [type=int]
      │    └── const: 1 [type=int]
      └── le [type=bool]
           ├── variable: @1 [type=int]
           └── const: 4 [type=int]

build-scalar vars=(int)
@1 BETWEEN SYMMETRIC 1 AND 4
----
or [type=bool]
 ├── and [type=bool]
 │    ├── ge [type=bool]
 │    │    ├── variable: @1 [type=int]
 │    │    └── const: 1 [type=int]
 │    └── le [type=bool]
 │         ├── variable: @1 [type=int]
 │         └── const: 4 [type=int]
 └── and [type=bool]
      ├── ge [type=bool]
      │    ├── variable: @1 [type=int]
      │    └── const: 4 [type=int]
      └── le [type=bool]
           ├── variable: @1 [type=int]
           └── const: 1 [type=int]

build-scalar vars=(int)
@1 NOT BETWEEN SYMMETRIC 1 AND 4
----
not [type=bool]
 └── or [type=bool]
      ├── and [type=bool]
      │    ├── ge [type=bool]
      │    │    ├── variable: @1 [type=int]
      │    │    └── const: 1 [type=int]
      │    └── le [type=bool]
      │         ├── variable: @1 [type=int]
      │         └── const: 4 [type=int]
      └── and [type=bool]
           ├── ge [type=bool]
           │    ├── variable: @1 [type=int]
           │    └── const: 4 [type=int]
           └── le [type=bool]
                ├── variable: @1 [type=int]
                └── const: 1 [type=int]

build-scalar vars=(int, int, int)
@1 BETWEEN @2 AND @3
----
and [type=bool]
 ├── ge [type=bool]
 │    ├── variable: @1 [type=int]
 │    └── variable: @2 [type=int]
 └── le [type=bool]
      ├── variable: @1 [type=int]
      └── variable: @3 [type=int]

build-scalar vars=(int, int, int)
(@1 + @2) BETWEEN (@2 + @3) AND (@3 + @1)
----
and [type=bool]
 ├── ge [type=bool]
 │    ├── plus [type=int]
 │    │    ├── variable: @1 [type=int]
 │    │    └── variable: @2 [type=int]
 │    └── plus [type=int]
 │         ├── variable: @2 [type=int]
 │         └── variable: @3 [type=int]
 └── le [type=bool]
      ├── plus [type=int]
      │    ├── variable: @1 [type=int]
      │    └── variable: @2 [type=int]
      └── plus [type=int]
           ├── variable: @3 [type=int]
           └── variable: @1 [type=int]

build-scalar vars=(int, int, int)
(@1 + @2) BETWEEN SYMMETRIC (@2 + @3) AND (@3 + @1)
----
or [type=bool]
 ├── and [type=bool]
 │    ├── ge [type=bool]
 │    │    ├── plus [type=int]
 │    │    │    ├── variable: @1 [type=int]
 │    │    │    └── variable: @2 [type=int]
 │    │    └── plus [type=int]
 │    │         ├── variable: @2 [type=int]
 │    │         └── variable: @3 [type=int]
 │    └── le [type=bool]
 │         ├── plus [type=int]
 │         │    ├── variable: @1 [type=int]
 │         │    └── variable: @2 [type=int]
 │         └── plus [type=int]
 │              ├── variable: @3 [type=int]
 │              └── variable: @1 [type=int]
 └── and [type=bool]
      ├── ge [type=bool]
      │    ├── plus [type=int]
      │    │    ├── variable: @1 [type=int]
      │    │    └── variable: @2 [type=int]
      │    └── plus [type=int]
      │         ├── variable: @3 [type=int]
      │         └── variable: @1 [type=int]
      └── le [type=bool]
           ├── plus [type=int]
           │    ├── variable: @1 [type=int]
           │    └── variable: @2 [type=int]
           └── plus [type=int]
                ├── variable: @2 [type=int]
                └── variable: @3 [type=int]

build-scalar vars=(int, int, int)
(@1, @2) BETWEEN (1, 2) AND (3, 4)
----
and [type=bool]
 ├── ge [type=bool]
 │    ├── tuple [type=tuple{int, int}]
 │    │    ├── variable: @1 [type=int]
 │    │    └── variable: @2 [type=int]
 │    └── tuple [type=tuple{int, int}]
 │         ├── const: 1 [type=int]
 │         └── const: 2 [type=int]
 └── le [type=bool]
      ├── tuple [type=tuple{int, int}]
      │    ├── variable: @1 [type=int]
      │    └── variable: @2 [type=int]
      └── tuple [type=tuple{int, int}]
           ├── const: 3 [type=int]
           └── const: 4 [type=int]

build-scalar vars=(int, int, int)
(@1, @2) NOT BETWEEN SYMMETRIC (1, 2) AND (3, 4)
----
not [type=bool]
 └── or [type=bool]
      ├── and [type=bool]
      │    ├── ge [type=bool]
      │    │    ├── tuple [type=tuple{int, int}]
      │    │    │    ├── variable: @1 [type=int]
      │    │    │    └── variable: @2 [type=int]
      │    │    └── tuple [type=tuple{int, int}]
      │    │         ├── const: 1 [type=int]
      │    │         └── const: 2 [type=int]
      │    └── le [type=bool]
      │         ├── tuple [type=tuple{int, int}]
      │         │    ├── variable: @1 [type=int]
      │         │    └── variable: @2 [type=int]
      │         └── tuple [type=tuple{int, int}]
      │              ├── const: 3 [type=int]
      │              └── const: 4 [type=int]
      └── and [type=bool]
           ├── ge [type=bool]
           │    ├── tuple [type=tuple{int, int}]
           │    │    ├── variable: @1 [type=int]
           │    │    └── variable: @2 [type=int]
           │    └── tuple [type=tuple{int, int}]
           │         ├── const: 3 [type=int]
           │         └── const: 4 [type=int]
           └── le [type=bool]
                ├── tuple [type=tuple{int, int}]
                │    ├── variable: @1 [type=int]
                │    └── variable: @2 [type=int]
                └── tuple [type=tuple{int, int}]
                     ├── const: 1 [type=int]
                     └── const: 2 [type=int]

build-scalar
NULL
----
null [type=unknown]

build-scalar
NULL::int
----
cast: INT [type=int]
 └── null [type=unknown]

build-scalar vars=(int[])
@1 = ARRAY[1, 2, 3]
----
eq [type=bool]
 ├── variable: @1 [type=int[]]
 └── array: [type=int[]]
      ├── const: 1 [type=int]
      ├── const: 2 [type=int]
      └── const: 3 [type=int]

build-scalar vars=(int[])
@1 = ARRAY[1, 1.0, '1']
----
eq [type=bool]
 ├── variable: @1 [type=int[]]
 └── array: [type=int[]]
      ├── const: 1 [type=int]
      ├── const: 1 [type=int]
      └── const: 1 [type=int]

build-scalar vars=(float[])
@1 = ARRAY[1, 1.1, '1.123']
----
eq [type=bool]
 ├── variable: @1 [type=float[]]
 └── array: [type=float[]]
      ├── const: 1.0 [type=float]
      ├── const: 1.1 [type=float]
      └── const: 1.123 [type=float]

build-scalar vars=(int[])
@1 = ARRAY[]
----
eq [type=bool]
 ├── variable: @1 [type=int[]]
 └── array: [type=int[]]

build-scalar vars=(string[])
@1 = ARRAY['foo', 'bar', 'baz']
----
eq [type=bool]
 ├── variable: @1 [type=string[]]
 └── array: [type=string[]]
      ├── const: 'foo' [type=string]
      ├── const: 'bar' [type=string]
      └── const: 'baz' [type=string]

build-scalar vars=(json)
@1->>'a' = 'b'
----
eq [type=bool]
 ├── fetch-text [type=string]
 │    ├── variable: @1 [type=jsonb]
 │    └── const: 'a' [type=string]
 └── const: 'b' [type=string]

build-scalar vars=(json)
@1->'a' = '"b"'
----
eq [type=bool]
 ├── fetch-val [type=jsonb]
 │    ├── variable: @1 [type=jsonb]
 │    └── const: 'a' [type=string]
 └── const: '"b"' [type=jsonb]

build-scalar vars=(json)
@1#>ARRAY['a'] = '"b"'
----
eq [type=bool]
 ├── fetch-val-path [type=jsonb]
 │    ├── variable: @1 [type=jsonb]
 │    └── array: [type=string[]]
 │         └── const: 'a' [type=string]
 └── const: '"b"' [type=jsonb]

build-scalar vars=(json)
@1#>>ARRAY['a'] = 'b'
----
eq [type=bool]
 ├── fetch-text-path [type=string]
 │    ├── variable: @1 [type=jsonb]
 │    └── array: [type=string[]]
 │         └── const: 'a' [type=string]
 └── const: 'b' [type=string]

build-scalar vars=(json, json)
@1 || @2
----
concat [type=jsonb]
 ├── variable: @1 [type=jsonb]
 └── variable: @2 [type=jsonb]

build-scalar allow-unsupported
'hello' COLLATE en
----
unsupported-expr: 'hello' COLLATE en [type=collatedstring{en}]

build-scalar
random()
----
function: random [type=float]

build-scalar
ARRAY[1, 2] || NULL
----
concat [type=int[]]
 ├── array: [type=int[]]
 │    ├── const: 1 [type=int]
 │    └── const: 2 [type=int]
 └── cast: INT[] [type=int[]]
      └── null [type=unknown]

build-scalar
NULL || ARRAY[1, 2]
----
concat [type=int[]]
 ├── cast: INT[] [type=int[]]
 │    └── null [type=unknown]
 └── array: [type=int[]]
      ├── const: 1 [type=int]
      └── const: 2 [type=int]

build-scalar
ARRAY[1, 2] || NULL::smallint
----
concat [type=int[]]
 ├── array: [type=int[]]
 │    ├── const: 1 [type=int]
 │    └── const: 2 [type=int]
 └── cast: INT2 [type=int]
      └── null [type=unknown]

build-scalar
NULL::oid || ARRAY[1, 2]
----
concat [type=oid[]]
 ├── cast: OID [type=oid]
 │    └── null [type=unknown]
 └── array: [type=oid[]]
      ├── const: 1 [type=oid]
      └── const: 2 [type=oid]

build-scalar
ARRAY['"foo"'::jsonb]
----
error: arrays of jsonb not allowed

build-scalar
ARRAY['"foo"'::json]
----
error: arrays of jsonb not allowed

opt
SELECT -((-9223372036854775808):::int)
----
project
 ├── columns: "?column?":1(int)
 ├── values
 │    └── tuple [type=tuple]
 └── projections
      └── unary-minus [type=int]
           └── const: -9223372036854775808 [type=int]

# TODO(justin): modify build-scalar to handle subqueries
# so this can use it.
build
SELECT ARRAY(SELECT 1)
----
project
 ├── columns: array:3(int[])
 ├── values
 │    └── tuple [type=tuple]
 └── projections
      └── coalesce [type=int[]]
           ├── subquery [type=int[]]
           │    └── scalar-group-by
           │         ├── columns: array_agg:2(int[])
           │         ├── project
           │         │    ├── columns: "?column?":1(int!null)
           │         │    ├── values
           │         │    │    └── tuple [type=tuple]
           │         │    └── projections
           │         │         └── const: 1 [type=int]
           │         └── aggregations
           │              └── array-agg [type=int[]]
           │                   └── variable: ?column? [type=int]
           └── array: [type=int[]]

exec-ddl
CREATE TABLE x (a INT PRIMARY KEY)
----
TABLE x
 ├── a int not null
 └── INDEX primary
      └── a int not null

exec-ddl
CREATE TABLE y (b INT PRIMARY KEY)
----
TABLE y
 ├── b int not null
 └── INDEX primary
      └── b int not null

build
SELECT b, ARRAY(SELECT a FROM x WHERE x.a = y.b) FROM y
----
project
 ├── columns: b:1(int!null) array:4(int[])
 ├── scan y
 │    └── columns: b:1(int!null)
 └── projections
      └── coalesce [type=int[]]
           ├── subquery [type=int[]]
           │    └── scalar-group-by
           │         ├── columns: array_agg:3(int[])
           │         ├── select
           │         │    ├── columns: a:2(int!null)
           │         │    ├── scan x
           │         │    │    └── columns: a:2(int!null)
           │         │    └── filters [type=bool]
           │         │         └── eq [type=bool]
           │         │              ├── variable: a [type=int]
           │         │              └── variable: b [type=int]
           │         └── aggregations
           │              └── array-agg [type=int[]]
           │                   └── variable: a [type=int]
           └── array: [type=int[]]

build
SELECT b, ARRAY(SELECT a FROM x ORDER BY a) FROM y
----
project
 ├── columns: b:1(int!null) array:4(int[])
 ├── scan y
 │    └── columns: b:1(int!null)
 └── projections
      └── coalesce [type=int[]]
           ├── subquery [type=int[]]
           │    └── scalar-group-by
           │         ├── columns: array_agg:3(int[])
           │         ├── internal-ordering: +2
           │         ├── scan x
           │         │    ├── columns: a:2(int!null)
           │         │    └── ordering: +2
           │         └── aggregations
           │              └── array-agg [type=int[]]
           │                   └── variable: a [type=int]
           └── array: [type=int[]]

build
SELECT ARRAY(VALUES ('foo'), ('bar'), ('baz'))
----
project
 ├── columns: array:3(string[])
 ├── values
 │    └── tuple [type=tuple]
 └── projections
      └── coalesce [type=string[]]
           ├── subquery [type=string[]]
           │    └── scalar-group-by
           │         ├── columns: array_agg:2(string[])
           │         ├── values
           │         │    ├── columns: column1:1(string)
           │         │    ├── tuple [type=tuple{string}]
           │         │    │    └── const: 'foo' [type=string]
           │         │    ├── tuple [type=tuple{string}]
           │         │    │    └── const: 'bar' [type=string]
           │         │    └── tuple [type=tuple{string}]
           │         │         └── const: 'baz' [type=string]
           │         └── aggregations
           │              └── array-agg [type=string[]]
           │                   └── variable: column1 [type=string]
           └── array: [type=string[]]

build
SELECT ARRAY(VALUES (ARRAY[1]))
----
error (0A000): can't build ARRAY(int[])

build
SELECT ARRAY(SELECT (1, 2))
----
error (0A000): can't build ARRAY(tuple{int, int})

build
SELECT ARRAY(VALUES ((1, 2)))
----
error (0A000): can't build ARRAY(tuple{int, int})

build
SELECT ARRAY(VALUES ('{}'::JSONB))
----
error (0A000): arrays of jsonb not allowed

build
SELECT ARRAY(SELECT 1, 2)
----
error (42601): subquery must return only one column, found 2

build
SELECT ARRAY(SELECT generate_series(1,100) ORDER BY 1 DESC)
----
project
 ├── columns: array:3(int[])
 ├── values
 │    └── tuple [type=tuple]
 └── projections
      └── coalesce [type=int[]]
           ├── subquery [type=int[]]
           │    └── scalar-group-by
           │         ├── columns: array_agg:2(int[])
           │         ├── internal-ordering: -1
           │         ├── sort
           │         │    ├── columns: generate_series:1(int)
           │         │    ├── ordering: -1
           │         │    └── inner-join-apply
           │         │         ├── columns: generate_series:1(int)
           │         │         ├── values
           │         │         │    └── tuple [type=tuple]
           │         │         ├── zip
           │         │         │    ├── columns: generate_series:1(int)
           │         │         │    └── function: generate_series [type=int]
           │         │         │         ├── const: 1 [type=int]
           │         │         │         └── const: 100 [type=int]
           │         │         └── true [type=bool]
           │         └── aggregations
           │              └── array-agg [type=int[]]
           │                   └── variable: generate_series [type=int]
           └── array: [type=int[]]

build-scalar
1 = ANY ARRAY[1, 2, 3]
----
any-scalar: eq [type=bool]
 ├── const: 1 [type=int]
 └── array: [type=int[]]
      ├── const: 1 [type=int]
      ├── const: 2 [type=int]
      └── const: 3 [type=int]

build-scalar
1 > ANY ARRAY[1, 2, 3]
----
any-scalar: gt [type=bool]
 ├── const: 1 [type=int]
 └── array: [type=int[]]
      ├── const: 1 [type=int]
      ├── const: 2 [type=int]
      └── const: 3 [type=int]

build-scalar
1 = ALL ARRAY[1, 2, 3]
----
not [type=bool]
 └── any-scalar: ne [type=bool]
      ├── const: 1 [type=int]
      └── array: [type=int[]]
           ├── const: 1 [type=int]
           ├── const: 2 [type=int]
           └── const: 3 [type=int]

build-scalar
1 > ALL ARRAY[1, 2, 3]
----
not [type=bool]
 └── any-scalar: le [type=bool]
      ├── const: 1 [type=int]
      └── array: [type=int[]]
           ├── const: 1 [type=int]
           ├── const: 2 [type=int]
           └── const: 3 [type=int]

build-scalar
1 = ANY (1, 2, 3)
----
any-scalar: eq [type=bool]
 ├── const: 1 [type=int]
 └── tuple [type=tuple{int, int, int}]
      ├── const: 1 [type=int]
      ├── const: 2 [type=int]
      └── const: 3 [type=int]

build-scalar
'foo' = ANY ('foo', 'bar', 'baz')
----
any-scalar: eq [type=bool]
 ├── const: 'foo' [type=string]
 └── tuple [type=tuple{string, string, string}]
      ├── const: 'foo' [type=string]
      ├── const: 'bar' [type=string]
      └── const: 'baz' [type=string]


build-scalar
1 = ANY ()
----
any-scalar: eq [type=bool]
 ├── const: 1 [type=int]
 └── tuple [type=tuple{}]

build
SELECT 1 > ALL ARRAY['foo']
----
error (22023): unsupported comparison operator: 1 > ALL ARRAY['foo']: could not parse "foo" as type int: strconv.ParseInt: parsing "foo": invalid syntax
