Skip to content
Snippets Groups Projects
Commit 3d584a69 authored by Vladimir Davydov's avatar Vladimir Davydov Committed by Dmitry Ivanov
Browse files

vinyl: fix handling of duplicate multikey entries in transaction write set

A multikey index stores a tuple once per each entry of the indexed
array field, excluding duplicates. For example, if the array field
equals {1, 3, 2, 3}, the tuple will be stored three times. Currently,
when a tuple with duplicate multikey entries is inserted into a
transaction write set, duplicates are overwritten as if they belonged
to different statements. Actually, this is pointless: we could just as
well skip them without trying to add to the write set. Besides, this
may break the assumptions taken by various optimizations, resulting in
anomalies. Consider the following example:

```lua
local s = box.schema.space.create('test', {engine = 'vinyl'})
s:create_index('primary')
s:create_index('secondary', {parts = {{'[2][*]', 'unsigned'}}})
s:replace({1, {10, 10}})
s:update({1}, {{'=', 2, {10}}})
```

It will insert the following entries to the transaction write set
of the secondary index:

 1. REPLACE {10, 1} [overwritten by no.2]
 2. REPLACE {10, 1} [overwritten by no.3]
 3. DELETE {10, 1} [turned into no-op as REPLACE + DELETE]
 4. DELETE {10, 1} [overwritten by no.5]
 5. REPLACE {10, 1} [turned into no-op as DELETE + REPLACE]

(1-2 correspond to `replace()` and 3-5 to `delete()`)

As a result, tuple {1, {10}} will be lost forever.

Let's fix this issue by silently skipping duplicate multikey entries
added to a transaction write set. After the fix, the example above
will produce the following write set entries:

 1. REPLACE{10, 1} [overwritten by no.2]
 2. DELETE{10, 1} [turned into no-op as REPLACE + DELETE]
 3. REPLACE{10, 1} [committed]

(1 corresponds to `replace()` and 2-3 to `delete()`)

Closes #10869
Closes #10870

NO_DOC=bug fix

(cherry picked from commit 1869dce15d9a797391e45df75507078d91f1651e)
parent 8f7bae8c
No related branches found
No related tags found
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment