# The following tests are similar to
# pkg/sql/opt/exec/execbuilder/testdata/ but are here as they depend
# on index mutations.

#
# Ensure MERGING indexes forces Puts even on unique indexes.
#
statement
CREATE TABLE ti (
    a INT PRIMARY KEY,
    b INT,
    FAMILY (a, b)
);
CREATE UNIQUE INDEX test_index_to_mutate ON ti (b);
INSERT INTO ti VALUES (1, 1), (2, 2), (4, 4)
----

mutate-index ti test_index_to_mutate MERGING
----

# Insert that would conflict in WRITE_ONLY does not conflict
kvtrace
INSERT INTO ti VALUES (3, 1)
----
CPut /Table/106/1/3/0 -> /TUPLE/2:2:Int/1
Put /Table/106/2/1/0 -> /BYTES/0x8b

kvtrace
UPDATE ti SET b = 2 WHERE a = 4
----
Scan /Table/106/1/4/0 lock Exclusive (Block, Unreplicated)
Put /Table/106/1/4/0 -> /TUPLE/2:2:Int/2
Del /Table/106/2/4/0
Put /Table/106/2/2/0 -> /BYTES/0x8c

kvtrace
UPSERT INTO ti VALUES (5, 1)
----
Scan /Table/106/1/5/0 lock Exclusive (Block, Unreplicated)
CPut /Table/106/1/5/0 -> /TUPLE/2:2:Int/1
Put /Table/106/2/1/0 -> /BYTES/0x8d

kvtrace
UPSERT INTO ti VALUES (2, 1)
----
Scan /Table/106/1/2/0 lock Exclusive (Block, Unreplicated)
Put /Table/106/1/2/0 -> /TUPLE/2:2:Int/1
Del /Table/106/2/2/0
Put /Table/106/2/1/0 -> /BYTES/0x8a

kvtrace
INSERT INTO ti VALUES (6, 1) ON CONFLICT DO NOTHING
----
Scan /Table/106/1/6/0
CPut /Table/106/1/6/0 -> /TUPLE/2:2:Int/1
Put /Table/106/2/1/0 -> /BYTES/0x8e

kvtrace
INSERT INTO ti VALUES (1, 2) ON CONFLICT (a) DO UPDATE SET b = excluded.b
----
Scan /Table/106/1/1/0 lock Exclusive (Block, Unreplicated)
Put /Table/106/1/1/0 -> /TUPLE/2:2:Int/2
Del /Table/106/2/1/0
Put /Table/106/2/2/0 -> /BYTES/0x89

# ---------------------------------------------------------
# Partial Index With ForcePut
# ---------------------------------------------------------
statement
CREATE TABLE tpfp (
    a INT PRIMARY KEY,
    b INT,
    c STRING,
    FAMILY (a, b, c),
    UNIQUE INDEX partial (c) WHERE a > b AND c IN ('foo', 'foobar')
)
----

mutate-index tpfp partial MERGING
----

statement
INSERT INTO tpfp VALUES (3, 4, 'bar')
----

# Update a row that doesn't match the partial index.
kvtrace
UPDATE tpfp SET b = b + 1
----
Scan /Table/107/{1-2} lock Exclusive (Block, Unreplicated)
Put /Table/107/1/3/0 -> /TUPLE/2:2:Int/5/1:3:Bytes/bar

# Update a row that didn't match the partial index before but matches after.
kvtrace
UPDATE tpfp SET b = b - 3, c = 'foo'
----
Scan /Table/107/{1-2} lock Exclusive (Block, Unreplicated)
Put /Table/107/1/3/0 -> /TUPLE/2:2:Int/2/1:3:Bytes/foo
Put /Table/107/2/"foo"/0 -> /BYTES/0x8b

# Update a row that matches the partial index before and after, but the index
# entry doesn't change.
kvtrace
UPDATE tpfp SET b = b - 1
----
Scan /Table/107/{1-2} lock Exclusive (Block, Unreplicated)
Put /Table/107/1/3/0 -> /TUPLE/2:2:Int/1/1:3:Bytes/foo

