# ---------------------------------------------------------
# Index With Delete Preserving Encoding
# ---------------------------------------------------------
statement
CREATE TABLE ti (
    a INT PRIMARY KEY,
    b INT,
    c INT,
    FAMILY (a, b, c),
    INDEX index_to_mutate (b, c)
);
----

mutate-index ti index_to_mutate WRITE_ONLY use_delete_preserving_encoding=true
----

statement
INSERT INTO ti VALUES (1, 2, 100), (2, 3, 200), (3, 4, 300)
----

kvtrace
UPSERT INTO ti VALUES (1, 3, 101)
----
Scan /Table/106/1/1/0 lock Exclusive (Block, Unreplicated)
Put /Table/106/1/1/0 -> /TUPLE/2:2:Int/3/1:3:Int/101
Put (delete) /Table/106/2/2/100/1/0
Put /Table/106/2/3/101/1/0 -> /BYTES/0x0a0103

# ---------------------------------------------------------
# Partial Index With Delete Preserving Encoding
# ---------------------------------------------------------
statement
CREATE TABLE tpi (
    a INT PRIMARY KEY,
    b INT,
    c STRING,
    FAMILY (a, b, c),
    INDEX partial (c) WHERE a > b AND c IN ('foo', 'foobar')
);
----

mutate-index tpi partial WRITE_ONLY use_delete_preserving_encoding=true
----

statement
INSERT INTO tpi VALUES (1, 2, 'bar'), (2, 3, 'bar'), (3, 4, 'foo')
----

# Upsert a row that doesn't match the partial index.
kvtrace
UPSERT INTO tpi VALUES (1, 3, 'bar')
----
Scan /Table/107/1/1/0 lock Exclusive (Block, Unreplicated)
Put /Table/107/1/1/0 -> /TUPLE/2:2:Int/3/1:3:Bytes/bar

# Upsert a row that didn't match the partial index before but matches after.
kvtrace
UPSERT INTO tpi VALUES (3, 2, 'foo')
----
Scan /Table/107/1/3/0 lock Exclusive (Block, Unreplicated)
Put /Table/107/1/3/0 -> /TUPLE/2:2:Int/2/1:3:Bytes/foo
Put /Table/107/2/"foo"/3/0 -> /BYTES/0x0a0103

# Upsert a row that matches the partial index before and after, but
# the index entry doesn't change. While the index entry doesn't
# change, we still write it out to a delete preserving index.
kvtrace
UPSERT INTO tpi VALUES (3, 1, 'foo')
----
Scan /Table/107/1/3/0 lock Exclusive (Block, Unreplicated)
Put /Table/107/1/3/0 -> /TUPLE/2:2:Int/1/1:3:Bytes/foo
Put /Table/107/2/"foo"/3/0 -> /BYTES/0x0a0103

# Upsert a row that matches the partial index before and after, and the index
# entry changes.
kvtrace
UPSERT INTO tpi VALUES (3, 2, 'foobar')
----
Scan /Table/107/1/3/0 lock Exclusive (Block, Unreplicated)
Put /Table/107/1/3/0 -> /TUPLE/2:2:Int/2/1:3:Bytes/foobar
Put (delete) /Table/107/2/"foo"/3/0
Put /Table/107/2/"foobar"/3/0 -> /BYTES/0x0a0103

# Upsert a row that matches the partial index before but not after.
kvtrace
UPSERT INTO tpi VALUES (3, 1, 'baz')
----
Scan /Table/107/1/3/0 lock Exclusive (Block, Unreplicated)
Put /Table/107/1/3/0 -> /TUPLE/2:2:Int/1/1:3:Bytes/baz
Put (delete) /Table/107/2/"foobar"/3/0

# ---------------------------------------------------------
# Expression Index With Delete Preserving Encoding
# ---------------------------------------------------------
statement
CREATE TABLE tei (
  k INT PRIMARY KEY,
  a INT,
  b INT,
  FAMILY (k, a, b),
  INDEX t_a_plus_b_idx ((a + b))
)
----

mutate-index tei t_a_plus_b_idx WRITE_ONLY use_delete_preserving_encoding=true
----

statement
INSERT INTO tei VALUES (1, 2, 100), (2, 3, 200), (3, 4, 300)
----

# Upsert a row which changes the index entry.
kvtrace
UPSERT INTO tei VALUES (1, 3, 500)
----
Scan /Table/108/1/1/0
Put /Table/108/1/1/0 -> /TUPLE/2:2:Int/3/1:3:Int/500
Put (delete) /Table/108/2/102/1/0
Put /Table/108/2/503/1/0 -> /BYTES/0x0a0103

# Upsert a row with different values without changing the index entry.
kvtrace
UPSERT INTO tei VALUES (1, 4, 499)
----
Scan /Table/108/1/1/0
Put /Table/108/1/1/0 -> /TUPLE/2:2:Int/4/1:3:Int/499
Put /Table/108/2/503/1/0 -> /BYTES/0x0a0103

