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

exec-ddl
CREATE TABLE uv (u INT, v INT NOT NULL)
----
TABLE uv
 ├── u int
 ├── v int not null
 ├── rowid int not null (hidden)
 └── INDEX primary
      └── rowid int not null (hidden)

build
SELECT * FROM xy WHERE x < 5
----
select
 ├── columns: x:1(int!null) y:2(int)
 ├── key: (1)
 ├── fd: (1)-->(2)
 ├── prune: (2)
 ├── interesting orderings: (+1)
 ├── scan xy
 │    ├── columns: x:1(int!null) y:2(int)
 │    ├── key: (1)
 │    ├── fd: (1)-->(2)
 │    ├── prune: (1,2)
 │    └── interesting orderings: (+1)
 └── filters
      └── lt [type=bool, outer=(1), constraints=(/1: (/NULL - /4]; tight)]
           ├── variable: x [type=int]
           └── const: 5 [type=int]

build
SELECT xy.x + 1 = length('foo') + xy.y AS a, uv.rowid * xy.x AS b FROM xy, uv
----
project
 ├── columns: a:6(bool) b:7(int)
 ├── prune: (6,7)
 ├── inner-join
 │    ├── columns: x:1(int!null) y:2(int) u:3(int) v:4(int!null) rowid:5(int!null)
 │    ├── key: (1,5)
 │    ├── fd: (1)-->(2), (5)-->(3,4)
 │    ├── prune: (1-5)
 │    ├── interesting orderings: (+1) (+5)
 │    ├── scan xy
 │    │    ├── columns: x:1(int!null) y:2(int)
 │    │    ├── key: (1)
 │    │    ├── fd: (1)-->(2)
 │    │    ├── prune: (1,2)
 │    │    └── interesting orderings: (+1)
 │    ├── scan uv
 │    │    ├── columns: u:3(int) v:4(int!null) rowid:5(int!null)
 │    │    ├── key: (5)
 │    │    ├── fd: (5)-->(3,4)
 │    │    ├── prune: (3-5)
 │    │    └── interesting orderings: (+5)
 │    └── filters (true)
 └── projections
      ├── eq [type=bool, outer=(1,2)]
      │    ├── plus [type=int]
      │    │    ├── variable: x [type=int]
      │    │    └── const: 1 [type=int]
      │    └── plus [type=int]
      │         ├── function: length [type=int]
      │         │    └── const: 'foo' [type=string]
      │         └── variable: y [type=int]
      └── mult [type=int, outer=(1,5)]
           ├── variable: rowid [type=int]
           └── variable: x [type=int]

build
SELECT * FROM xy WHERE EXISTS(SELECT * FROM uv WHERE u=x)
----
select
 ├── columns: x:1(int!null) y:2(int)
 ├── key: (1)
 ├── fd: (1)-->(2)
 ├── prune: (2)
 ├── interesting orderings: (+1)
 ├── scan xy
 │    ├── columns: x:1(int!null) y:2(int)
 │    ├── key: (1)
 │    ├── fd: (1)-->(2)
 │    ├── prune: (1,2)
 │    └── interesting orderings: (+1)
 └── filters
      └── exists [type=bool, outer=(1), correlated-subquery]
           └── project
                ├── columns: u:3(int!null) v:4(int!null)
                ├── outer: (1)
                ├── fd: ()-->(3)
                ├── prune: (3,4)
                └── select
                     ├── columns: u:3(int!null) v:4(int!null) rowid:5(int!null)
                     ├── outer: (1)
                     ├── key: (5)
                     ├── fd: ()-->(3), (5)-->(4)
                     ├── prune: (4,5)
                     ├── interesting orderings: (+5)
                     ├── scan uv
                     │    ├── columns: u:3(int) v:4(int!null) rowid:5(int!null)
                     │    ├── key: (5)
                     │    ├── fd: (5)-->(3,4)
                     │    ├── prune: (3-5)
                     │    └── interesting orderings: (+5)
                     └── filters
                          └── eq [type=bool, outer=(1,3), constraints=(/1: (/NULL - ]; /3: (/NULL - ]), fd=(1)==(3), (3)==(1)]
                               ├── variable: u [type=int]
                               └── variable: x [type=int]

build
SELECT * FROM xy WHERE y IN (SELECT v FROM uv WHERE u=x)
----
select
 ├── columns: x:1(int!null) y:2(int)
 ├── key: (1)
 ├── fd: (1)-->(2)
 ├── interesting orderings: (+1)
 ├── scan xy
 │    ├── columns: x:1(int!null) y:2(int)
 │    ├── key: (1)
 │    ├── fd: (1)-->(2)
 │    ├── prune: (1,2)
 │    └── interesting orderings: (+1)
 └── filters
      └── any: eq [type=bool, outer=(1,2), correlated-subquery]
           ├── project
           │    ├── columns: v:4(int!null)
           │    ├── outer: (1)
           │    ├── prune: (4)
           │    └── select
           │         ├── columns: u:3(int!null) v:4(int!null) rowid:5(int!null)
           │         ├── outer: (1)
           │         ├── key: (5)
           │         ├── fd: ()-->(3), (5)-->(4)
           │         ├── prune: (4,5)
           │         ├── interesting orderings: (+5)
           │         ├── scan uv
           │         │    ├── columns: u:3(int) v:4(int!null) rowid:5(int!null)
           │         │    ├── key: (5)
           │         │    ├── fd: (5)-->(3,4)
           │         │    ├── prune: (3-5)
           │         │    └── interesting orderings: (+5)
           │         └── filters
           │              └── eq [type=bool, outer=(1,3), constraints=(/1: (/NULL - ]; /3: (/NULL - ]), fd=(1)==(3), (3)==(1)]
           │                   ├── variable: u [type=int]
           │                   └── variable: x [type=int]
           └── variable: y [type=int]

