# 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:1(unknown)
      ├── right columns: column1:2(int)
      ├── values
      │    ├── columns: column1:1(unknown)
      │    └── tuple [type=tuple{unknown}]
      │         └── null [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:7(string)
 ├── union-all
 │    ├── columns: a:5(int!null) b:6(int)
 │    ├── left columns: a:1(int) b:2(unknown)
 │    ├── right columns: a:3(int) b:4(int)
 │    ├── project
 │    │    ├── columns: a:1(int!null) b:2(unknown)
 │    │    ├── values
 │    │    │    └── tuple [type=tuple]
 │    │    └── projections
 │    │         ├── const: 1 [type=int]
 │    │         └── null [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:7(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:4(unknown)
 │    ├── 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: a:3(int!null) b:4(unknown)
 │         ├── values
 │         │    └── tuple [type=tuple]
 │         └── projections
 │              ├── const: 2 [type=int]
 │              └── null [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: uniontest.k:1(int!null) uniontest.v:2(int) uniontest.rowid:3(int!null)
 │         ├── scan uniontest
 │         │    └── columns: uniontest.k:1(int) uniontest.v:2(int) uniontest.rowid:3(int!null)
 │         └── filters [type=bool]
 │              └── eq [type=bool]
 │                   ├── variable: uniontest.k [type=int]
 │                   └── const: 1 [type=int]
 └── project
      ├── columns: uniontest.v:5(int)
      └── select
           ├── columns: uniontest.k:4(int!null) uniontest.v:5(int) uniontest.rowid:6(int!null)
           ├── scan uniontest
           │    └── columns: uniontest.k:4(int) uniontest.v:5(int) uniontest.rowid:6(int!null)
           └── filters [type=bool]
                └── eq [type=bool]
                     ├── variable: uniontest.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: uniontest.k:1(int!null) uniontest.v:2(int) uniontest.rowid:3(int!null)
 │         ├── scan uniontest
 │         │    └── columns: uniontest.k:1(int) uniontest.v:2(int) uniontest.rowid:3(int!null)
 │         └── filters [type=bool]
 │              └── eq [type=bool]
 │                   ├── variable: uniontest.k [type=int]
 │                   └── const: 1 [type=int]
 └── project
      ├── columns: uniontest.v:5(int)
      └── select
           ├── columns: uniontest.k:4(int!null) uniontest.v:5(int) uniontest.rowid:6(int!null)
           ├── scan uniontest
           │    └── columns: uniontest.k:4(int) uniontest.v:5(int) uniontest.rowid:6(int!null)
           └── filters [type=bool]
                └── eq [type=bool]
                     ├── variable: uniontest.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: uniontest.v:2(int)
 ├── right columns: uniontest.v:5(int)
 ├── project
 │    ├── columns: uniontest.v:2(int)
 │    └── select
 │         ├── columns: uniontest.k:1(int!null) uniontest.v:2(int) uniontest.rowid:3(int!null)
 │         ├── scan uniontest
 │         │    └── columns: uniontest.k:1(int) uniontest.v:2(int) uniontest.rowid:3(int!null)
 │         └── filters [type=bool]
 │              └── eq [type=bool]
 │                   ├── variable: uniontest.k [type=int]
 │                   └── const: 1 [type=int]
 └── project
      ├── columns: uniontest.v:5(int)
      └── select
           ├── columns: uniontest.k:4(int!null) uniontest.v:5(int) uniontest.rowid:6(int!null)
           ├── scan uniontest
           │    └── columns: uniontest.k:4(int) uniontest.v:5(int) uniontest.rowid:6(int!null)
           └── filters [type=bool]
                └── eq [type=bool]
                     ├── variable: uniontest.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: uniontest.v:2(int)
 ├── right columns: uniontest.v:5(int)
 ├── project
 │    ├── columns: uniontest.v:2(int)
 │    └── select
 │         ├── columns: uniontest.k:1(int!null) uniontest.v:2(int) uniontest.rowid:3(int!null)
 │         ├── scan uniontest
 │         │    └── columns: uniontest.k:1(int) uniontest.v:2(int) uniontest.rowid:3(int!null)
 │         └── filters [type=bool]
 │              └── eq [type=bool]
 │                   ├── variable: uniontest.k [type=int]
 │                   └── const: 1 [type=int]
 └── project
      ├── columns: uniontest.v:5(int)
      └── select
           ├── columns: uniontest.k:4(int!null) uniontest.v:5(int) uniontest.rowid:6(int!null)
           ├── scan uniontest
           │    └── columns: uniontest.k:4(int) uniontest.v:5(int) uniontest.rowid:6(int!null)
           └── filters [type=bool]
                └── eq [type=bool]
                     ├── variable: uniontest.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: uniontest.v:2(int)
 ├── right columns: uniontest.v:5(int)
 ├── project
 │    ├── columns: uniontest.v:2(int)
 │    └── select
 │         ├── columns: uniontest.k:1(int!null) uniontest.v:2(int) uniontest.rowid:3(int!null)
 │         ├── scan uniontest
 │         │    └── columns: uniontest.k:1(int) uniontest.v:2(int) uniontest.rowid:3(int!null)
 │         └── filters [type=bool]
 │              └── eq [type=bool]
 │                   ├── variable: uniontest.k [type=int]
 │                   └── const: 1 [type=int]
 └── project
      ├── columns: uniontest.v:5(int)
      └── select
           ├── columns: uniontest.k:4(int!null) uniontest.v:5(int) uniontest.rowid:6(int!null)
           ├── scan uniontest
           │    └── columns: uniontest.k:4(int) uniontest.v:5(int) uniontest.rowid:6(int!null)
           └── filters [type=bool]
                └── eq [type=bool]
                     ├── variable: uniontest.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: uniontest.v:2(int)
 ├── right columns: uniontest.v:5(int)
 ├── project
 │    ├── columns: uniontest.v:2(int)
 │    └── select
 │         ├── columns: uniontest.k:1(int!null) uniontest.v:2(int) uniontest.rowid:3(int!null)
 │         ├── scan uniontest
 │         │    └── columns: uniontest.k:1(int) uniontest.v:2(int) uniontest.rowid:3(int!null)
 │         └── filters [type=bool]
 │              └── eq [type=bool]
 │                   ├── variable: uniontest.k [type=int]
 │                   └── const: 1 [type=int]
 └── project
      ├── columns: uniontest.v:5(int)
      └── select
           ├── columns: uniontest.k:4(int!null) uniontest.v:5(int) uniontest.rowid:6(int!null)
           ├── scan uniontest
           │    └── columns: uniontest.k:4(int) uniontest.v:5(int) uniontest.rowid:6(int!null)
           └── filters [type=bool]
                └── eq [type=bool]
                     ├── variable: uniontest.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: uniontest.k:1(int!null) uniontest.v:2(int) uniontest.rowid:3(int!null)
 │         │         ├── scan uniontest
 │         │         │    └── columns: uniontest.k:1(int) uniontest.v:2(int) uniontest.rowid:3(int!null)
 │         │         └── filters [type=bool]
 │         │              └── eq [type=bool]
 │         │                   ├── variable: uniontest.k [type=int]
 │         │                   └── const: 1 [type=int]
 │         └── project
 │              ├── columns: uniontest.v:5(int)
 │              └── select
 │                   ├── columns: uniontest.k:4(int!null) uniontest.v:5(int) uniontest.rowid:6(int!null)
 │                   ├── scan uniontest
 │                   │    └── columns: uniontest.k:4(int) uniontest.v:5(int) uniontest.rowid:6(int!null)
 │                   └── filters [type=bool]
 │                        └── eq [type=bool]
 │                             ├── variable: uniontest.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: uniontest.k:1(int!null) uniontest.v:2(int) uniontest.rowid:3(int!null)
 │         │         ├── scan uniontest
 │         │         │    └── columns: uniontest.k:1(int) uniontest.v:2(int) uniontest.rowid:3(int!null)
 │         │         └── filters [type=bool]
 │         │              └── eq [type=bool]
 │         │                   ├── variable: uniontest.k [type=int]
 │         │                   └── const: 1 [type=int]
 │         └── project
 │              ├── columns: uniontest.v:5(int)
 │              └── select
 │                   ├── columns: uniontest.k:4(int!null) uniontest.v:5(int) uniontest.rowid:6(int!null)
 │                   ├── scan uniontest
 │                   │    └── columns: uniontest.k:4(int) uniontest.v:5(int) uniontest.rowid:6(int!null)
 │                   └── filters [type=bool]
 │                        └── eq [type=bool]
 │                             ├── variable: uniontest.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: uniontest.k:4(int)
 ├── project
 │    ├── columns: uniontest.v:2(int)
 │    └── scan uniontest
 │         └── columns: uniontest.k:1(int) uniontest.v:2(int) uniontest.rowid:3(int!null)
 └── project
      ├── columns: uniontest.k:4(int)
      └── scan uniontest
           └── columns: uniontest.k:4(int) uniontest.v:5(int) uniontest.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: uniontest.k:4(int)
 ├── project
 │    ├── columns: uniontest.v:2(int)
 │    └── scan uniontest
 │         └── columns: uniontest.k:1(int) uniontest.v:2(int) uniontest.rowid:3(int!null)
 └── project
      ├── columns: uniontest.k:4(int)
      └── scan uniontest
           └── columns: uniontest.k:4(int) uniontest.v:5(int) uniontest.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 [type=bool]
      └── 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 [type=bool]
      └── 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: abc.b:6(string)
      ├── project
      │    ├── columns: abc.a:1(string) abc.b:2(string!null)
      │    └── scan abc
      │         └── columns: abc.a:1(string) abc.b:2(string!null) abc.c:3(string!null) abc.rowid:4(int!null)
      └── project
           ├── columns: abc.b:6(string!null)
           └── scan abc
                └── columns: abc.a:5(string) abc.b:6(string!null) abc.c:7(string!null) abc.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) abc.b:2(string!null)
      │    └── scan abc
      │         └── columns: abc.a:1(string) abc.b:2(string!null) abc.c:3(string!null) abc.rowid:4(int!null)
      └── project
           ├── columns: abc.a:5(string) abc.c:7(string!null)
           └── scan abc
                └── columns: abc.a:5(string) abc.b:6(string!null) abc.c:7(string!null) abc.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: abc.a:1(string)
 ├── right columns: abc.b:6(string)
 ├── project
 │    ├── columns: abc.a:1(string) abc.b:2(string!null)
 │    └── scan abc
 │         └── columns: abc.a:1(string) abc.b:2(string!null) abc.c:3(string!null) abc.rowid:4(int!null)
 └── project
      ├── columns: abc.a:5(string) abc.b:6(string!null) abc.c:7(string!null)
      └── scan abc
           └── columns: abc.a:5(string) abc.b:6(string!null) abc.c:7(string!null) abc.rowid:8(int!null)
