exec-ddl
CREATE TABLE x (a INT PRIMARY KEY)
----

exec-ddl
CREATE TABLE y (b INT PRIMARY KEY)
----

exec-ddl
CREATE TABLE z (c INT PRIMARY KEY)
----

exec-ddl
CREATE TABLE ax (a INT, x INT)
----

exec-ddl
CREATE TABLE ay (a INT, y INT)
----

exec-ddl
CREATE TABLE az (a INT, z INT)
----

build
SELECT * FROM x, y, z
----
project
 ├── columns: a:1!null b:4!null c:7!null
 └── inner-join (cross)
      ├── columns: a:1!null x.crdb_internal_mvcc_timestamp:2 x.tableoid:3 b:4!null y.crdb_internal_mvcc_timestamp:5 y.tableoid:6 c:7!null z.crdb_internal_mvcc_timestamp:8 z.tableoid:9
      ├── scan x
      │    └── columns: a:1!null x.crdb_internal_mvcc_timestamp:2 x.tableoid:3
      ├── inner-join (cross)
      │    ├── columns: b:4!null y.crdb_internal_mvcc_timestamp:5 y.tableoid:6 c:7!null z.crdb_internal_mvcc_timestamp:8 z.tableoid:9
      │    ├── scan y
      │    │    └── columns: b:4!null y.crdb_internal_mvcc_timestamp:5 y.tableoid:6
      │    ├── scan z
      │    │    └── columns: c:7!null z.crdb_internal_mvcc_timestamp:8 z.tableoid:9
      │    └── filters (true)
      └── filters (true)

build
SELECT * FROM x, LATERAL (SELECT * FROM y WHERE b = a)
----
project
 ├── columns: a:1!null b:4!null
 └── inner-join-apply
      ├── columns: a:1!null x.crdb_internal_mvcc_timestamp:2 x.tableoid:3 b:4!null
      ├── scan x
      │    └── columns: a:1!null x.crdb_internal_mvcc_timestamp:2 x.tableoid:3
      ├── project
      │    ├── columns: b:4!null
      │    └── select
      │         ├── columns: b:4!null y.crdb_internal_mvcc_timestamp:5 y.tableoid:6
      │         ├── scan y
      │         │    └── columns: b:4!null y.crdb_internal_mvcc_timestamp:5 y.tableoid:6
      │         └── filters
      │              └── b:4 = a:1
      └── filters (true)

build
SELECT * FROM x, (SELECT * FROM y WHERE b = a)
----
error (42703): column "a" does not exist

# Ensure that the presence of LATERAL properly affects name resolution.

build
SELECT
  (SELECT b FROM (SELECT c AS a FROM z), LATERAL (SELECT * FROM y WHERE b = a))
FROM x
----
project
 ├── columns: b:10
 ├── scan x
 │    └── columns: a:1!null x.crdb_internal_mvcc_timestamp:2 x.tableoid:3
 └── projections
      └── subquery [as=b:10]
           └── max1-row
                ├── columns: y.b:7!null
                └── project
                     ├── columns: y.b:7!null
                     └── inner-join-apply
                          ├── columns: c:4!null y.b:7!null
                          ├── project
                          │    ├── columns: c:4!null
                          │    └── scan z
                          │         └── columns: c:4!null z.crdb_internal_mvcc_timestamp:5 z.tableoid:6
                          ├── project
                          │    ├── columns: y.b:7!null
                          │    └── select
                          │         ├── columns: y.b:7!null y.crdb_internal_mvcc_timestamp:8 y.tableoid:9
                          │         ├── scan y
                          │         │    └── columns: y.b:7!null y.crdb_internal_mvcc_timestamp:8 y.tableoid:9
                          │         └── filters
                          │              └── y.b:7 = c:4
                          └── filters (true)

build
SELECT
  (SELECT b FROM (SELECT c AS a FROM z), (SELECT * FROM y WHERE b = a))
FROM x
----
project
 ├── columns: b:10
 ├── scan x
 │    └── columns: a:1!null x.crdb_internal_mvcc_timestamp:2 x.tableoid:3
 └── projections
      └── subquery [as=b:10]
           └── max1-row
                ├── columns: y.b:7!null
                └── project
                     ├── columns: y.b:7!null
                     └── inner-join (cross)
                          ├── columns: c:4!null y.b:7!null
                          ├── project
                          │    ├── columns: c:4!null
                          │    └── scan z
                          │         └── columns: c:4!null z.crdb_internal_mvcc_timestamp:5 z.tableoid:6
                          ├── project
                          │    ├── columns: y.b:7!null
                          │    └── select
                          │         ├── columns: y.b:7!null y.crdb_internal_mvcc_timestamp:8 y.tableoid:9
                          │         ├── scan y
                          │         │    └── columns: y.b:7!null y.crdb_internal_mvcc_timestamp:8 y.tableoid:9
                          │         └── filters
                          │              └── y.b:7 = a:1
                          └── filters (true)

build
SELECT * FROM x AS o WHERE EXISTS(SELECT * FROM x, LATERAL (SELECT * FROM y WHERE b = x.a AND o.a = x.a))
----
project
 ├── columns: a:1!null
 └── select
      ├── columns: o.a:1!null o.crdb_internal_mvcc_timestamp:2 o.tableoid:3
      ├── scan x [as=o]
      │    └── columns: o.a:1!null o.crdb_internal_mvcc_timestamp:2 o.tableoid:3
      └── filters
           └── exists
                └── project
                     ├── columns: x.a:4!null b:7!null
                     └── inner-join-apply
                          ├── columns: x.a:4!null x.crdb_internal_mvcc_timestamp:5 x.tableoid:6 b:7!null
                          ├── scan x
                          │    └── columns: x.a:4!null x.crdb_internal_mvcc_timestamp:5 x.tableoid:6
                          ├── project
                          │    ├── columns: b:7!null
                          │    └── select
                          │         ├── columns: b:7!null y.crdb_internal_mvcc_timestamp:8 y.tableoid:9
                          │         ├── scan y
                          │         │    └── columns: b:7!null y.crdb_internal_mvcc_timestamp:8 y.tableoid:9
                          │         └── filters
                          │              └── (b:7 = x.a:4) AND (o.a:1 = x.a:4)
                          └── filters (true)

build
SELECT * FROM x, LATERAL (SELECT * FROM y WHERE b = a), z
----
project
 ├── columns: a:1!null b:4!null c:7!null
 └── inner-join-apply
      ├── columns: a:1!null x.crdb_internal_mvcc_timestamp:2 x.tableoid:3 b:4!null c:7!null z.crdb_internal_mvcc_timestamp:8 z.tableoid:9
      ├── inner-join-apply
      │    ├── columns: a:1!null x.crdb_internal_mvcc_timestamp:2 x.tableoid:3 b:4!null
      │    ├── scan x
      │    │    └── columns: a:1!null x.crdb_internal_mvcc_timestamp:2 x.tableoid:3
      │    ├── project
      │    │    ├── columns: b:4!null
      │    │    └── select
      │    │         ├── columns: b:4!null y.crdb_internal_mvcc_timestamp:5 y.tableoid:6
      │    │         ├── scan y
      │    │         │    └── columns: b:4!null y.crdb_internal_mvcc_timestamp:5 y.tableoid:6
      │    │         └── filters
      │    │              └── b:4 = a:1
      │    └── filters (true)
      ├── scan z
      │    └── columns: c:7!null z.crdb_internal_mvcc_timestamp:8 z.tableoid:9
      └── filters (true)

build
SELECT * FROM x, LATERAL (SELECT * FROM y WHERE b = a), x
----
error (42712): source name "x" specified more than once (missing AS clause)

exec-ddl
CREATE TABLE j (
  id INT PRIMARY KEY,
  j JSONB
)
----

build
SELECT * FROM j, jsonb_array_elements(j.j->'foo')
----
project
 ├── columns: id:1!null j:2 value:5
 └── inner-join-apply
      ├── columns: id:1!null j:2 crdb_internal_mvcc_timestamp:3 tableoid:4 value:5
      ├── scan j
      │    └── columns: id:1!null j:2 crdb_internal_mvcc_timestamp:3 tableoid:4
      ├── project-set
      │    ├── columns: value:5
      │    ├── values
      │    │    └── ()
      │    └── zip
      │         └── jsonb_array_elements(j:2->'foo')
      └── filters (true)

# Explicit LATERAL makes no difference for SRFs.

build
SELECT * FROM j, LATERAL jsonb_array_elements(j.j->'foo')
----
project
 ├── columns: id:1!null j:2 value:5
 └── inner-join-apply
      ├── columns: id:1!null j:2 crdb_internal_mvcc_timestamp:3 tableoid:4 value:5
      ├── scan j
      │    └── columns: id:1!null j:2 crdb_internal_mvcc_timestamp:3 tableoid:4
      ├── project-set
      │    ├── columns: value:5
      │    ├── values
      │    │    └── ()
      │    └── zip
      │         └── jsonb_array_elements(j:2->'foo')
      └── filters (true)

