Skip to content
Snippets Groups Projects
Commit 3f14e319 authored by Vladimir Davydov's avatar Vladimir Davydov Committed by Konstantin Osipov
Browse files

alter: fix modification of primary key definition

If pk_def passed to index_def_new() is not NULL, the function will merge
it with the given key_def to create index cmp_def, no matter if the
index is primary or secondary. When an index is altered, we call
index_def_new() to create the new definition, passing the primary key
definition of the altered space for pk_def. If it is the primary index
that is altered, we will pass the definition of the old primary index
and index_def_new() will happily merge it with the new index definition,
resulting in invalid index_def::cmp_def. This doesn't affect memtx, as
memtx doesn't use cmp_def for unique indexes, but it does affect vinyl
in a peculiar way:

  tarantool> _ = box.schema.space.create('test', {engine = 'vinyl'})
  ---
  ...

  tarantool> _ = box.space.test:create_index('pk')
  ---
  ...

  tarantool> _ = box.space.test.index.pk:alter{parts = {2, 'unsigned'}}
  ---
  ...

  tarantool> _ = box.space.test:replace{1, 1}
  ---
  ...

  tarantool> _ = box.space.test:replace{2, 1}
  ---
  ...

  tarantool> box.space.test:select()
  ---
  - - [1, 1]
    - [2, 1]
  ...

(expected: [2, 1])

Fix this by making index_def_new() merge key_def with pk_def only for
secondary indexes.

Closes #3508
parent 1318ac44
No related branches found
No related tags found
No related merge requests found
......@@ -86,7 +86,7 @@ index_def_new(uint32_t space_id, uint32_t iid, const char *name,
return NULL;
}
def->key_def = key_def_dup(key_def);
if (pk_def != NULL) {
if (iid != 0) {
def->cmp_def = key_def_merge(key_def, pk_def);
if (! opts->is_unique) {
def->cmp_def->unique_part_count =
......
......@@ -120,9 +120,14 @@ space:replace{1, 2}
---
- [1, 2]
...
space:get(2)
-- gh-3508 - Altering primary index of a vinyl space doesn't work as expected
space:replace{2, 2}
---
- [1, 2]
- [2, 2]
...
space:select()
---
- - [2, 2]
...
space:drop()
---
......
......@@ -39,7 +39,9 @@ box.snapshot()
while pk:stat().disk.compact.count == 0 do fiber.sleep(0.01) end
pk:alter{parts = {2, 'unsigned'}} -- success: space is empty now
space:replace{1, 2}
space:get(2)
-- gh-3508 - Altering primary index of a vinyl space doesn't work as expected
space:replace{2, 2}
space:select()
space:drop()
--
......
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