diff --git a/src/box/alter.cc b/src/box/alter.cc index 1a46a8177313f7c76d4f24206d95ded54ba683c0..4938b0d223221330aecd8d3f3da0d986d21ada22 100644 --- a/src/box/alter.cc +++ b/src/box/alter.cc @@ -260,7 +260,8 @@ alter_space_commit(struct trigger *trigger, void * /* event */) space_swap_index(alter->old_space, alter->new_space, index_id(old_index), - index_id(new_index)); + index_id(new_index), + false); } } /* @@ -563,7 +564,7 @@ ModifyIndex::commit(struct alter_space *alter) { /* Move the old index to the new place but preserve */ space_swap_index(alter->old_space, alter->new_space, - old_key_def->iid, new_key_def->iid); + old_key_def->iid, new_key_def->iid, true); } ModifyIndex::~ModifyIndex() diff --git a/src/box/box_lua.cc b/src/box/box_lua.cc index 01959b2f5ae5f75abef5b9aa2887dba279b7567e..868ec4fd93724fde3d6a7162a5fc628ba87a235f 100644 --- a/src/box/box_lua.cc +++ b/src/box/box_lua.cc @@ -714,7 +714,7 @@ static int lbox_index_tostring(struct lua_State *L) { Index *index = lua_checkindex(L, 1); - lua_pushfstring(L, "index %d", (int) index_id(index)); + lua_pushfstring(L, " index %d", (int) index_id(index)); return 1; } diff --git a/src/box/key_def.cc b/src/box/key_def.cc index 07d4b248261e3bcb41ba65c1cfe91f83926e5488..f224c7d013743c460a2f4d5c6ed2684ce458b096 100644 --- a/src/box/key_def.cc +++ b/src/box/key_def.cc @@ -45,7 +45,7 @@ key_def_new(uint32_t space_id, uint32_t iid, const char *name, tnt_raise(LoggedError, ER_MEMORY_ISSUE, sz, "struct key_def", "malloc"); } - int n = snprintf(def->name, sizeof(def->name) - 1, "%s", name); + int n = snprintf(def->name, sizeof(def->name), "%s", name); if (n >= sizeof(def->name)) { free(def); tnt_raise(LoggedError, ER_MODIFY_INDEX, diff --git a/src/box/lua/schema.lua b/src/box/lua/schema.lua index af74cdf35872c55bf07a1ed443f0eab5de575b29..744a4fb7fdeca3110e5343ab97b741342624b17f 100644 --- a/src/box/lua/schema.lua +++ b/src/box/lua/schema.lua @@ -93,7 +93,29 @@ box.schema.index.drop = function(space_id, index_id) end box.schema.index.rename = function(space_id, index_id, name) local _index = box.space[box.schema.INDEX_ID] - _index:update({space_id, index_id}, "=p", 3, name) + _index:update({space_id, index_id}, "=p", 2, name) +end +box.schema.index.alter = function(space_id, index_id, options) + if options == nil then + return + end + local ops = "" + local args = {} + local function add_op(op, opno) + if op then + ops = ops.."=p" + table.insert(args, opno) + table.insert(args, op) + end + end + add_op(options.id, 1) + add_op(options.name, 2) + add_op(options.type, 3) + if options.unique ~= nil then + add_op(options.unique and 1 or 0, 4) + end + local _index = box.space[box.schema.INDEX_ID] + _index:update({space_id, index_id}, ops, unpack(args)) end function box.schema.space.bless(space) @@ -165,6 +187,12 @@ function box.schema.space.bless(space) index_mt.drop = function(index) return box.schema.index.drop(index.n, index.id) end + index_mt.rename = function(index, name) + return box.schema.index.rename(index.n, index.id, name) + end + index_mt.alter= function(index, options) + return box.schema.index.alter(index.n, index.id, options) + end -- local space_mt = {} space_mt.len = function(space) return space.index[0]:len() end diff --git a/src/box/space.cc b/src/box/space.cc index 849053f1ffa54009e35f79799a66b63710a17e42..644f279fe105a2954a7ae6d811cf6fdc8978f01c 100644 --- a/src/box/space.cc +++ b/src/box/space.cc @@ -307,11 +307,17 @@ space_dump_def(const struct space *space, struct rlist *key_list) void space_swap_index(struct space *lhs, struct space *rhs, uint32_t lhs_id, - uint32_t rhs_id) + uint32_t rhs_id, bool keep_key_def) { Index *tmp = lhs->index_map[lhs_id]; lhs->index_map[lhs_id] = rhs->index_map[rhs_id]; rhs->index_map[rhs_id] = tmp; + if (keep_key_def) { + struct key_def *tmp = lhs->index_map[lhs_id]->key_def; + lhs->index_map[lhs_id]->key_def = + rhs->index_map[rhs_id]->key_def; + rhs->index_map[rhs_id]->key_def = tmp; + } } extern "C" void diff --git a/src/box/space.h b/src/box/space.h index 4932abf478943d2b192337da9ec126d81a178056..98ba9fb211440270bbd56e56e645a9514ce6810e 100644 --- a/src/box/space.h +++ b/src/box/space.h @@ -259,7 +259,7 @@ space_dump_def(const struct space *space, struct rlist *key_list); */ void space_swap_index(struct space *lhs, struct space *rhs, uint32_t lhs_id, - uint32_t rhs_id); + uint32_t rhs_id, bool keep_key_def); /** Rebuild index map in a space after a series of swap index. */ void diff --git a/test/box/alter_limits.result b/test/box/alter_limits.result index 0d958152857e473625e986c6e107cfc23e9cae98..85dbf7a9cbe6550c21167b07ffde72606c124e7b 100644 --- a/test/box/alter_limits.result +++ b/test/box/alter_limits.result @@ -133,7 +133,7 @@ s:select(0) ... s:select_range(0, 0, 0) --- -- error: '[string "-- schema.lua (internal file)..."]:174: attempt to index a nil +- error: '[string "-- schema.lua (internal file)..."]:202: attempt to index a nil value' ... s:delete(0) @@ -504,12 +504,169 @@ s:drop() --- ... -- index name, name manipulation --- box.schema.create_space(string.rep('t', box.schema.NAME_MAX)..'_') --- s = box.schema.create_space(string.rep('t', box.schema.NAME_MAX - 1)..'_') --- s.name --- s:drop() --- s = box.schema.create_space(string.rep('t', box.schema.NAME_MAX - 2)..'_') +s = box.schema.create_space('test') +--- +... +s:create_index('primary', 'hash') +--- +... +-- space cache is updated correctly +s.index[0].name +--- +- primary +... +s.index[0].id +--- +- 0 +... +s.index[0].type +--- +- HASH +... +s.index['primary'].name +--- +- primary +... +s.index['primary'].id +--- +- 0 +... +s.index['primary'].type +--- +- HASH +... +s.index.primary.name +--- +- primary +... +s.index.primary.id +--- +- 0 +... +-- other properties are preserved +s.index.primary.type +--- +- HASH +... +s.index.primary.unique +--- +- true +... +s.index.primary:rename('new') +--- +... +s.index[0].name +--- +- new +... +s.index.primary +--- +- null +... +s.index.new.name +--- +- new +... +-- too long name +s.index[0]:rename(string.rep('t', box.schema.NAME_MAX)..'_') +--- +- error: 'Can''t create or modify index 0 in space 512: index name is too long' +... +s.index[0].name +--- +- new +... +s.index[0]:rename(string.rep('t', box.schema.NAME_MAX - 1)..'_') +--- +... +s.index[0].name +--- +- ttttttttttttttttttttttttttttttt_ +... +s.index[0]:rename(string.rep('t', box.schema.NAME_MAX - 2)..'_') +--- +... +s.index[0].name +--- +- tttttttttttttttttttttttttttttt_ +... +s.index[0]:rename('primary') +--- +... +s.index.primary.name +--- +- primary +... +-- cleanup +s:drop() +--- +... -- modify index +s = box.schema.create_space('test') +--- +... +s:create_index('primary', 'hash') +--- +... +s.index.primary:alter({unique=false}) +--- +- error: 'Can''t create or modify index 0 in space 512: HASH index must be unique' +... +s.index.primary:alter({type='tree', unique=false, name='pk'}) +--- +... +s.index.primary +--- +- null +... +s.index.pk.type +--- +- TREE +... +s.index.pk.unique +--- +- false +... +s.index.pk:rename('primary') +--- +... +s:create_index('second', 'tree', { parts = { 1, 'str' } }) +--- +... +s.index.second.id +--- +- 1 +... +s:create_index('third', 'hash', { parts = { 2, 'num64' } }) +--- +... +s.index.third:rename('second') +--- +- error: Duplicate key exists in unique index 1 +... +s.index.third.id +--- +- 2 +... +s.index.second:drop() +--- +... +s.index.third:alter({id = 1, name = 'second'}) +--- +... +s.index.third +--- +- null +... +s.index.second.name +--- +- second +... +s.index.second.id +--- +- 1 +... +-- -- ------------ -- - alter unique -> non unique -- - alter index type diff --git a/test/box/alter_limits.test.lua b/test/box/alter_limits.test.lua index d57cfff7a54d914341e9c89447c803a226080fd6..53465d0540178936446799bfe0ba284164ac9b5f 100644 --- a/test/box/alter_limits.test.lua +++ b/test/box/alter_limits.test.lua @@ -191,13 +191,55 @@ s.index[0]:drop() -- cleanup s:drop() -- index name, name manipulation - --- box.schema.create_space(string.rep('t', box.schema.NAME_MAX)..'_') --- s = box.schema.create_space(string.rep('t', box.schema.NAME_MAX - 1)..'_') --- s.name --- s:drop() --- s = box.schema.create_space(string.rep('t', box.schema.NAME_MAX - 2)..'_') +s = box.schema.create_space('test') +s:create_index('primary', 'hash') +-- space cache is updated correctly +s.index[0].name +s.index[0].id +s.index[0].type +s.index['primary'].name +s.index['primary'].id +s.index['primary'].type +s.index.primary.name +s.index.primary.id +-- other properties are preserved +s.index.primary.type +s.index.primary.unique +s.index.primary:rename('new') +s.index[0].name +s.index.primary +s.index.new.name +-- too long name +s.index[0]:rename(string.rep('t', box.schema.NAME_MAX)..'_') +s.index[0].name +s.index[0]:rename(string.rep('t', box.schema.NAME_MAX - 1)..'_') +s.index[0].name +s.index[0]:rename(string.rep('t', box.schema.NAME_MAX - 2)..'_') +s.index[0].name +s.index[0]:rename('primary') +s.index.primary.name +-- cleanup +s:drop() -- modify index +s = box.schema.create_space('test') +s:create_index('primary', 'hash') +s.index.primary:alter({unique=false}) +s.index.primary:alter({type='tree', unique=false, name='pk'}) +s.index.primary +s.index.pk.type +s.index.pk.unique +s.index.pk:rename('primary') +s:create_index('second', 'tree', { parts = { 1, 'str' } }) +s.index.second.id +s:create_index('third', 'hash', { parts = { 2, 'num64' } }) +s.index.third:rename('second') +s.index.third.id +s.index.second:drop() +s.index.third:alter({id = 1, name = 'second'}) +s.index.third +s.index.second.name +s.index.second.id +-- -- ------------ -- - alter unique -> non unique -- - alter index type diff --git a/test/box/lua.result b/test/box/lua.result index fc98c621d4cfbe7455675b1fa361ac60435823c4..2ffce19b70815ba544b3d4268a8d683a68b81958 100644 --- a/test/box/lua.result +++ b/test/box/lua.result @@ -545,7 +545,7 @@ box.index.bind(0, 1) ... box.index.bind(0, 0) --- --index 0 +- index 0 ... #box.index.bind(0,0) ---