# tests adapted from logictest -- union

build
VALUES (1), (1), (1), (2), (2) UNION VALUES (1), (3), (1)
----
union
 ├── columns: column1:3(int)
 ├── left columns: column1:1(int)
 ├── right columns: column1:2(int)
 ├── values
 │    ├── columns: column1:1(int)
 │    ├── tuple [type=tuple{int}]
 │    │    └── const: 1 [type=int]
 │    ├── tuple [type=tuple{int}]
 │    │    └── const: 1 [type=int]
 │    ├── tuple [type=tuple{int}]
 │    │    └── const: 1 [type=int]
 │    ├── tuple [type=tuple{int}]
 │    │    └── const: 2 [type=int]
 │    └── tuple [type=tuple{int}]
 │         └── const: 2 [type=int]
 └── values
      ├── columns: column1:2(int)
      ├── tuple [type=tuple{int}]
      │    └── const: 1 [type=int]
      ├── tuple [type=tuple{int}]
      │    └── const: 3 [type=int]
      └── tuple [type=tuple{int}]
           └── const: 1 [type=int]

build
VALUES (1), (1), (1), (2), (2) UNION ALL VALUES (1), (3), (1)
----
union-all
 ├── columns: column1:3(int)
 ├── left columns: column1:1(int)
 ├── right columns: column1:2(int)
 ├── values
 │    ├── columns: column1:1(int)
 │    ├── tuple [type=tuple{int}]
 │    │    └── const: 1 [type=int]
 │    ├── tuple [type=tuple{int}]
 │    │    └── const: 1 [type=int]
 │    ├── tuple [type=tuple{int}]
 │    │    └── const: 1 [type=int]
 │    ├── tuple [type=tuple{int}]
 │    │    └── const: 2 [type=int]
 │    └── tuple [type=tuple{int}]
 │         └── const: 2 [type=int]
 └── values
      ├── columns: column1:2(int)
      ├── tuple [type=tuple{int}]
      │    └── const: 1 [type=int]
      ├── tuple [type=tuple{int}]
      │    └── const: 3 [type=int]
      └── tuple [type=tuple{int}]
           └── const: 1 [type=int]

build
VALUES (1), (1), (1), (2), (2) INTERSECT VALUES (1), (3), (1)
----
intersect
 ├── columns: column1:1(int)
 ├── left columns: column1:1(int)
 ├── right columns: column1:2(int)
 ├── values
 │    ├── columns: column1:1(int)
 │    ├── tuple [type=tuple{int}]
 │    │    └── const: 1 [type=int]
 │    ├── tuple [type=tuple{int}]
 │    │    └── const: 1 [type=int]
 │    ├── tuple [type=tuple{int}]
 │    │    └── const: 1 [type=int]
 │    ├── tuple [type=tuple{int}]
 │    │    └── const: 2 [type=int]
 │    └── tuple [type=tuple{int}]
 │         └── const: 2 [type=int]
 └── values
      ├── columns: column1:2(int)
      ├── tuple [type=tuple{int}]
      │    └── const: 1 [type=int]
      ├── tuple [type=tuple{int}]
      │    └── const: 3 [type=int]
      └── tuple [type=tuple{int}]
           └── const: 1 [type=int]

build
VALUES (1), (1), (1), (2), (2) INTERSECT ALL VALUES (1), (3), (1)
----
intersect-all
 ├── columns: column1:1(int)
 ├── left columns: column1:1(int)
 ├── right columns: column1:2(int)
 ├── values
 │    ├── columns: column1:1(int)
 │    ├── tuple [type=tuple{int}]
 │    │    └── const: 1 [type=int]
 │    ├── tuple [type=tuple{int}]
 │    │    └── const: 1 [type=int]
 │    ├── tuple [type=tuple{int}]
 │    │    └── const: 1 [type=int]
 │    ├── tuple [type=tuple{int}]
 │    │    └── const: 2 [type=int]
 │    └── tuple [type=tuple{int}]
 │         └── const: 2 [type=int]
 └── values
      ├── columns: column1:2(int)
      ├── tuple [type=tuple{int}]
      │    └── const: 1 [type=int]
      ├── tuple [type=tuple{int}]
      │    └── const: 3 [type=int]
      └── tuple [type=tuple{int}]
           └── const: 1 [type=int]

build
VALUES (1), (1), (1), (2), (2) EXCEPT VALUES (1), (3), (1)
----
except
 ├── columns: column1:1(int)
 ├── left columns: column1:1(int)
 ├── right columns: column1:2(int)
 ├── values
 │    ├── columns: column1:1(int)
 │    ├── tuple [type=tuple{int}]
 │    │    └── const: 1 [type=int]
 │    ├── tuple [type=tuple{int}]
 │    │    └── const: 1 [type=int]
 │    ├── tuple [type=tuple{int}]
 │    │    └── const: 1 [type=int]
 │    ├── tuple [type=tuple{int}]
 │    │    └── const: 2 [type=int]
 │    └── tuple [type=tuple{int}]
 │         └── const: 2 [type=int]
 └── values
      ├── columns: column1:2(int)
      ├── tuple [type=tuple{int}]
      │    └── const: 1 [type=int]
      ├── tuple [type=tuple{int}]
      │    └── const: 3 [type=int]
      └── tuple [type=tuple{int}]
           └── const: 1 [type=int]

build
VALUES (1), (1), (1), (2), (2) EXCEPT ALL VALUES (1), (3), (1)
----
except-all
 ├── columns: column1:1(int)
 ├── left columns: column1:1(int)
 ├── right columns: column1:2(int)
 ├── values
 │    ├── columns: column1:1(int)
 │    ├── tuple [type=tuple{int}]
 │    │    └── const: 1 [type=int]
 │    ├── tuple [type=tuple{int}]
 │    │    └── const: 1 [type=int]
 │    ├── tuple [type=tuple{int}]
 │    │    └── const: 1 [type=int]
 │    ├── tuple [type=tuple{int}]
 │    │    └── const: 2 [type=int]
 │    └── tuple [type=tuple{int}]
 │         └── const: 2 [type=int]
 └── values
      ├── columns: column1:2(int)
      ├── tuple [type=tuple{int}]
      │    └── const: 1 [type=int]
      ├── tuple [type=tuple{int}]
      │    └── const: 3 [type=int]
      └── tuple [type=tuple{int}]
           └── const: 1 [type=int]

build
VALUES (1, 2), (1, 1), (1, 2), (2, 1), (2, 1) UNION VALUES (1, 3), (3, 4), (1, 1)
----
union
 ├── columns: column1:5(int) column2:6(int)
 ├── left columns: column1:1(int) column2:2(int)
 ├── right columns: column1:3(int) column2:4(int)
 ├── values
 │    ├── columns: column1:1(int) column2:2(int)
 │    ├── tuple [type=tuple{int, int}]
 │    │    ├── const: 1 [type=int]
 │    │    └── const: 2 [type=int]
 │    ├── tuple [type=tuple{int, int}]
 │    │    ├── const: 1 [type=int]
 │    │    └── const: 1 [type=int]
 │    ├── tuple [type=tuple{int, int}]
 │    │    ├── const: 1 [type=int]
 │    │    └── const: 2 [type=int]
 │    ├── tuple [type=tuple{int, int}]
 │    │    ├── const: 2 [type=int]
 │    │    └── const: 1 [type=int]
 │    └── tuple [type=tuple{int, int}]
 │         ├── const: 2 [type=int]
 │         └── const: 1 [type=int]
 └── values
      ├── columns: column1:3(int) column2:4(int)
      ├── tuple [type=tuple{int, int}]
      │    ├── const: 1 [type=int]
      │    └── const: 3 [type=int]
      ├── tuple [type=tuple{int, int}]
      │    ├── const: 3 [type=int]
      │    └── const: 4 [type=int]
      └── tuple [type=tuple{int, int}]
           ├── const: 1 [type=int]
           └── const: 1 [type=int]

build
(VALUES (1), (1), (1), (2), (2) UNION ALL VALUES (1), (3), (1)) ORDER BY 1 DESC LIMIT 2
----
limit
 ├── columns: column1:3(int)
 ├── internal-ordering: -3
 ├── ordering: -3
 ├── sort
 │    ├── columns: column1:3(int)
 │    ├── ordering: -3
 │    └── union-all
 │         ├── columns: column1:3(int)
 │         ├── left columns: column1:1(int)
 │         ├── right columns: column1:2(int)
 │         ├── values
 │         │    ├── columns: column1:1(int)
 │         │    ├── tuple [type=tuple{int}]
 │         │    │    └── const: 1 [type=int]
 │         │    ├── tuple [type=tuple{int}]
 │         │    │    └── const: 1 [type=int]
 │         │    ├── tuple [type=tuple{int}]
 │         │    │    └── const: 1 [type=int]
 │         │    ├── tuple [type=tuple{int}]
 │         │    │    └── const: 2 [type=int]
 │         │    └── tuple [type=tuple{int}]
 │         │         └── const: 2 [type=int]
 │         └── values
 │              ├── columns: column1:2(int)
 │              ├── tuple [type=tuple{int}]
 │              │    └── const: 1 [type=int]
 │              ├── tuple [type=tuple{int}]
 │              │    └── const: 3 [type=int]
 │              └── tuple [type=tuple{int}]
 │                   └── const: 1 [type=int]
 └── const: 2 [type=int]