# Upsert a row with a different primary key with the same index entry.
kvtrace
UPSERT INTO tei VALUES (2, 4, 499)
----
Scan /Table/108/1/2/0
Put /Table/108/1/2/0 -> /TUPLE/2:2:Int/4/1:3:Int/499
Put (delete) /Table/108/2/203/2/0
Put /Table/108/2/503/2/0 -> /BYTES/0x0a0103

# ---------------------------------------------------------
# Inverted Index With Delete Preserving Encoding
# ---------------------------------------------------------

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

mutate-index tii inverted WRITE_ONLY use_delete_preserving_encoding=true
----

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

# Upsert a row that has 1 new entry and 1 removed entry in the index.
kvtrace
UPSERT INTO tii VALUES (1, ARRAY[1, 2, 2, NULL, 4, 4])
----
Scan /Table/109/1/1/0 lock Exclusive (Block, Unreplicated)
Put /Table/109/1/1/0 -> /TUPLE/
Put (delete) /Table/109/2/NULL/1/0
Put (delete) /Table/109/2/1/1/0
Put (delete) /Table/109/2/2/1/0
Put (delete) /Table/109/2/3/1/0
Put /Table/109/2/NULL/1/0 -> /BYTES/0x0a0103
Put /Table/109/2/1/1/0 -> /BYTES/0x0a0103
Put /Table/109/2/2/1/0 -> /BYTES/0x0a0103
Put /Table/109/2/4/1/0 -> /BYTES/0x0a0103

# ---------------------------------------------------------
# Multicolumn Inverted Index With Delete Preserving Encoding
# ---------------------------------------------------------
statement
CREATE TABLE tmi (
  a INT PRIMARY KEY,
  b INT,
  c JSON,
  FAMILY (a, b, c),
  INVERTED INDEX inverted (b, c)
)
----

mutate-index tmi inverted WRITE_ONLY use_delete_preserving_encoding=true
----

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

kvtrace
UPSERT INTO tmi VALUES (1, 3, '{"a": "foobar", "c": "baz"}'::json)
----
Scan /Table/110/1/1/0 lock Exclusive (Block, Unreplicated)
Put /Table/110/1/1/0 -> /TUPLE/2:2:Int/3/
Put (delete) /Table/110/2/2/"a"/"foo"/1/0
Put (delete) /Table/110/2/2/"b"/"bar"/1/0
Put /Table/110/2/3/"a"/"foobar"/1/0 -> /BYTES/0x0a0103
Put /Table/110/2/3/"c"/"baz"/1/0 -> /BYTES/0x0a0103

# ---------------------------------------------------------
# Unique Index With Delete Preserving Encoding
# ---------------------------------------------------------
statement
CREATE TABLE tui (
    a INT PRIMARY KEY,
    b INT,
    c INT,
    FAMILY (a, b, c),
    UNIQUE INDEX index_to_mutate (b, c)
);
----

mutate-index tui index_to_mutate WRITE_ONLY use_delete_preserving_encoding=true
----

statement
INSERT INTO tui VALUES (1, 2, 100), (2, 3, 200), (3, 4, 300)
----

statement
DELETE FROM tui WHERE a = 2
----

kvtrace
UPSERT INTO tui VALUES (1, 3, 200)
----
Scan /Table/111/1/1/0 lock Exclusive (Block, Unreplicated)
Put /Table/111/1/1/0 -> /TUPLE/2:2:Int/3/1:3:Int/200
Put (delete) /Table/111/2/2/100/0
Put /Table/111/2/3/200/0 -> /BYTES/0x0a020389

# ---------------------------------------------------------------
# Multi Column Family Table With Delete Preserving Encoding Index
# ---------------------------------------------------------------
statement
CREATE TABLE mcf (
    a INT PRIMARY KEY,
    b INT,
    c STRING,
    FAMILY (a, b),
    FAMILY (c),
    INDEX multi_fam (b)
);
----

mutate-index mcf multi_fam WRITE_ONLY use_delete_preserving_encoding=true
----

statement
INSERT INTO mcf VALUES (1, 2, 'bar'), (2, 3, 'bar'), (3, 4, 'foo')
----

# Upsert a row that changes the first family but not the second
kvtrace
UPSERT INTO mcf VALUES (1, 1, 'baz')
----
Scan /Table/112/1/{1-2} lock Exclusive (Block, Unreplicated)
Put /Table/112/1/1/0 -> /TUPLE/2:2:Int/1
Put /Table/112/1/1/1/1 -> /BYTES/baz
Put (delete) /Table/112/2/2/1/0
Put /Table/112/2/1/1/0 -> /BYTES/0x0a0103

# Upsert a row that changes the second family but not the first
kvtrace
UPSERT INTO mcf VALUES (1, 1, 'bat')
----
Scan /Table/112/1/{1-2} lock Exclusive (Block, Unreplicated)
Put /Table/112/1/1/0 -> /TUPLE/2:2:Int/1
Put /Table/112/1/1/1/1 -> /BYTES/bat
Put /Table/112/2/1/1/0 -> /BYTES/0x0a0103