# Referencing a lateral SRF from a lateral SRF.

build
SELECT * FROM j, jsonb_array_elements(j.j->'foo') AS e, jsonb_array_elements(e.e->'bar')
----
project
 ├── columns: id:1!null j:2 e:5 value:6
 └── inner-join-apply
      ├── columns: id:1!null j:2 crdb_internal_mvcc_timestamp:3 tableoid:4 value:5 value:6
      ├── inner-join-apply
      │    ├── columns: id:1!null j:2 crdb_internal_mvcc_timestamp:3 tableoid:4 value:5
      │    ├── scan j
      │    │    └── columns: id:1!null j:2 crdb_internal_mvcc_timestamp:3 tableoid:4
      │    ├── project-set
      │    │    ├── columns: value:5
      │    │    ├── values
      │    │    │    └── ()
      │    │    └── zip
      │    │         └── jsonb_array_elements(j:2->'foo')
      │    └── filters (true)
      ├── project-set
      │    ├── columns: value:6
      │    ├── values
      │    │    └── ()
      │    └── zip
      │         └── jsonb_array_elements(value:5->'bar')
      └── filters (true)

build
SELECT
    *
FROM
    j,
    jsonb_array_elements(
        (
            SELECT
                j2.j->'members' AS members
            FROM
                j AS j2
            WHERE
                j2.j->>'name' = j.j->>'name'
        )
    )
----
project
 ├── columns: id:1!null j:2 value:10
 └── inner-join-apply
      ├── columns: j.id:1!null j.j:2 j.crdb_internal_mvcc_timestamp:3 j.tableoid:4 value:10
      ├── scan j
      │    └── columns: j.id:1!null j.j:2 j.crdb_internal_mvcc_timestamp:3 j.tableoid:4
      ├── project-set
      │    ├── columns: value:10
      │    ├── values
      │    │    └── ()
      │    └── zip
      │         └── function: jsonb_array_elements
      │              └── subquery
      │                   └── max1-row
      │                        ├── columns: members:9
      │                        └── project
      │                             ├── columns: members:9
      │                             ├── select
      │                             │    ├── columns: j2.id:5!null j2.j:6 j2.crdb_internal_mvcc_timestamp:7 j2.tableoid:8
      │                             │    ├── scan j [as=j2]
      │                             │    │    └── columns: j2.id:5!null j2.j:6 j2.crdb_internal_mvcc_timestamp:7 j2.tableoid:8
      │                             │    └── filters
      │                             │         └── (j2.j:6->>'name') = (j.j:2->>'name')
      │                             └── projections
      │                                  └── j2.j:6->'members' [as=members:9]
      └── filters (true)

build
SELECT * FROM x JOIN LATERAL (SELECT * FROM y WHERE b = x.a) ON true
----
project
 ├── columns: a:1!null b:4!null
 └── inner-join-apply
      ├── columns: a:1!null x.crdb_internal_mvcc_timestamp:2 x.tableoid:3 b:4!null
      ├── scan x
      │    └── columns: a:1!null x.crdb_internal_mvcc_timestamp:2 x.tableoid:3
      ├── project
      │    ├── columns: b:4!null
      │    └── select
      │         ├── columns: b:4!null y.crdb_internal_mvcc_timestamp:5 y.tableoid:6
      │         ├── scan y
      │         │    └── columns: b:4!null y.crdb_internal_mvcc_timestamp:5 y.tableoid:6
      │         └── filters
      │              └── b:4 = a:1
      └── filters
           └── true

build
SELECT * FROM x LEFT JOIN LATERAL (SELECT * FROM y WHERE b = x.a) ON true
----
project
 ├── columns: a:1!null b:4
 └── left-join-apply
      ├── columns: a:1!null x.crdb_internal_mvcc_timestamp:2 x.tableoid:3 b:4
      ├── scan x
      │    └── columns: a:1!null x.crdb_internal_mvcc_timestamp:2 x.tableoid:3
      ├── project
      │    ├── columns: b:4!null
      │    └── select
      │         ├── columns: b:4!null y.crdb_internal_mvcc_timestamp:5 y.tableoid:6
      │         ├── scan y
      │         │    └── columns: b:4!null y.crdb_internal_mvcc_timestamp:5 y.tableoid:6
      │         └── filters
      │              └── b:4 = a:1
      └── filters
           └── true