# The ORDER BY and LIMIT apply to the UNION, not the last VALUES.
build
VALUES (1), (1), (1), (2), (2) UNION ALL VALUES (1), (3), (1) ORDER BY 1 DESC LIMIT 2
----
limit
 ├── columns: column1:3(int)
 ├── internal-ordering: -3
 ├── ordering: -3
 ├── sort
 │    ├── columns: column1:3(int)
 │    ├── ordering: -3
 │    └── union-all
 │         ├── columns: column1:3(int)
 │         ├── left columns: column1:1(int)
 │         ├── right columns: column1:2(int)
 │         ├── values
 │         │    ├── columns: column1:1(int)
 │         │    ├── tuple [type=tuple{int}]
 │         │    │    └── const: 1 [type=int]
 │         │    ├── tuple [type=tuple{int}]
 │         │    │    └── const: 1 [type=int]
 │         │    ├── tuple [type=tuple{int}]
 │         │    │    └── const: 1 [type=int]
 │         │    ├── tuple [type=tuple{int}]
 │         │    │    └── const: 2 [type=int]
 │         │    └── tuple [type=tuple{int}]
 │         │         └── const: 2 [type=int]
 │         └── values
 │              ├── columns: column1:2(int)
 │              ├── tuple [type=tuple{int}]
 │              │    └── const: 1 [type=int]
 │              ├── tuple [type=tuple{int}]
 │              │    └── const: 3 [type=int]
 │              └── tuple [type=tuple{int}]
 │                   └── const: 1 [type=int]
 └── const: 2 [type=int]

# UNION with NULL columns in operands works.
build
VALUES (NULL) UNION ALL VALUES (1) ORDER BY 1
----
sort
 ├── columns: column1:3(int)
 ├── ordering: +3
 └── union-all
      ├── columns: column1:3(int)
      ├── left columns: column1:4(int)
      ├── right columns: column1:2(int)
      ├── project
      │    ├── columns: column1:4(int)
      │    ├── values
      │    │    ├── columns: column1:1(unknown)
      │    │    └── tuple [type=tuple{unknown}]
      │    │         └── null [type=unknown]
      │    └── projections
      │         └── cast: INT8 [type=int]
      │              └── variable: column1 [type=unknown]
      └── values
           ├── columns: column1:2(int)
           └── tuple [type=tuple{int}]
                └── const: 1 [type=int]

build
VALUES (NULL) UNION ALL VALUES (NULL)
----
union-all
 ├── columns: column1:3(unknown)
 ├── left columns: column1:1(unknown)
 ├── right columns: column1:2(unknown)
 ├── values
 │    ├── columns: column1:1(unknown)
 │    └── tuple [type=tuple{unknown}]
 │         └── null [type=unknown]
 └── values
      ├── columns: column1:2(unknown)
      └── tuple [type=tuple{unknown}]
           └── null [type=unknown]

build
SELECT x, pg_typeof(y) FROM (SELECT 1 AS a, NULL AS b UNION ALL SELECT 2 AS a, 4 AS b) AS t(x, y)
----
project
 ├── columns: x:5(int!null) pg_typeof:8(string)
 ├── union-all
 │    ├── columns: a:5(int!null) b:6(int)
 │    ├── left columns: a:1(int) b:7(int)
 │    ├── right columns: a:3(int) b:4(int)
 │    ├── project
 │    │    ├── columns: b:7(int) a:1(int!null)
 │    │    ├── project
 │    │    │    ├── columns: a:1(int!null) b:2(unknown)
 │    │    │    ├── values
 │    │    │    │    └── tuple [type=tuple]
 │    │    │    └── projections
 │    │    │         ├── const: 1 [type=int]
 │    │    │         └── null [type=unknown]
 │    │    └── projections
 │    │         └── cast: INT8 [type=int]
 │    │              └── variable: b [type=unknown]
 │    └── project
 │         ├── columns: a:3(int!null) b:4(int!null)
 │         ├── values
 │         │    └── tuple [type=tuple]
 │         └── projections
 │              ├── const: 2 [type=int]
 │              └── const: 4 [type=int]
 └── projections
      └── function: pg_typeof [type=string]
           └── variable: b [type=int]

build
SELECT x, pg_typeof(y) FROM (SELECT 1 AS a, 3 AS b UNION ALL SELECT 2 AS a, NULL AS b) AS t(x, y)
----
project
 ├── columns: x:5(int!null) pg_typeof:8(string)
 ├── union-all
 │    ├── columns: a:5(int!null) b:6(int)
 │    ├── left columns: a:1(int) b:2(int)
 │    ├── right columns: a:3(int) b:7(int)
 │    ├── project
 │    │    ├── columns: a:1(int!null) b:2(int!null)
 │    │    ├── values
 │    │    │    └── tuple [type=tuple]
 │    │    └── projections
 │    │         ├── const: 1 [type=int]
 │    │         └── const: 3 [type=int]
 │    └── project
 │         ├── columns: b:7(int) a:3(int!null)
 │         ├── project
 │         │    ├── columns: a:3(int!null) b:4(unknown)
 │         │    ├── values
 │         │    │    └── tuple [type=tuple]
 │         │    └── projections
 │         │         ├── const: 2 [type=int]
 │         │         └── null [type=unknown]
 │         └── projections
 │              └── cast: INT8 [type=int]
 │                   └── variable: b [type=unknown]
 └── projections
      └── function: pg_typeof [type=string]
           └── variable: b [type=int]

