Tarantool development patches archive
 help / color / mirror / Atom feed
From: Vladimir Davydov <vdavydov.dev@gmail.com>
To: kostja@tarantool.org
Cc: tarantool-patches@freelists.org
Subject: [PATCH] alter: fix modification of primary key definition
Date: Fri,  6 Jul 2018 15:03:26 +0300	[thread overview]
Message-ID: <02e284d4e65535e32b195934026dc2d01a83e8fa.1530878427.git.vdavydov.dev@gmail.com> (raw)

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
---
https://github.com/tarantool/tarantool/issues/3508
https://github.com/tarantool/tarantool/commits/dv/gh-3508-fix-pk-def-alter

 src/box/index_def.c     | 2 +-
 test/vinyl/ddl.result   | 8 ++++++--
 test/vinyl/ddl.test.lua | 3 ++-
 3 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/src/box/index_def.c b/src/box/index_def.c
index 38f23e0f..9cda63c7 100644
--- a/src/box/index_def.c
+++ b/src/box/index_def.c
@@ -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 =
diff --git a/test/vinyl/ddl.result b/test/vinyl/ddl.result
index 16ee7097..708a9d6d 100644
--- a/test/vinyl/ddl.result
+++ b/test/vinyl/ddl.result
@@ -120,9 +120,13 @@ space:replace{1, 2}
 ---
 - [1, 2]
 ...
-space:get(2)
+space:replace{2, 2}
 ---
-- [1, 2]
+- [2, 2]
+...
+space:select()
+---
+- - [2, 2]
 ...
 space:drop()
 ---
diff --git a/test/vinyl/ddl.test.lua b/test/vinyl/ddl.test.lua
index 95dd5a11..cd623871 100644
--- a/test/vinyl/ddl.test.lua
+++ b/test/vinyl/ddl.test.lua
@@ -39,7 +39,8 @@ 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)
+space:replace{2, 2}
+space:select()
 space:drop()
 
 --
-- 
2.11.0

                 reply	other threads:[~2018-07-06 12:03 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=02e284d4e65535e32b195934026dc2d01a83e8fa.1530878427.git.vdavydov.dev@gmail.com \
    --to=vdavydov.dev@gmail.com \
    --cc=kostja@tarantool.org \
    --cc=tarantool-patches@freelists.org \
    --subject='Re: [PATCH] alter: fix modification of primary key definition' \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox