# This file contains tests on tables with inverted indexes. Even though index
# selection is not a factor in the optbuilder, inverted indexes involve virtual
# columns that need to be handled properly (especially during mutations).

exec-ddl
CREATE TABLE kj (
    k INT PRIMARY KEY,
    j JSON,
    INVERTED INDEX (j)
)
----

build
SELECT * FROM kj
----
project
 ├── columns: k:1!null j:2
 └── scan kj
      └── columns: k:1!null j:2 crdb_internal_mvcc_timestamp:3 tableoid:4

exec-ddl
SHOW CREATE TABLE kj
----
TABLE kj
 ├── k int not null
 ├── j jsonb
 ├── crdb_internal_mvcc_timestamp decimal [hidden] [system]
 ├── tableoid oid [hidden] [system]
 ├── j_inverted_key encodedkey not null [inverted]
 ├── PRIMARY INDEX kj_pkey
 │    └── k int not null
 └── INVERTED INDEX kj_j_idx
      ├── j_inverted_key encodedkey not null [inverted]
      └── k int not null

build
SELECT j_inverted_key FROM kj
----
error (42703): column "j_inverted_key" does not exist

build
INSERT INTO kj VALUES (1, '{"a": 2}')
----
insert kj
 ├── columns: <none>
 ├── insert-mapping:
 │    ├── column1:6 => k:1
 │    └── column2:7 => j:2
 └── values
      ├── columns: column1:6!null column2:7!null
      └── (1, '{"a": 2}')

build
UPSERT INTO kj VALUES (1, '{"a": 2}')
----
upsert kj
 ├── arbiter indexes: kj_pkey
 ├── columns: <none>
 ├── canary column: k:8
 ├── fetch columns: k:8 j:9
 ├── insert-mapping:
 │    ├── column1:6 => k:1
 │    └── column2:7 => j:2
 ├── update-mapping:
 │    └── column2:7 => j:2
 └── project
      ├── columns: upsert_k:13 column1:6!null column2:7!null k:8 j:9 crdb_internal_mvcc_timestamp:10 tableoid:11
      ├── left-join (hash)
      │    ├── columns: column1:6!null column2:7!null k:8 j:9 crdb_internal_mvcc_timestamp:10 tableoid:11
      │    ├── ensure-upsert-distinct-on
      │    │    ├── columns: column1:6!null column2:7!null
      │    │    ├── grouping columns: column1:6!null
      │    │    ├── values
      │    │    │    ├── columns: column1:6!null column2:7!null
      │    │    │    └── (1, '{"a": 2}')
      │    │    └── aggregations
      │    │         └── first-agg [as=column2:7]
      │    │              └── column2:7
      │    ├── scan kj
      │    │    ├── columns: k:8!null j:9 crdb_internal_mvcc_timestamp:10 tableoid:11
      │    │    └── flags: avoid-full-scan disabled not visible index feature
      │    └── filters
      │         └── column1:6 = k:8
      └── projections
           └── CASE WHEN k:8 IS NULL THEN column1:6 ELSE k:8 END [as=upsert_k:13]

build
INSERT INTO kj VALUES (1, '{"a": 2}') ON CONFLICT (k) DO NOTHING
----
insert kj
 ├── arbiter indexes: kj_pkey
 ├── columns: <none>
 ├── insert-mapping:
 │    ├── column1:6 => k:1
 │    └── column2:7 => j:2
 └── upsert-distinct-on
      ├── columns: column1:6!null column2:7!null
      ├── grouping columns: column1:6!null
      ├── anti-join (hash)
      │    ├── columns: column1:6!null column2:7!null
      │    ├── values
      │    │    ├── columns: column1:6!null column2:7!null
      │    │    └── (1, '{"a": 2}')
      │    ├── scan kj
      │    │    ├── columns: k:8!null j:9
      │    │    └── flags: avoid-full-scan disabled not visible index feature
      │    └── filters
      │         └── column1:6 = k:8
      └── aggregations
           └── first-agg [as=column2:7]
                └── column2:7

build
INSERT INTO kj VALUES (1, '{"a": 2}') ON CONFLICT (k) DO UPDATE SET j = '{"a": 3}'
----
upsert kj
 ├── arbiter indexes: kj_pkey
 ├── columns: <none>
 ├── canary column: k:8
 ├── fetch columns: k:8 j:9
 ├── insert-mapping:
 │    ├── column1:6 => k:1
 │    └── column2:7 => j:2
 ├── update-mapping:
 │    └── upsert_j:15 => j:2
 └── project
      ├── columns: upsert_k:14 upsert_j:15!null column1:6!null column2:7!null k:8 j:9 crdb_internal_mvcc_timestamp:10 tableoid:11 j_new:13!null
      ├── project
      │    ├── columns: j_new:13!null column1:6!null column2:7!null k:8 j:9 crdb_internal_mvcc_timestamp:10 tableoid:11
      │    ├── left-join (hash)
      │    │    ├── columns: column1:6!null column2:7!null k:8 j:9 crdb_internal_mvcc_timestamp:10 tableoid:11
      │    │    ├── ensure-upsert-distinct-on
      │    │    │    ├── columns: column1:6!null column2:7!null
      │    │    │    ├── grouping columns: column1:6!null
      │    │    │    ├── values
      │    │    │    │    ├── columns: column1:6!null column2:7!null
      │    │    │    │    └── (1, '{"a": 2}')
      │    │    │    └── aggregations
      │    │    │         └── first-agg [as=column2:7]
      │    │    │              └── column2:7
      │    │    ├── scan kj
      │    │    │    ├── columns: k:8!null j:9 crdb_internal_mvcc_timestamp:10 tableoid:11
      │    │    │    └── flags: avoid-full-scan disabled not visible index feature
      │    │    └── filters
      │    │         └── column1:6 = k:8
      │    └── projections
      │         └── '{"a": 3}' [as=j_new:13]
      └── projections
           ├── CASE WHEN k:8 IS NULL THEN column1:6 ELSE k:8 END [as=upsert_k:14]
           └── CASE WHEN k:8 IS NULL THEN column2:7 ELSE j_new:13 END [as=upsert_j:15]

build
UPDATE kj SET j = '{"a": 3}' WHERE k > 0
----
update kj
 ├── columns: <none>
 ├── fetch columns: k:6 j:7
 ├── update-mapping:
 │    └── j_new:11 => j:2
 └── project
      ├── columns: j_new:11!null k:6!null j:7 crdb_internal_mvcc_timestamp:8 tableoid:9
      ├── select
      │    ├── columns: k:6!null j:7 crdb_internal_mvcc_timestamp:8 tableoid:9
      │    ├── scan kj
      │    │    ├── columns: k:6!null j:7 crdb_internal_mvcc_timestamp:8 tableoid:9
      │    │    └── flags: avoid-full-scan
      │    └── filters
      │         └── k:6 > 0
      └── projections
           └── '{"a": 3}' [as=j_new:11]

build
DELETE FROM kj WHERE j @> '{"a": 2}'
----
delete kj
 ├── columns: <none>
 ├── fetch columns: k:6 j:7
 └── select
      ├── columns: k:6!null j:7!null crdb_internal_mvcc_timestamp:8 tableoid:9
      ├── scan kj
      │    ├── columns: k:6!null j:7 crdb_internal_mvcc_timestamp:8 tableoid:9
      │    └── flags: avoid-full-scan
      └── filters
           └── j:7 @> '{"a": 2}'