exec-ddl
CREATE TABLE uniontest (
  k INT,
  v INT
)
----
TABLE uniontest
 ├── k int
 ├── v int
 ├── rowid int not null (hidden)
 └── INDEX primary
      └── rowid int not null (hidden)

build
SELECT v FROM uniontest WHERE k = 1 UNION SELECT v FROM uniontest WHERE k = 2
----
union
 ├── columns: v:7(int)
 ├── left columns: uniontest.v:2(int)
 ├── right columns: uniontest.v:5(int)
 ├── project
 │    ├── columns: uniontest.v:2(int)
 │    └── select
 │         ├── columns: k:1(int!null) uniontest.v:2(int) rowid:3(int!null)
 │         ├── scan uniontest
 │         │    └── columns: k:1(int) uniontest.v:2(int) rowid:3(int!null)
 │         └── filters
 │              └── eq [type=bool]
 │                   ├── variable: k [type=int]
 │                   └── const: 1 [type=int]
 └── project
      ├── columns: uniontest.v:5(int)
      └── select
           ├── columns: k:4(int!null) uniontest.v:5(int) rowid:6(int!null)
           ├── scan uniontest
           │    └── columns: k:4(int) uniontest.v:5(int) rowid:6(int!null)
           └── filters
                └── eq [type=bool]
                     ├── variable: k [type=int]
                     └── const: 2 [type=int]

build
SELECT v FROM uniontest WHERE k = 1 UNION ALL SELECT v FROM uniontest WHERE k = 2
----
union-all
 ├── columns: v:7(int)
 ├── left columns: uniontest.v:2(int)
 ├── right columns: uniontest.v:5(int)
 ├── project
 │    ├── columns: uniontest.v:2(int)
 │    └── select
 │         ├── columns: k:1(int!null) uniontest.v:2(int) rowid:3(int!null)
 │         ├── scan uniontest
 │         │    └── columns: k:1(int) uniontest.v:2(int) rowid:3(int!null)
 │         └── filters
 │              └── eq [type=bool]
 │                   ├── variable: k [type=int]
 │                   └── const: 1 [type=int]
 └── project
      ├── columns: uniontest.v:5(int)
      └── select
           ├── columns: k:4(int!null) uniontest.v:5(int) rowid:6(int!null)
           ├── scan uniontest
           │    └── columns: k:4(int) uniontest.v:5(int) rowid:6(int!null)
           └── filters
                └── eq [type=bool]
                     ├── variable: k [type=int]
                     └── const: 2 [type=int]

build
SELECT v FROM uniontest WHERE k = 1 INTERSECT SELECT v FROM uniontest WHERE k = 2
----
intersect
 ├── columns: v:2(int)
 ├── left columns: v:2(int)
 ├── right columns: v:5(int)
 ├── project
 │    ├── columns: v:2(int)
 │    └── select
 │         ├── columns: k:1(int!null) v:2(int) rowid:3(int!null)
 │         ├── scan uniontest
 │         │    └── columns: k:1(int) v:2(int) rowid:3(int!null)
 │         └── filters
 │              └── eq [type=bool]
 │                   ├── variable: k [type=int]
 │                   └── const: 1 [type=int]
 └── project
      ├── columns: v:5(int)
      └── select
           ├── columns: k:4(int!null) v:5(int) rowid:6(int!null)
           ├── scan uniontest
           │    └── columns: k:4(int) v:5(int) rowid:6(int!null)
           └── filters
                └── eq [type=bool]
                     ├── variable: k [type=int]
                     └── const: 2 [type=int]

build
SELECT v FROM uniontest WHERE k = 1 INTERSECT ALL SELECT v FROM uniontest WHERE k = 2
----
intersect-all
 ├── columns: v:2(int)
 ├── left columns: v:2(int)
 ├── right columns: v:5(int)
 ├── project
 │    ├── columns: v:2(int)
 │    └── select
 │         ├── columns: k:1(int!null) v:2(int) rowid:3(int!null)
 │         ├── scan uniontest
 │         │    └── columns: k:1(int) v:2(int) rowid:3(int!null)
 │         └── filters
 │              └── eq [type=bool]
 │                   ├── variable: k [type=int]
 │                   └── const: 1 [type=int]
 └── project
      ├── columns: v:5(int)
      └── select
           ├── columns: k:4(int!null) v:5(int) rowid:6(int!null)
           ├── scan uniontest
           │    └── columns: k:4(int) v:5(int) rowid:6(int!null)
           └── filters
                └── eq [type=bool]
                     ├── variable: k [type=int]
                     └── const: 2 [type=int]

build
SELECT v FROM uniontest WHERE k = 1 EXCEPT SELECT v FROM uniontest WHERE k = 2
----
except
 ├── columns: v:2(int)
 ├── left columns: v:2(int)
 ├── right columns: v:5(int)
 ├── project
 │    ├── columns: v:2(int)
 │    └── select
 │         ├── columns: k:1(int!null) v:2(int) rowid:3(int!null)
 │         ├── scan uniontest
 │         │    └── columns: k:1(int) v:2(int) rowid:3(int!null)
 │         └── filters
 │              └── eq [type=bool]
 │                   ├── variable: k [type=int]
 │                   └── const: 1 [type=int]
 └── project
      ├── columns: v:5(int)
      └── select
           ├── columns: k:4(int!null) v:5(int) rowid:6(int!null)
           ├── scan uniontest
           │    └── columns: k:4(int) v:5(int) rowid:6(int!null)
           └── filters
                └── eq [type=bool]
                     ├── variable: k [type=int]
                     └── const: 2 [type=int]

build
SELECT v FROM uniontest WHERE k = 1 EXCEPT ALL SELECT v FROM uniontest WHERE k = 2
----
except-all
 ├── columns: v:2(int)
 ├── left columns: v:2(int)
 ├── right columns: v:5(int)
 ├── project
 │    ├── columns: v:2(int)
 │    └── select
 │         ├── columns: k:1(int!null) v:2(int) rowid:3(int!null)
 │         ├── scan uniontest
 │         │    └── columns: k:1(int) v:2(int) rowid:3(int!null)
 │         └── filters
 │              └── eq [type=bool]
 │                   ├── variable: k [type=int]
 │                   └── const: 1 [type=int]
 └── project
      ├── columns: v:5(int)
      └── select
           ├── columns: k:4(int!null) v:5(int) rowid:6(int!null)
           ├── scan uniontest
           │    └── columns: k:4(int) v:5(int) rowid:6(int!null)
           └── filters
                └── eq [type=bool]
                     ├── variable: k [type=int]
                     └── const: 2 [type=int]

build
(SELECT v FROM uniontest WHERE k = 1 UNION ALL SELECT v FROM uniontest WHERE k = 2) ORDER BY 1 DESC LIMIT 2
----
limit
 ├── columns: v:7(int)
 ├── internal-ordering: -7
 ├── ordering: -7
 ├── sort
 │    ├── columns: v:7(int)
 │    ├── ordering: -7
 │    └── union-all
 │         ├── columns: v:7(int)
 │         ├── left columns: uniontest.v:2(int)
 │         ├── right columns: uniontest.v:5(int)
 │         ├── project
 │         │    ├── columns: uniontest.v:2(int)
 │         │    └── select
 │         │         ├── columns: k:1(int!null) uniontest.v:2(int) rowid:3(int!null)
 │         │         ├── scan uniontest
 │         │         │    └── columns: k:1(int) uniontest.v:2(int) rowid:3(int!null)
 │         │         └── filters
 │         │              └── eq [type=bool]
 │         │                   ├── variable: k [type=int]
 │         │                   └── const: 1 [type=int]
 │         └── project
 │              ├── columns: uniontest.v:5(int)
 │              └── select
 │                   ├── columns: k:4(int!null) uniontest.v:5(int) rowid:6(int!null)
 │                   ├── scan uniontest
 │                   │    └── columns: k:4(int) uniontest.v:5(int) rowid:6(int!null)
 │                   └── filters
 │                        └── eq [type=bool]
 │                             ├── variable: k [type=int]
 │                             └── const: 2 [type=int]
 └── const: 2 [type=int]

# The ORDER BY and LIMIT apply to the UNION, not the last SELECT.
build
SELECT v FROM uniontest WHERE k = 1 UNION ALL SELECT v FROM uniontest WHERE k = 2 ORDER BY 1 DESC LIMIT 2
----
limit
 ├── columns: v:7(int)
 ├── internal-ordering: -7
 ├── ordering: -7
 ├── sort
 │    ├── columns: v:7(int)
 │    ├── ordering: -7
 │    └── union-all
 │         ├── columns: v:7(int)
 │         ├── left columns: uniontest.v:2(int)
 │         ├── right columns: uniontest.v:5(int)
 │         ├── project
 │         │    ├── columns: uniontest.v:2(int)
 │         │    └── select
 │         │         ├── columns: k:1(int!null) uniontest.v:2(int) rowid:3(int!null)
 │         │         ├── scan uniontest
 │         │         │    └── columns: k:1(int) uniontest.v:2(int) rowid:3(int!null)
 │         │         └── filters
 │         │              └── eq [type=bool]
 │         │                   ├── variable: k [type=int]
 │         │                   └── const: 1 [type=int]
 │         └── project
 │              ├── columns: uniontest.v:5(int)
 │              └── select
 │                   ├── columns: k:4(int!null) uniontest.v:5(int) rowid:6(int!null)
 │                   ├── scan uniontest
 │                   │    └── columns: k:4(int) uniontest.v:5(int) rowid:6(int!null)
 │                   └── filters
 │                        └── eq [type=bool]
 │                             ├── variable: k [type=int]
 │                             └── const: 2 [type=int]
 └── const: 2 [type=int]