# Update a row that matches the partial index before and after, and the index
# entry changes.
kvtrace
UPDATE tpfp SET b = b + 1, c = 'foobar'
----
Scan /Table/107/{1-2} lock Exclusive (Block, Unreplicated)
Put /Table/107/1/3/0 -> /TUPLE/2:2:Int/2/1:3:Bytes/foobar
Del /Table/107/2/"foo"/0
Put /Table/107/2/"foobar"/0 -> /BYTES/0x8b

# Update a row that matches the partial index before but not after.
kvtrace
UPDATE tpfp SET c = 'baz'
----
Scan /Table/107/{1-2} lock Exclusive (Block, Unreplicated)
Put /Table/107/1/3/0 -> /TUPLE/2:2:Int/2/1:3:Bytes/baz
Del /Table/107/2/"foobar"/0

# ---------------------------------------------------------
# Expression Index With ForcePut
# ---------------------------------------------------------
statement
CREATE TABLE tefp (
  k INT PRIMARY KEY,
  a INT,
  b INT,
  FAMILY (k, a, b),
  UNIQUE INDEX t_a_plus_b_idx ((a + b))
)
----

statement
INSERT INTO tefp VALUES (1, 2, 100)
----

# Update a row which changes the index entry.
kvtrace
UPDATE tefp SET a = a + 1, b = b + 100
----
Scan /Table/108/{1-2} lock Exclusive (Block, Unreplicated)
Put /Table/108/1/1/0 -> /TUPLE/2:2:Int/3/1:3:Int/200
Del /Table/108/2/102/0
CPut /Table/108/2/203/0 -> /BYTES/0x89 (expecting does not exist)

# Update a row with different values without changing the index entry.
kvtrace
UPDATE tefp SET a = a + 1, b = b - 1
----
Scan /Table/108/{1-2} lock Exclusive (Block, Unreplicated)
Put /Table/108/1/1/0 -> /TUPLE/2:2:Int/4/1:3:Int/199

# ---------------------------------------------------------
# Inverted Index With ForcePut
# ---------------------------------------------------------

statement
CREATE TABLE tifp (
  a INT PRIMARY KEY,
  b INT[],
  FAMILY (a,b),
  INVERTED INDEX inverted (b)
 )
----

mutate-index tifp inverted MERGING
----

statement
INSERT INTO tifp VALUES (1, ARRAY[1, 2, 3, 2, 2, NULL, 3])
----

# Update a row that has 1 new entry and 1 removed entry in the index.
kvtrace
UPDATE tifp SET b = ARRAY[1, 2, 2, NULL, 4, 4]
----
Scan /Table/109/{1-2} lock Exclusive (Block, Unreplicated)
Put /Table/109/1/1/0 -> /TUPLE/
Del /Table/109/2/3/1/0
Put /Table/109/2/4/1/0 -> /BYTES/

# ---------------------------------------------------------
# Multicolumn Inverted Index With ForcePut
# ---------------------------------------------------------
statement ok
CREATE TABLE tmfp (
  a INT PRIMARY KEY,
  b INT,
  c JSON,
  FAMILY (a, b, c),
  INVERTED INDEX inverted (b, c)
)
----

mutate-index tmfp inverted MERGING
----

statement
INSERT INTO tmfp VALUES (1, 2, '{"a": "foo", "b": "bar"}'::json)
----

kvtrace
UPDATE tmfp SET b = 3, c = '{"a": "foobar", "c": "baz"}'::json
----
Scan /Table/110/{1-2} lock Exclusive (Block, Unreplicated)
Put /Table/110/1/1/0 -> /TUPLE/2:2:Int/3/
Del /Table/110/2/2/"a"/"foo"/1/0
Del /Table/110/2/2/"b"/"bar"/1/0
Put /Table/110/2/3/"a"/"foobar"/1/0 -> /BYTES/
Put /Table/110/2/3/"c"/"baz"/1/0 -> /BYTES/