# Regression for 36137: need to detect correlation in 2nd Any operator argument.
build
SELECT * FROM xy WHERE x=1 OR y IN (SELECT v FROM uv)
----
select
 ├── columns: x:1(int!null) y:2(int)
 ├── key: (1)
 ├── fd: (1)-->(2)
 ├── interesting orderings: (+1)
 ├── scan xy
 │    ├── columns: x:1(int!null) y:2(int)
 │    ├── key: (1)
 │    ├── fd: (1)-->(2)
 │    ├── prune: (1,2)
 │    └── interesting orderings: (+1)
 └── filters
      └── or [type=bool, outer=(1,2), correlated-subquery]
           ├── eq [type=bool]
           │    ├── variable: x [type=int]
           │    └── const: 1 [type=int]
           └── any: eq [type=bool]
                ├── project
                │    ├── columns: v:4(int!null)
                │    ├── prune: (4)
                │    └── scan uv
                │         ├── columns: u:3(int) v:4(int!null) rowid:5(int!null)
                │         ├── key: (5)
                │         ├── fd: (5)-->(3,4)
                │         ├── prune: (3-5)
                │         └── interesting orderings: (+5)
                └── variable: y [type=int]

# Side-effects: test DivOp and impure FuncOp.
build
SELECT sum(x), div
FROM (SELECT x, y, x/y AS div FROM xy)
INNER JOIN (SELECT * FROM uv WHERE now() > '2018-01-01')
ON x=u
GROUP BY div
----
group-by
 ├── columns: sum:7(decimal) div:3(decimal)
 ├── grouping columns: div:3(decimal)
 ├── side-effects
 ├── key: (3)
 ├── fd: (3)-->(7)
 ├── prune: (7)
 ├── project
 │    ├── columns: x:1(int!null) div:3(decimal)
 │    ├── side-effects
 │    ├── fd: (1)-->(3)
 │    ├── prune: (1,3)
 │    ├── interesting orderings: (+1)
 │    └── inner-join
 │         ├── columns: x:1(int!null) y:2(int) div:3(decimal) u:4(int!null) v:5(int!null)
 │         ├── side-effects
 │         ├── fd: (1)-->(2,3), (1)==(4), (4)==(1)
 │         ├── prune: (2,3,5)
 │         ├── interesting orderings: (+1)
 │         ├── project
 │         │    ├── columns: div:3(decimal) x:1(int!null) y:2(int)
 │         │    ├── side-effects
 │         │    ├── key: (1)
 │         │    ├── fd: (1)-->(2,3)
 │         │    ├── prune: (1-3)
 │         │    ├── interesting orderings: (+1)
 │         │    ├── scan xy
 │         │    │    ├── columns: x:1(int!null) y:2(int)
 │         │    │    ├── key: (1)
 │         │    │    ├── fd: (1)-->(2)
 │         │    │    ├── prune: (1,2)
 │         │    │    └── interesting orderings: (+1)
 │         │    └── projections
 │         │         └── div [type=decimal, outer=(1,2), side-effects]
 │         │              ├── variable: x [type=int]
 │         │              └── variable: y [type=int]
 │         ├── project
 │         │    ├── columns: u:4(int) v:5(int!null)
 │         │    ├── side-effects
 │         │    ├── prune: (4,5)
 │         │    └── select
 │         │         ├── columns: u:4(int) v:5(int!null) rowid:6(int!null)
 │         │         ├── side-effects
 │         │         ├── key: (6)
 │         │         ├── fd: (6)-->(4,5)
 │         │         ├── prune: (4-6)
 │         │         ├── interesting orderings: (+6)
 │         │         ├── scan uv
 │         │         │    ├── columns: u:4(int) v:5(int!null) rowid:6(int!null)
 │         │         │    ├── key: (6)
 │         │         │    ├── fd: (6)-->(4,5)
 │         │         │    ├── prune: (4-6)
 │         │         │    └── interesting orderings: (+6)
 │         │         └── filters
 │         │              └── gt [type=bool, side-effects]
 │         │                   ├── function: now [type=timestamptz]
 │         │                   └── const: '2018-01-01 00:00:00+00:00' [type=timestamptz]
 │         └── filters
 │              └── eq [type=bool, outer=(1,4), constraints=(/1: (/NULL - ]; /4: (/NULL - ]), fd=(1)==(4), (4)==(1)]
 │                   ├── variable: x [type=int]
 │                   └── variable: u [type=int]
 └── aggregations
      └── sum [type=decimal, outer=(1)]
           └── variable: x [type=int]