build
SELECT v FROM uniontest UNION SELECT k FROM uniontest
----
union
 ├── columns: v:7(int)
 ├── left columns: uniontest.v:2(int)
 ├── right columns: k:4(int)
 ├── project
 │    ├── columns: uniontest.v:2(int)
 │    └── scan uniontest
 │         └── columns: k:1(int) uniontest.v:2(int) rowid:3(int!null)
 └── project
      ├── columns: k:4(int)
      └── scan uniontest
           └── columns: k:4(int) uniontest.v:5(int) rowid:6(int!null)

build
SELECT v FROM uniontest UNION ALL SELECT k FROM uniontest
----
union-all
 ├── columns: v:7(int)
 ├── left columns: uniontest.v:2(int)
 ├── right columns: k:4(int)
 ├── project
 │    ├── columns: uniontest.v:2(int)
 │    └── scan uniontest
 │         └── columns: k:1(int) uniontest.v:2(int) rowid:3(int!null)
 └── project
      ├── columns: k:4(int)
      └── scan uniontest
           └── columns: k:4(int) uniontest.v:5(int) rowid:6(int!null)

build
SELECT * FROM (SELECT * FROM (VALUES (1)) a LEFT JOIN (VALUES (1) UNION VALUES (2)) b on a.column1 = b.column1);
----
left-join
 ├── columns: column1:1(int) column1:4(int)
 ├── values
 │    ├── columns: column1:1(int)
 │    └── tuple [type=tuple{int}]
 │         └── const: 1 [type=int]
 ├── union
 │    ├── columns: column1:4(int)
 │    ├── left columns: column1:2(int)
 │    ├── right columns: column1:3(int)
 │    ├── values
 │    │    ├── columns: column1:2(int)
 │    │    └── tuple [type=tuple{int}]
 │    │         └── const: 1 [type=int]
 │    └── values
 │         ├── columns: column1:3(int)
 │         └── tuple [type=tuple{int}]
 │              └── const: 2 [type=int]
 └── filters
      └── eq [type=bool]
           ├── variable: column1 [type=int]
           └── variable: column1 [type=int]

build
SELECT * FROM (VALUES (1)) a LEFT JOIN (VALUES (1) UNION VALUES (2)) b on a.column1 = b.column1;
----
left-join
 ├── columns: column1:1(int) column1:4(int)
 ├── values
 │    ├── columns: column1:1(int)
 │    └── tuple [type=tuple{int}]
 │         └── const: 1 [type=int]
 ├── union
 │    ├── columns: column1:4(int)
 │    ├── left columns: column1:2(int)
 │    ├── right columns: column1:3(int)
 │    ├── values
 │    │    ├── columns: column1:2(int)
 │    │    └── tuple [type=tuple{int}]
 │    │         └── const: 1 [type=int]
 │    └── values
 │         ├── columns: column1:3(int)
 │         └── tuple [type=tuple{int}]
 │              └── const: 2 [type=int]
 └── filters
      └── eq [type=bool]
           ├── variable: column1 [type=int]
           └── variable: column1 [type=int]

build
SELECT 1, 2 UNION SELECT 3
----
error (42601): each UNION query must have the same number of columns: 2 vs 1

build
SELECT 1, 2 INTERSECT SELECT 3
----
error (42601): each INTERSECT query must have the same number of columns: 2 vs 1

build
SELECT 1, 2 EXCEPT SELECT 3
----
error (42601): each EXCEPT query must have the same number of columns: 2 vs 1

build
SELECT 1 UNION SELECT '3'
----
error (42804): UNION types int and string cannot be matched

build
SELECT 1 INTERSECT SELECT '3'
----
error (42804): INTERSECT types int and string cannot be matched

build
SELECT 1 EXCEPT SELECT '3'
----
error (42804): EXCEPT types int and string cannot be matched

build
SELECT 1 UNION SELECT 3 ORDER BY z
----
error (42703): column "z" does not exist

build
SELECT ARRAY[1] UNION ALL SELECT ARRAY['foo']
----
error (42804): UNION types int[] and string[] cannot be matched