build
SELECT * FROM x RIGHT JOIN LATERAL (SELECT * FROM y WHERE b = x.a) ON true
----
error (42601): The combining JOIN type must be INNER or LEFT for a LATERAL reference

build
SELECT * FROM x FULL OUTER JOIN LATERAL (SELECT * FROM y WHERE b = x.a) ON true
----
error (42601): The combining JOIN type must be INNER or LEFT for a LATERAL reference


build
SELECT * FROM ax JOIN LATERAL (SELECT * FROM ay WHERE x=y) USING (a)
----
project
 ├── columns: a:1 x:2 y:7!null
 └── inner-join-apply
      ├── columns: ax.a:1 x:2 ax.rowid:3!null ax.crdb_internal_mvcc_timestamp:4 ax.tableoid:5 ay.a:6 y:7!null
      ├── scan ax
      │    └── columns: ax.a:1 x:2 ax.rowid:3!null ax.crdb_internal_mvcc_timestamp:4 ax.tableoid:5
      ├── project
      │    ├── columns: ay.a:6 y:7!null
      │    └── select
      │         ├── columns: ay.a:6 y:7!null ay.rowid:8!null ay.crdb_internal_mvcc_timestamp:9 ay.tableoid:10
      │         ├── scan ay
      │         │    └── columns: ay.a:6 y:7 ay.rowid:8!null ay.crdb_internal_mvcc_timestamp:9 ay.tableoid:10
      │         └── filters
      │              └── x:2 = y:7
      └── filters
           └── ax.a:1 = ay.a:6

build
SELECT * FROM ax NATURAL JOIN LATERAL (SELECT * FROM ay WHERE x=y)
----
project
 ├── columns: a:1 x:2 y:7!null
 └── inner-join-apply
      ├── columns: ax.a:1 x:2 ax.rowid:3!null ax.crdb_internal_mvcc_timestamp:4 ax.tableoid:5 ay.a:6 y:7!null
      ├── scan ax
      │    └── columns: ax.a:1 x:2 ax.rowid:3!null ax.crdb_internal_mvcc_timestamp:4 ax.tableoid:5
      ├── project
      │    ├── columns: ay.a:6 y:7!null
      │    └── select
      │         ├── columns: ay.a:6 y:7!null ay.rowid:8!null ay.crdb_internal_mvcc_timestamp:9 ay.tableoid:10
      │         ├── scan ay
      │         │    └── columns: ay.a:6 y:7 ay.rowid:8!null ay.crdb_internal_mvcc_timestamp:9 ay.tableoid:10
      │         └── filters
      │              └── x:2 = y:7
      └── filters
           └── ax.a:1 = ay.a:6

build
SELECT * FROM ax JOIN ay ON true LEFT JOIN LATERAL (SELECT a+z AS y FROM az WHERE x=z) USING (y)
----
project
 ├── columns: y:7 a:1 x:2 a:6
 └── left-join-apply
      ├── columns: ax.a:1 x:2 ax.rowid:3!null ax.crdb_internal_mvcc_timestamp:4 ax.tableoid:5 ay.a:6 ay.y:7 ay.rowid:8!null ay.crdb_internal_mvcc_timestamp:9 ay.tableoid:10 y:16
      ├── inner-join (cross)
      │    ├── columns: ax.a:1 x:2 ax.rowid:3!null ax.crdb_internal_mvcc_timestamp:4 ax.tableoid:5 ay.a:6 ay.y:7 ay.rowid:8!null ay.crdb_internal_mvcc_timestamp:9 ay.tableoid:10
      │    ├── scan ax
      │    │    └── columns: ax.a:1 x:2 ax.rowid:3!null ax.crdb_internal_mvcc_timestamp:4 ax.tableoid:5
      │    ├── scan ay
      │    │    └── columns: ay.a:6 ay.y:7 ay.rowid:8!null ay.crdb_internal_mvcc_timestamp:9 ay.tableoid:10
      │    └── filters
      │         └── true
      ├── project
      │    ├── columns: y:16
      │    ├── select
      │    │    ├── columns: az.a:11 z:12!null az.rowid:13!null az.crdb_internal_mvcc_timestamp:14 az.tableoid:15
      │    │    ├── scan az
      │    │    │    └── columns: az.a:11 z:12 az.rowid:13!null az.crdb_internal_mvcc_timestamp:14 az.tableoid:15
      │    │    └── filters
      │    │         └── x:2 = z:12
      │    └── projections
      │         └── az.a:11 + z:12 [as=y:16]
      └── filters
           └── ay.y:7 = y:16
