exec-ddl
CREATE TABLE a (
    k INT PRIMARY KEY,
    i INT,
    s STRING,
    b BOOL,
    j JSON,
    INDEX i (i) WHERE s LIKE 'foo%',
    INVERTED INDEX j (j)
)
----

# --------------------------------------------------
# EliminateIndexJoinInsideProject
# --------------------------------------------------

# Eliminate the IndexJoin when the Project passthrough columns are a subset of
# the IndexJoin's input columns.
opt expect=EliminateIndexJoinInsideProject
SELECT k, i FROM a WHERE s LIKE 'foo%'
----
project
 ├── columns: k:1!null i:2
 ├── key: (1)
 ├── fd: (1)-->(2)
 └── scan a@i,partial
      ├── columns: k:1!null i:2
      ├── key: (1)
      └── fd: (1)-->(2)

# Eliminate the IndexJoin when the Project projection outer columns are a subset of
# the IndexJoin's input columns.
opt expect=EliminateIndexJoinInsideProject
SELECT k + 1, i + 1 FROM a WHERE s LIKE 'foo%'
----
project
 ├── columns: "?column?":9!null "?column?":10
 ├── immutable
 ├── scan a@i,partial
 │    ├── columns: k:1!null i:2
 │    ├── key: (1)
 │    └── fd: (1)-->(2)
 └── projections
      ├── k:1 + 1 [as="?column?":9, outer=(1), immutable]
      └── i:2 + 1 [as="?column?":10, outer=(2), immutable]

# Do not eliminate the IndexJoin when the Project passthrough columns are not a
# subset of the IndexJoin's input columns.
opt expect-not=EliminateIndexJoinInsideProject
SELECT k, b FROM a WHERE s LIKE 'foo%'
----
project
 ├── columns: k:1!null b:4
 ├── key: (1)
 ├── fd: (1)-->(4)
 └── index-join a
      ├── columns: k:1!null s:3!null b:4
      ├── key: (1)
      ├── fd: (1)-->(3,4)
      └── scan a@i,partial
           ├── columns: k:1!null
           └── key: (1)

# Do not eliminate the IndexJoin when the Project projection outer columns are
# not a subset of the IndexJoin's input columns.
opt expect-not=EliminateIndexJoinInsideProject
SELECT k, NOT b FROM a WHERE s LIKE 'foo%'
----
project
 ├── columns: k:1!null "?column?":9
 ├── key: (1)
 ├── fd: (1)-->(9)
 ├── index-join a
 │    ├── columns: k:1!null s:3!null b:4
 │    ├── key: (1)
 │    ├── fd: (1)-->(3,4)
 │    └── scan a@i,partial
 │         ├── columns: k:1!null
 │         └── key: (1)
 └── projections
      └── NOT b:4 [as="?column?":9, outer=(4)]

# Eliminate the IndexJoin for an inverted index scan when only the primary key
# column(s) are needed as passthrough columns.
opt expect=EliminateIndexJoinInsideProject
SELECT k FROM a WHERE j @> '{"a": "b"}'
----
project
 ├── columns: k:1!null
 ├── immutable
 ├── key: (1)
 └── scan a@j,inverted
      ├── columns: k:1!null
      ├── inverted constraint: /8/1
      │    └── spans: ["a"/"b", "a"/"b"]
      └── key: (1)

# Eliminate the IndexJoin for an inverted index scan when only the primary key
# column(s) are needed for projection columns.
opt expect=EliminateIndexJoinInsideProject
SELECT k + 1 FROM a WHERE j @> '{"a": "b"}'
----
project
 ├── columns: "?column?":9!null
 ├── immutable
 ├── scan a@j,inverted
 │    ├── columns: k:1!null
 │    ├── inverted constraint: /8/1
 │    │    └── spans: ["a"/"b", "a"/"b"]
 │    └── key: (1)
 └── projections
      └── k:1 + 1 [as="?column?":9, outer=(1), immutable]

# Do not eliminate the IndexJoin when the indexed column is needed. An inverted
# index scan cannot recreate the JSON column, so it must fetched from the
# primary index via an IndexJoin.
opt expect-not=EliminateIndexJoinInsideProject
SELECT j FROM a WHERE j @> '{"a": "b"}'
----
index-join a
 ├── columns: j:5!null
 ├── immutable
 └── scan a@j,inverted
      ├── columns: k:1!null
      ├── inverted constraint: /8/1
      │    └── spans: ["a"/"b", "a"/"b"]
      └── key: (1)