exec-ddl
CREATE TABLE t.xy (x STRING NOT NULL, y STRING NOT NULL)
----
TABLE xy
 ├── x string not null
 ├── y string not null
 ├── rowid int not null (hidden)
 └── INDEX primary
      └── rowid int not null (hidden)

exec-ddl
CREATE TABLE t.abc (
  a string,
  b string NOT NULL,
  c string NOT NULL
)
----
TABLE abc
 ├── a string
 ├── b string not null
 ├── c string not null
 ├── rowid int not null (hidden)
 └── INDEX primary
      └── rowid int not null (hidden)

build
(SELECT x, x, y FROM xy) UNION (SELECT a, b, c FROM abc)
----
union
 ├── columns: x:8(string) x:9(string!null) y:10(string!null)
 ├── left columns: xy.x:1(string) xy.x:1(string) xy.y:2(string)
 ├── right columns: a:4(string) b:5(string) c:6(string)
 ├── project
 │    ├── columns: xy.x:1(string!null) xy.y:2(string!null)
 │    └── scan xy
 │         └── columns: xy.x:1(string!null) xy.y:2(string!null) xy.rowid:3(int!null)
 └── project
      ├── columns: a:4(string) b:5(string!null) c:6(string!null)
      └── scan abc
           └── columns: a:4(string) b:5(string!null) c:6(string!null) abc.rowid:7(int!null)

build
(SELECT a FROM abc ORDER BY b) UNION ALL (SELECT b FROM abc) ORDER BY a
----
sort
 ├── columns: a:9(string)
 ├── ordering: +9
 └── union-all
      ├── columns: a:9(string)
      ├── left columns: abc.a:1(string)
      ├── right columns: b:6(string)
      ├── project
      │    ├── columns: abc.a:1(string) b:2(string!null)
      │    └── scan abc
      │         └── columns: abc.a:1(string) b:2(string!null) c:3(string!null) rowid:4(int!null)
      └── project
           ├── columns: b:6(string!null)
           └── scan abc
                └── columns: abc.a:5(string) b:6(string!null) c:7(string!null) rowid:8(int!null)

build
(SELECT a FROM abc ORDER BY b) UNION ALL (SELECT a FROM abc ORDER BY c) ORDER BY a
----
sort
 ├── columns: a:9(string)
 ├── ordering: +9
 └── union-all
      ├── columns: a:9(string)
      ├── left columns: abc.a:1(string)
      ├── right columns: abc.a:5(string)
      ├── project
      │    ├── columns: abc.a:1(string) b:2(string!null)
      │    └── scan abc
      │         └── columns: abc.a:1(string) b:2(string!null) c:3(string!null) rowid:4(int!null)
      └── project
           ├── columns: abc.a:5(string) c:7(string!null)
           └── scan abc
                └── columns: abc.a:5(string) b:6(string!null) c:7(string!null) rowid:8(int!null)

build
(SELECT a FROM abc ORDER BY b) EXCEPT (SELECT b FROM abc ORDER BY c, b, a)
----
except
 ├── columns: a:1(string)
 ├── left columns: a:1(string)
 ├── right columns: b:6(string)
 ├── project
 │    ├── columns: a:1(string) b:2(string!null)
 │    └── scan abc
 │         └── columns: a:1(string) b:2(string!null) c:3(string!null) rowid:4(int!null)
 └── project
      ├── columns: a:5(string) b:6(string!null) c:7(string!null)
      └── scan abc
           └── columns: a:5(string) b:6(string!null) c:7(string!null) rowid:8(int!null)

# Tests for type propagation.

build
VALUES (NULL, NULL), (NULL, 'x') UNION VALUES (1, 'a'), (2, 'b')
----
union
 ├── columns: column1:5(int) column2:6(string)
 ├── left columns: column1:7(int) column2:2(string)
 ├── right columns: column1:3(int) column2:4(string)
 ├── project
 │    ├── columns: column1:7(int) column2:2(string)
 │    ├── values
 │    │    ├── columns: column1:1(unknown) column2:2(string)
 │    │    ├── tuple [type=tuple{unknown, string}]
 │    │    │    ├── null [type=unknown]
 │    │    │    └── null [type=unknown]
 │    │    └── tuple [type=tuple{unknown, string}]
 │    │         ├── null [type=unknown]
 │    │         └── const: 'x' [type=string]
 │    └── projections
 │         └── cast: INT8 [type=int]
 │              └── variable: column1 [type=unknown]
 └── values
      ├── columns: column1:3(int) column2:4(string)
      ├── tuple [type=tuple{int, string}]
      │    ├── const: 1 [type=int]
      │    └── const: 'a' [type=string]
      └── tuple [type=tuple{int, string}]
           ├── const: 2 [type=int]
           └── const: 'b' [type=string]

build
VALUES (3, NULL), (NULL, 'x') INTERSECT VALUES (1, NULL), (2, NULL)
----
intersect
 ├── columns: column1:1(int) column2:2(string)
 ├── left columns: column1:1(int) column2:2(string)
 ├── right columns: column1:3(int) column2:5(string)
 ├── values
 │    ├── columns: column1:1(int) column2:2(string)
 │    ├── tuple [type=tuple{int, string}]
 │    │    ├── const: 3 [type=int]
 │    │    └── null [type=unknown]
 │    └── tuple [type=tuple{int, string}]
 │         ├── null [type=unknown]
 │         └── const: 'x' [type=string]
 └── project
      ├── columns: column2:5(string) column1:3(int)
      ├── values
      │    ├── columns: column1:3(int) column2:4(unknown)
      │    ├── tuple [type=tuple{int, unknown}]
      │    │    ├── const: 1 [type=int]
      │    │    └── null [type=unknown]
      │    └── tuple [type=tuple{int, unknown}]
      │         ├── const: 2 [type=int]
      │         └── null [type=unknown]
      └── projections
           └── cast: STRING [type=string]
                └── variable: column2 [type=unknown]

build
VALUES (NULL, NULL), (NULL, 'x') UNION ALL VALUES (1, NULL), (2, NULL)
----
union-all
 ├── columns: column1:5(int) column2:6(string)
 ├── left columns: column1:7(int) column2:2(string)
 ├── right columns: column1:3(int) column2:8(string)
 ├── project
 │    ├── columns: column1:7(int) column2:2(string)
 │    ├── values
 │    │    ├── columns: column1:1(unknown) column2:2(string)
 │    │    ├── tuple [type=tuple{unknown, string}]
 │    │    │    ├── null [type=unknown]
 │    │    │    └── null [type=unknown]
 │    │    └── tuple [type=tuple{unknown, string}]
 │    │         ├── null [type=unknown]
 │    │         └── const: 'x' [type=string]
 │    └── projections
 │         └── cast: INT8 [type=int]
 │              └── variable: column1 [type=unknown]
 └── project
      ├── columns: column2:8(string) column1:3(int)
      ├── values
      │    ├── columns: column1:3(int) column2:4(unknown)
      │    ├── tuple [type=tuple{int, unknown}]
      │    │    ├── const: 1 [type=int]
      │    │    └── null [type=unknown]
      │    └── tuple [type=tuple{int, unknown}]
      │         ├── const: 2 [type=int]
      │         └── null [type=unknown]
      └── projections
           └── cast: STRING [type=string]
                └── variable: column2 [type=unknown]

build
VALUES (NULL, NULL), (NULL, NULL) UNION ALL VALUES (NULL, NULL), (NULL, NULL)
----
union-all
 ├── columns: column1:5(unknown) column2:6(unknown)
 ├── left columns: column1:1(unknown) column2:2(unknown)
 ├── right columns: column1:3(unknown) column2:4(unknown)
 ├── values
 │    ├── columns: column1:1(unknown) column2:2(unknown)
 │    ├── tuple [type=tuple{unknown, unknown}]
 │    │    ├── null [type=unknown]
 │    │    └── null [type=unknown]
 │    └── tuple [type=tuple{unknown, unknown}]
 │         ├── null [type=unknown]
 │         └── null [type=unknown]
 └── values
      ├── columns: column1:3(unknown) column2:4(unknown)
      ├── tuple [type=tuple{unknown, unknown}]
      │    ├── null [type=unknown]
      │    └── null [type=unknown]
      └── tuple [type=tuple{unknown, unknown}]
           ├── null [type=unknown]
           └── null [type=unknown]

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

# Regression test for #34524.
build
(SELECT NULL FROM a) EXCEPT (VALUES((SELECT 1 FROM a LIMIT 1)), (1))
----
except
 ├── columns: "?column?":6(int)
 ├── left columns: "?column?":6(int)
 ├── right columns: column1:5(int)
 ├── project
 │    ├── columns: "?column?":6(int)
 │    ├── project
 │    │    ├── columns: "?column?":2(unknown)
 │    │    ├── scan a
 │    │    │    └── columns: a:1(int!null)
 │    │    └── projections
 │    │         └── null [type=unknown]
 │    └── projections
 │         └── cast: INT8 [type=int]
 │              └── variable: ?column? [type=unknown]
 └── values
      ├── columns: column1:5(int)
      ├── tuple [type=tuple{int}]
      │    └── subquery [type=int]
      │         └── max1-row
      │              ├── columns: "?column?":4(int!null)
      │              └── limit
      │                   ├── columns: "?column?":4(int!null)
      │                   ├── project
      │                   │    ├── columns: "?column?":4(int!null)
      │                   │    ├── scan a
      │                   │    │    └── columns: a:3(int!null)
      │                   │    └── projections
      │                   │         └── const: 1 [type=int]
      │                   └── const: 1 [type=int]
      └── tuple [type=tuple{int}]
           └── const: 1 [type=int]
