diff --git a/include/errcode.h b/include/errcode.h index 256b1e2c89a04ef7077802bd0a6289015585d2d9..685d612a3fd12d880c556b631293f2f6616cef2b 100644 --- a/include/errcode.h +++ b/include/errcode.h @@ -84,7 +84,7 @@ enum { TNT_ERRMSG_MAX = 512 }; /* 29 */_(ER_LAST_DROP, 2, "Can't drop the primary key in a system space, space id %u") \ /* 30 */_(ER_DROP_PRIMARY_KEY, 2, "Can't drop primary key in space %u while secondary keys exist") \ /* 31 */_(ER_SPACE_ARITY, 2, "Tuple field count %u does not match space %u arity %u") \ - /* 32 */_(ER_UNUSED32, 2, "Unused32") \ + /* 32 */_(ER_INDEX_ARITY, 2, "Tuple field count %u is less than required by a defined index (expected %u)") \ /* 33 */_(ER_UNUSED33, 2, "Unused33") \ /* 34 */_(ER_UNUSED34, 2, "Unused34") \ /* 35 */_(ER_UNUSED35, 2, "Unused35") \ diff --git a/src/box/alter.cc b/src/box/alter.cc index f60fd1030487f5126a3187cda4648b58778a74ce..013d3e0e516cb2f3e950d33a0922c756fc97a0e3 100644 --- a/src/box/alter.cc +++ b/src/box/alter.cc @@ -69,8 +69,9 @@ key_def_new_from_tuple(struct tuple *tuple) enum index_type type = STR2ENUM(index_type, type_str); uint32_t is_unique = tuple_field_u32(tuple, INDEX_IS_UNIQUE); uint32_t part_count = tuple_field_u32(tuple, INDEX_PART_COUNT); + const char *name = tuple_field_cstr(tuple, NAME); - struct key_def *key_def = key_def_new(index_id, type, + struct key_def *key_def = key_def_new(id, index_id, name, type, is_unique > 0, part_count); auto scoped_guard = make_scoped_guard([=] { key_def_delete(key_def); }); @@ -88,7 +89,7 @@ key_def_new_from_tuple(struct tuple *tuple) STR2ENUM(field_type, field_type_str); key_def_set_part(key_def, i, fieldno, field_type); } - key_def_check(id, key_def); + key_def_check(key_def); scoped_guard.is_active = false; return key_def; } @@ -259,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); } } /* @@ -562,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->id, new_key_def->id); + old_key_def->iid, new_key_def->iid, true); } ModifyIndex::~ModifyIndex() @@ -661,7 +663,7 @@ AddIndex::prepare(struct alter_space *alter) void AddIndex::alter_def(struct alter_space *alter) { - rlist_add_entry(&alter->key_list, new_key_def, link); + rlist_add_tail_entry(&alter->key_list, new_key_def, link); } /** @@ -716,7 +718,7 @@ AddIndex::alter(struct alter_space *alter) * Possible both during and after recovery. */ if (alter->new_space->engine.state == READY_NO_KEYS) { - if (new_key_def->id == 0) { + if (new_key_def->iid == 0) { /* * Adding a primary key: bring the space * up to speed with the current recovery @@ -745,10 +747,10 @@ AddIndex::alter(struct alter_space *alter) return; } Index *pk = index_find(alter->old_space, 0); - Index *new_index = index_find(alter->new_space, new_key_def->id); + Index *new_index = index_find(alter->new_space, new_key_def->iid); /* READY_PRIMARY_KEY is a state that only occurs during WAL recovery. */ if (alter->new_space->engine.state == READY_PRIMARY_KEY) { - if (new_key_def->id == 0) { + if (new_key_def->iid == 0) { /* * Bulk rebuild of the new primary key * from old primary key - it is safe to do @@ -780,11 +782,17 @@ AddIndex::alter(struct alter_space *alter) new_index->endBuild(); /* Build the new index. */ struct tuple *tuple; + struct tuple_format *format = alter->new_space->format; + char *field_map = ((char *) palloc(fiber->gc_pool, + format->field_map_size) + + format->field_map_size); while ((tuple = it->next(it))) { /* - * @todo: - * tuple_format_validate(alter->new_space->format, - * tuple) + * Check that the tuple is OK according to the + * new format. + */ + tuple_init_field_map(format, tuple, (uint32_t *) field_map); + /* * @todo: better message if there is a duplicate. */ struct tuple *old_tuple = @@ -994,10 +1002,10 @@ on_replace_dd_index(struct trigger * /* trigger */, void *event) struct tuple *old_tuple = txn->old_tuple; struct tuple *new_tuple = txn->new_tuple; uint32_t id = tuple_field_u32(old_tuple ? old_tuple : new_tuple, ID); - uint32_t index_id = tuple_field_u32(old_tuple ? old_tuple : new_tuple, - INDEX_ID); + uint32_t iid = tuple_field_u32(old_tuple ? old_tuple : new_tuple, + INDEX_ID); struct space *old_space = space_find(id); - Index *old_index = space_index(old_space, index_id); + Index *old_index = space_index(old_space, iid); struct alter_space *alter = alter_space_new(); auto scoped_guard = make_scoped_guard([=] { alter_space_delete(alter); }); diff --git a/src/box/box_lua.cc b/src/box/box_lua.cc index 7d43c1c28381782d0bf61ccac063708e4ff4540b..868ec4fd93724fde3d6a7162a5fc628ba87a235f 100644 --- a/src/box/box_lua.cc +++ b/src/box/box_lua.cc @@ -688,7 +688,7 @@ lua_checkindex(struct lua_State *L, int i) } static int -lbox_index_new(struct lua_State *L) +lbox_index_bind(struct lua_State *L) { uint32_t id = (uint32_t) luaL_checkint(L, 1); /* get space id */ uint32_t iid = (uint32_t) luaL_checkint(L, 2); /* get index id in */ @@ -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; } @@ -976,7 +976,7 @@ static const struct luaL_reg lbox_index_meta[] = { }; static const struct luaL_reg indexlib [] = { - {"new", lbox_index_new}, + {"bind", lbox_index_bind}, {NULL, NULL} }; diff --git a/src/box/box_lua_space.cc b/src/box/box_lua_space.cc index a3ea0ebe4433ba06a83edd89391d1e387596f304..edc3c5aa28748a7a97058873ea09454ded864188 100644 --- a/src/box/box_lua_space.cc +++ b/src/box/box_lua_space.cc @@ -93,16 +93,23 @@ lbox_fillspace(struct lua_State *L, struct space *space, int i) if (index == NULL) continue; struct key_def *key_def = index->key_def; - lua_pushnumber(L, key_def->id); + lua_pushnumber(L, key_def->iid); lua_newtable(L); /* space.index[i] */ - lua_pushstring(L, "unique"); lua_pushboolean(L, key_def->is_unique); - lua_settable(L, -3); + lua_setfield(L, -2, "unique"); - lua_pushstring(L, "type"); lua_pushstring(L, index_type_strs[key_def->type]); - lua_settable(L, -3); + lua_setfield(L, -2, "type"); + + lua_pushnumber(L, key_def->iid); + lua_setfield(L, -2, "id"); + + lua_pushnumber(L, key_def->space_id); + lua_setfield(L, -2, "n"); + + lua_pushstring(L, key_def->name); + lua_setfield(L, -2, "name"); lua_pushstring(L, "key_field"); lua_newtable(L); @@ -111,21 +118,21 @@ lbox_fillspace(struct lua_State *L, struct space *space, int i) lua_pushnumber(L, j); lua_newtable(L); - lua_pushstring(L, "type"); lua_pushstring(L, field_type_strs[key_def->parts[j].type]); - lua_settable(L, -3); + lua_setfield(L, -2, "type"); - lua_pushstring(L, "fieldno"); lua_pushnumber(L, key_def->parts[j].fieldno); - lua_settable(L, -3); + lua_setfield(L, -2, "fieldno"); - lua_settable(L, -3); + lua_settable(L, -3); /* index[i].key_field[j] */ } - lua_settable(L, -3); /* index[i].key_field */ + lua_settable(L, -3); /* space.index[i].key_field */ - lua_settable(L, -3); /* space.index[i] */ + lua_settable(L, -3); /* space.index[i] */ + lua_rawgeti(L, -1, key_def->iid); + lua_setfield(L, -2, key_def->name); } lua_pop(L, 1); /* pop the index field */ @@ -175,9 +182,7 @@ box_lua_space_new(struct lua_State *L, struct space *space) lua_settable(L, -4); } lbox_fillspace(L, space, lua_gettop(L)); - lua_pushstring(L, space_name(space)); - lua_insert(L, -2); - lua_rawset(L, -3); + lua_setfield(L, -2, space_name(space)); lua_pop(L, 2); /* box, space */ } diff --git a/src/box/index.h b/src/box/index.h index a90b5c71c5aa90fb266dc572c83b8ee8f1ec2832..860fb0e01481d97243788884b82f12f1b89a28e0 100644 --- a/src/box/index.h +++ b/src/box/index.h @@ -232,7 +232,7 @@ replace_check_dup(struct tuple *old_tuple, struct tuple *dup_tuple, static inline uint32_t index_id(const Index *index) { - return index->key_def->id; + return index->key_def->iid; } /** True if this index is a primary key. */ diff --git a/src/box/key_def.cc b/src/box/key_def.cc index 0fb0320ded756048cdf9c6dfcd81ba55bce4b438..03d363f07e9e42b38fd876b2c6c4f5f2979973ee 100644 --- a/src/box/key_def.cc +++ b/src/box/key_def.cc @@ -28,23 +28,33 @@ */ #include "key_def.h" #include <stdlib.h> +#include <stdio.h> #include "exception.h" const char *field_type_strs[] = {"UNKNOWN", "NUM", "NUM64", "STR", "\0"}; STRS(index_type, ENUM_INDEX_TYPE); struct key_def * -key_def_new(uint32_t id, enum index_type type, bool is_unique, - uint32_t part_count) +key_def_new(uint32_t space_id, uint32_t iid, const char *name, + enum index_type type, bool is_unique, uint32_t part_count) { uint32_t parts_size = sizeof(struct key_part) * part_count; size_t sz = parts_size + sizeof(struct key_def); struct key_def *def = (struct key_def *) malloc(sz); - if (def == NULL) + if (def == NULL) { tnt_raise(LoggedError, ER_MEMORY_ISSUE, sz, "struct key_def", "malloc"); + } + int n = snprintf(def->name, sizeof(def->name), "%s", name); + if (n >= sizeof(def->name)) { + free(def); + tnt_raise(LoggedError, ER_MODIFY_INDEX, + (unsigned) iid, (unsigned) space_id, + "index name is too long"); + } def->type = type; - def->id = id; + def->space_id = space_id; + def->iid = iid; def->is_unique = is_unique; def->part_count = part_count; @@ -79,8 +89,10 @@ key_part_cmp(const struct key_part *parts1, uint32_t part_count1, int key_def_cmp(const struct key_def *key1, const struct key_def *key2) { - if (key1->id != key2->id) - return key1->id < key2->id ? -1 : 1; + if (key1->iid != key2->iid) + return key1->iid < key2->iid ? -1 : 1; + if (strcmp(key1->name, key2->name)) + return strcmp(key1->name, key2->name); if (key1->type != key2->type) return (int) key1->type < (int) key2->type ? -1 : 1; if (key1->is_unique != key2->is_unique) @@ -91,11 +103,11 @@ key_def_cmp(const struct key_def *key1, const struct key_def *key2) } void -key_list_del_key(struct rlist *key_list, uint32_t id) +key_list_del_key(struct rlist *key_list, uint32_t iid) { struct key_def *key; rlist_foreach_entry(key, key_list, link) { - if (key->id == id) { + if (key->iid == iid) { rlist_del_entry(key, link); return; } @@ -104,32 +116,43 @@ key_list_del_key(struct rlist *key_list, uint32_t id) } void -key_def_check(uint32_t id, struct key_def *key_def) +key_def_check(struct key_def *key_def) { - if (key_def->id >= BOX_INDEX_MAX) { + if (key_def->iid >= BOX_INDEX_MAX) { tnt_raise(ClientError, ER_MODIFY_INDEX, - (unsigned) key_def->id, (unsigned) id, + (unsigned) key_def->iid, + (unsigned) key_def->space_id, "index id too big"); } + if (key_def->iid == 0 && key_def->is_unique == false) { + tnt_raise(ClientError, ER_MODIFY_INDEX, + (unsigned) key_def->iid, + (unsigned) key_def->space_id, + "primary key must be unique"); + } if (key_def->part_count == 0) { tnt_raise(ClientError, ER_MODIFY_INDEX, - (unsigned) key_def->id, (unsigned) id, + (unsigned) key_def->iid, + (unsigned) key_def->space_id, "part count must be positive"); } if (key_def->part_count > BOX_INDEX_PART_MAX) { tnt_raise(ClientError, ER_MODIFY_INDEX, - (unsigned) key_def->id, (unsigned) id, + (unsigned) key_def->iid, + (unsigned) key_def->space_id, "too many key parts"); } for (uint32_t i = 0; i < key_def->part_count; i++) { if (key_def->parts[i].type == field_type_MAX) { tnt_raise(ClientError, ER_MODIFY_INDEX, - (unsigned) key_def->id, (unsigned) id, + (unsigned) key_def->iid, + (unsigned) key_def->space_id, "unknown field type"); } if (key_def->parts[i].fieldno > BOX_INDEX_FIELD_MAX) { tnt_raise(ClientError, ER_MODIFY_INDEX, - (unsigned) key_def->id, (unsigned) id, + (unsigned) key_def->iid, + (unsigned) key_def->space_id, "field no is too big"); } for (uint32_t j = 0; j < i; j++) { @@ -140,8 +163,8 @@ key_def_check(uint32_t id, struct key_def *key_def) if (key_def->parts[i].fieldno == key_def->parts[j].fieldno) { tnt_raise(ClientError, ER_MODIFY_INDEX, - (unsigned) key_def->id, - (unsigned) id, + (unsigned) key_def->iid, + (unsigned) key_def->space_id, "same key part is indexed twice"); } } @@ -150,7 +173,8 @@ key_def_check(uint32_t id, struct key_def *key_def) case HASH: if (! key_def->is_unique) { tnt_raise(ClientError, ER_MODIFY_INDEX, - (unsigned) key_def->id, (unsigned) id, + (unsigned) key_def->iid, + (unsigned) key_def->space_id, "HASH index must be unique"); } break; @@ -160,18 +184,21 @@ key_def_check(uint32_t id, struct key_def *key_def) case BITSET: if (key_def->part_count != 1) { tnt_raise(ClientError, ER_MODIFY_INDEX, - (unsigned) key_def->id, (unsigned) id, - "BITSET index key can not be multipart"); + (unsigned) key_def->iid, + (unsigned) key_def->space_id, + "BITSET index key can not be multipart"); } if (key_def->is_unique) { tnt_raise(ClientError, ER_MODIFY_INDEX, - (unsigned) key_def->id, (unsigned) id, + (unsigned) key_def->iid, + (unsigned) key_def->space_id, "BITSET can not be unique"); } break; default: tnt_raise(ClientError, ER_INDEX_TYPE, - (unsigned) key_def->id, (unsigned) id); + (unsigned) key_def->iid, + (unsigned) key_def->space_id); break; } } diff --git a/src/box/key_def.h b/src/box/key_def.h index 10daefc5821bd1ec9a3d6c83c91ec0226d531ebd..56bfc26dff50a2472b9bcd69ad2638bf5044fdc2 100644 --- a/src/box/key_def.h +++ b/src/box/key_def.h @@ -82,7 +82,11 @@ struct key_def { /* A link in key list. */ struct rlist link; /** Ordinal index number in the index array. */ - uint32_t id; + uint32_t iid; + /* Space id. */ + uint32_t space_id; + /** Index name. */ + char name[BOX_NAME_MAX + 1]; /** The size of the 'parts' array. */ uint32_t part_count; /** Index type. */ @@ -95,13 +99,14 @@ struct key_def { /** Initialize a pre-allocated key_def. */ struct key_def * -key_def_new(uint32_t id, enum index_type type, - bool is_unique, uint32_t part_count); +key_def_new(uint32_t space_id, uint32_t iid, const char *name, + enum index_type type, bool is_unique, uint32_t part_count); static inline struct key_def * key_def_dup(struct key_def *def) { - struct key_def *dup = key_def_new(def->id, def->type, def->is_unique, + struct key_def *dup = key_def_new(def->space_id, def->iid, def->name, + def->type, def->is_unique, def->part_count); if (dup) { memcpy(dup->parts, def->parts, @@ -146,8 +151,8 @@ key_part_cmp(const struct key_part *parts1, uint32_t part_count1, /** * One key definition is greater than the other if it's id is - * greater, it's index type is greater (HASH < TREE < BITSET) - * or its key part array is greater. + * greater, it's name is greater, it's index type is greater + * (HASH < TREE < BITSET) or its key part array is greater. */ int key_def_cmp(const struct key_def *key1, const struct key_def *key2); @@ -175,7 +180,7 @@ key_list_del_key(struct rlist *key_list, uint32_t id); * @param type_str type name (to produce a nice error) */ void -key_def_check(uint32_t id, struct key_def *key_def); +key_def_check(struct key_def *key_def); /** Space metadata. */ struct space_def { diff --git a/src/box/lua/schema.lua b/src/box/lua/schema.lua index 04bdcf82dd2215b22d8f5f1a0fc9893e9f1587cb..f92066fb79e468691642401ccac3989f91ed2e30 100644 --- a/src/box/lua/schema.lua +++ b/src/box/lua/schema.lua @@ -91,6 +91,32 @@ box.schema.index.drop = function(space_id, index_id) local _index = box.space[box.schema.INDEX_ID] _index:delete(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", 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) local index_mt = {} @@ -158,9 +184,18 @@ function box.schema.space.bless(space) end return unpack(range) end + index_mt.select = function(index, ...) + return box.select(index.n, index.id, ...) + end 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 @@ -219,10 +254,10 @@ function box.schema.space.bless(space) setmetatable(space, space_mt) if type(space.index) == 'table' and space.enabled then for j, index in pairs(space.index) do - rawset(index, 'idx', box.index.new(space.n, j)) - rawset(index, 'id', j) - rawset(index, 'n', space.n) - setmetatable(index, index_mt) + if type(j) == 'number' then + rawset(index, 'idx', box.index.bind(space.n, j)) + setmetatable(index, index_mt) + end end end end diff --git a/src/box/schema.cc b/src/box/schema.cc index 967d48d0880ff230d36ba0ab377e1d1097480f0f..065f28ec10c5dfc5de59a2d76afa3f00255fe820 100644 --- a/src/box/schema.cc +++ b/src/box/schema.cc @@ -72,6 +72,13 @@ space_by_id(uint32_t id) return (struct space *) mh_i32ptr_node(spaces, space)->val; } +extern "C" const char * +space_name_by_id(uint32_t id) +{ + struct space *space = space_by_id(id); + return space ? space_name(space) : ""; +} + /** * Visit all spaces and apply 'func'. */ @@ -210,25 +217,30 @@ schema_init() * (and re-created) first. */ /* _schema - key/value space with schema description */ - struct space_def space_def = { SC_SCHEMA_ID, 0, "_schema" }; - struct key_def *key_def = key_def_new(0 /* id */, + struct space_def def = { SC_SCHEMA_ID, 0, "_schema" }; + struct key_def *key_def = key_def_new(def.id, + 0 /* index id */, + "primary", /* name */ TREE /* index type */, true /* unique */, 1 /* part count */); key_def_set_part(key_def, 0 /* part no */, 0 /* field no */, STRING); - (void) sc_space_new(&space_def, key_def, NULL); + (void) sc_space_new(&def, key_def, NULL); /* _space - home for all spaces. */ - space_def.id = SC_SPACE_ID; - snprintf(space_def.name, sizeof(space_def.name), "_space"); + key_def->space_id = def.id = SC_SPACE_ID; + snprintf(def.name, sizeof(def.name), "_space"); key_def_set_part(key_def, 0 /* part no */, 0 /* field no */, NUM); - (void) sc_space_new(&space_def, key_def, - &alter_space_on_replace_space); + (void) sc_space_new(&def, key_def, &alter_space_on_replace_space); key_def_delete(key_def); /* _index - definition of indexes in all spaces */ - key_def = key_def_new(0 /* id */, + def.id = SC_INDEX_ID; + snprintf(def.name, sizeof(def.name), "_index"); + key_def = key_def_new(def.id, + 0 /* index id */, + "primary", TREE /* index type */, true /* unique */, 2 /* part count */); @@ -236,10 +248,7 @@ schema_init() key_def_set_part(key_def, 0 /* part no */, 0 /* field no */, NUM); /* index no */ key_def_set_part(key_def, 1 /* part no */, 1 /* field no */, NUM); - space_def.id = SC_INDEX_ID; - snprintf(space_def.name, sizeof(space_def.name), "_index"); - (void) sc_space_new(&space_def, key_def, - &alter_space_on_replace_index); + (void) sc_space_new(&def, key_def, &alter_space_on_replace_index); key_def_delete(key_def); } diff --git a/src/box/schema.h b/src/box/schema.h index a97076ce073981b80637443983185228e9e9a6a6..76873bb9495151197e1a3405bc988447b2508ea4 100644 --- a/src/box/schema.h +++ b/src/box/schema.h @@ -60,6 +60,10 @@ space_foreach(void (*func)(struct space *sp, void *udata), void *udata); extern "C" struct space * space_by_id(uint32_t id); +/** No-throw conversion of space id to space name */ +extern "C" const char * +space_name_by_id(uint32_t id); + static inline struct space * space_find(uint32_t id) { diff --git a/src/box/space.cc b/src/box/space.cc index 2b08ad60366a872a9a4f5ab6495f017e3562b14f..644f279fe105a2954a7ae6d811cf6fdc8978f01c 100644 --- a/src/box/space.cc +++ b/src/box/space.cc @@ -52,7 +52,7 @@ space_new(struct space_def *def, struct rlist *key_list) struct key_def *key_def; rlist_foreach_entry(key_def, key_list, link) { index_count++; - index_id_max = MAX(index_id_max, key_def->id); + index_id_max = MAX(index_id_max, key_def->iid); } size_t sz = sizeof(struct space) + (index_count + index_id_max + 1) * sizeof(Index *); @@ -76,7 +76,7 @@ space_new(struct space_def *def, struct rlist *key_list) space->index_id_max = index_id_max; /* fill space indexes */ rlist_foreach_entry(key_def, key_list, link) { - space->index_map[key_def->id] = Index::factory(key_def); + space->index_map[key_def->iid] = Index::factory(key_def); } space_fill_index_map(space); space->engine = engine_no_keys; @@ -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/src/box/tuple.cc b/src/box/tuple.cc index 33375d7cc89555b5a4727ae47068b6a0182c4bbf..bc4a2862fff02e87116298b8f13b211a6da16e79 100644 --- a/src/box/tuple.cc +++ b/src/box/tuple.cc @@ -63,7 +63,7 @@ field_type_create(enum field_type *types, uint32_t field_count, if (*ptype != UNKNOWN && *ptype != part->type) { tnt_raise(ClientError, ER_FIELD_TYPE_MISMATCH, - key_def->id, part - key_def->parts, + key_def->iid, part - key_def->parts, field_type_strs[part->type], field_type_strs[*ptype]); } @@ -216,19 +216,19 @@ tuple_format_new(struct rlist *key_list) * Validate a new tuple format and initialize tuple-local * format data. */ -static inline void -tuple_init_field_map(struct tuple *tuple, struct tuple_format *format) +void +tuple_init_field_map(struct tuple_format *format, struct tuple *tuple, uint32_t *field_map) { /* Check to see if the tuple has a sufficient number of fields. */ if (tuple->field_count < format->field_count) - tnt_raise(IllegalParams, - "tuple must have all indexed fields"); + tnt_raise(ClientError, ER_INDEX_ARITY, + (unsigned) tuple->field_count, + (unsigned) format->field_count); int32_t *offset = format->offset; enum field_type *type = format->types; enum field_type *end = format->types + format->field_count; const char *pos = tuple->data; - uint32_t *field_map = (uint32_t *) tuple; uint32_t i = 0; for (; type < end; offset++, type++, i++) { @@ -457,7 +457,7 @@ tuple_update(struct tuple_format *format, try { tuple_update_execute(update, new_tuple->data); - tuple_init_field_map(new_tuple, format); + tuple_init_field_map(format, new_tuple, (uint32_t *)new_tuple); } catch (const Exception&) { tuple_delete(new_tuple); throw; @@ -494,7 +494,7 @@ tuple_new(struct tuple_format *format, uint32_t field_count, new_tuple->field_count = field_count; memcpy(new_tuple->data, end - tuple_len, tuple_len); try { - tuple_init_field_map(new_tuple, format); + tuple_init_field_map(format, new_tuple, (uint32_t *)new_tuple); } catch (...) { tuple_delete(new_tuple); throw; diff --git a/src/box/tuple.h b/src/box/tuple.h index 0297dc7677fc3d2b4eb8aa1c57497b85a528123c..b0ba2ff7dd6fd759582011d94e5ef1049e41ac7c 100644 --- a/src/box/tuple.h +++ b/src/box/tuple.h @@ -353,6 +353,10 @@ tuple_next_cstr(struct tuple_iterator *it); void tuple_print(struct tbuf *buf, const struct tuple *tuple); +void +tuple_init_field_map(struct tuple_format *format, + struct tuple *tuple, uint32_t *field_map); + struct tuple * tuple_update(struct tuple_format *new_format, void *(*region_alloc)(void *, size_t), void *alloc_ctx, diff --git a/test/big/sql.result b/test/big/sql.result index 699f7d0a80103b15f6b6c1d7b2f26a65871e2169..55cfbcea3bb3fab882882953cde5cfe903f8b25a 100644 --- a/test/big/sql.result +++ b/test/big/sql.result @@ -64,14 +64,14 @@ box.space[0]:truncate() # insert into t0 values ('Britney') --- -- error: 'Illegal parameters, tuple must have all indexed fields' +- error: 'Tuple field count 1 is less than required by a defined index (expected 2)' ... select * from t0 where k1='Anything' --- ... insert into t0 values ('Stephanie') --- -- error: 'Illegal parameters, tuple must have all indexed fields' +- error: 'Tuple field count 1 is less than required by a defined index (expected 2)' ... select * from t0 where k1='Anything' --- @@ -385,7 +385,7 @@ select * from t0 where k1='Britney' ... replace into t0 values ('Spears') --- -- error: 'Illegal parameters, tuple must have all indexed fields' +- error: 'Tuple field count 1 is less than required by a defined index (expected 2)' ... select * from t0 where k0='Spears' --- diff --git a/test/big/tree_pk_multipart.result b/test/big/tree_pk_multipart.result index f20e075cbcd82a2f227f65751dca68c40d96f8c2..b0c884a9dcb0b26a8eb445d38b389865b7278970 100644 --- a/test/big/tree_pk_multipart.result +++ b/test/big/tree_pk_multipart.result @@ -439,11 +439,11 @@ space = box.space[0] ... space:insert(1, 1) --- -- error: Illegal parameters, tuple must have all indexed fields +- error: Tuple field count 2 is less than required by a defined index (expected 3) ... space:replace_if_exists(1, 1) --- -- error: Illegal parameters, tuple must have all indexed fields +- error: Tuple field count 2 is less than required by a defined index (expected 3) ... space:drop() --- diff --git a/test/box/alter_limits.result b/test/box/alter_limits.result index 6acadfc4c913d2165239c1bca4c41d7558a58562..1c545a9b9aa51bc3c7da120e59577e65d10e529d 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)..."]:170: attempt to index a nil +- error: '[string "-- schema.lua (internal file)..."]:205: attempt to index a nil value' ... s:delete(0) @@ -477,36 +477,383 @@ s:create_index('t1', 'hash', {parts = parts}); s:drop() --- ... --- add index: --- --------- --- - a test case for contraints in tuple_format_new --- - index rebuild: --- - a duplicate in the new index --- - no field for the new index --- - wrong field type in the new index --- - alter algorithm correctly detects --- test that during the rebuild there is a duplicate --- according to the new index --- - index rebuild -> no field in the index (validate tuple --- during build) --- - alter unique -> non unique --- - alter index type --- - index access by name --- - alter add key part --- - arbitrary index --- - test that during commit phase --- -> inject error at commit, inject error at rollback --- - add check that doesn't allow drop of a primary --- key in presence of other keys, or moves the space --- to disabled state otherwise. +-- check costraints in tuple_format_new() +s = box.schema.create_space('test') +--- +... +s:create_index('t1', 'hash', { parts = { 0, 'num' }}) +--- +... +-- field type contradicts field type of another index +s:create_index('t2', 'hash', { parts = { 0, 'str' }}) +--- +- error: Ambiguous field type in index 1, key part 0. Requested type is STR but the + field has previously been defined as NUM +... +-- ok +s:create_index('t2', 'hash', { parts = { 1, 'str' }}) +--- +... +-- don't allow drop of the primary key in presence of other keys +s.index[0]:drop() +--- +- error: Can't drop primary key in space 512 while secondary keys exist +... +-- cleanup +s:drop() +--- +... +-- index name, name manipulation +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: primary key must be unique' +... +-- unique -> non-unique, index type +s.index.primary:alter({type='tree', unique=false, name='pk'}) +--- +- error: 'Can''t create or modify index 0 in space 512: primary key must be unique' +... +s.index.primary +--- +- unique: true + idx: index 0 + n: 512 + type: HASH + key_field: + 0: + type: NUM + fieldno: 0 + name: primary + id: 0 +... +s.index.pk.type +--- +- error: '[string "return s.index.pk.type"]:1: attempt to index field ''pk'' (a nil + value)' +... +s.index.pk.unique +--- +- error: '[string "return s.index.pk.unique"]:1: attempt to index field ''pk'' (a + nil value)' +... +s.index.pk:rename('primary') +--- +- error: '[string "return s.index.pk:rename(''primary'')"]:1: attempt to index field + ''pk'' (a nil value)' +... +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 +... +s:drop() +--- +... +-- ---------------------------------------------------------------- +-- BUILD INDEX: changes of a non-empty index +-- ---------------------------------------------------------------- +s = box.schema.create_space('full') +--- +... +s:create_index('primary', 'tree', {parts = { 0, 'str' }}) +--- +... +s:insert('No such movie', 999) +--- +- ['No such movie', 999] +... +s:insert('Barbara', 2012) +--- +- ['Barbara', 2012] +... +s:insert('Cloud Atlas', 2012) +--- +- ['Cloud Atlas', 2012] +... +s:insert('Almanya - Willkommen in Deutschland', 2011) +--- +- ['Almanya - Willkommen in Deutschland', 2011] +... +s:insert('Halt auf freier Strecke', 2011) +--- +- ['Halt auf freier Strecke', 2011] +... +s:insert('Homevideo', 2011) +--- +- ['Homevideo', 2011] +... +s:insert('Die Fremde', 2010) +--- +- ['Die Fremde', 2010] +... +-- create index with data +s:create_index('year', 'tree', { unique=false, parts = { 1, 'num'} }) +--- +... +s.index.primary:select() +--- +- ['Almanya - Willkommen in Deutschland', 2011] +- ['Barbara', 2012] +- ['Cloud Atlas', 2012] +- ['Die Fremde', 2010] +- ['Halt auf freier Strecke', 2011] +- ['Homevideo', 2011] +- ['No such movie', 999] +... +-- a duplicate in the created index +s:create_index('nodups', 'tree', { unique=true, parts = { 1, 'num'} }) +--- +- error: Duplicate key exists in unique index 2 +... +-- change of non-unique index to unique: same effect +s.index.year:alter({unique=true}) +--- +- error: Duplicate key exists in unique index 1 +... +-- num -> str -> num transition +box.space['_index']:update({s.n, s.index.year.id}, "=p", 7, 'str') +--- +- [512, 1, 1918985593, 1701147252, 0, 1, 1, 'str'] +... +s.index.primary:select() +--- +- ['Almanya - Willkommen in Deutschland', 2011] +- ['Barbara', 2012] +- ['Cloud Atlas', 2012] +- ['Die Fremde', 2010] +- ['Halt auf freier Strecke', 2011] +- ['Homevideo', 2011] +- ['No such movie', 999] +... +box.space['_index']:update({s.n, s.index.year.id}, "=p", 7, 'num') +--- +- [512, 1, 1918985593, 1701147252, 0, 1, 1, 'num'] +... +-- ambiguous field type +s:create_index('str', 'tree', {unique = false, parts = { 1, 'str'}}) +--- +- error: Ambiguous field type in index 2, key part 0. Requested type is STR but the + field has previously been defined as NUM +... +-- create index on a non-existing field +s:create_index('nosuchfield', 'tree', {unique = true, parts = { 2, 'str'}}) +--- +- error: Tuple field count 2 is less than required by a defined index (expected 3) +... +s.index.year:drop() +--- +... +s:insert('Der Baader Meinhof Komplex', '2009 ') +--- +- ['Der Baader Meinhof Komplex', '2009 '] +... +-- create an index on a field with a wrong type +s:create_index('year', 'tree', {unique = false, parts = { 1, 'num'}}) +--- +- error: 'Tuple field 1 type does not match one required by operation: expected NUM' +... +-- a field is missing +s:replace('Der Baader Meinhof Komplex') +--- +- ['Der Baader Meinhof Komplex'] +... +s:create_index('year', 'tree', {unique = false, parts = { 1, 'num'}}) +--- +- error: Tuple field count 1 is less than required by a defined index (expected 2) +... +s:drop() +--- +... +-- unique -> non-unique transition +s = box.schema.create_space('test') +--- +... +-- primary key must be unique +s:create_index('primary', 'tree', { unique = false, parts = {0, 'num'}}) +--- +- error: 'Can''t create or modify index 0 in space 512: primary key must be unique' +... +-- create primary key +s:create_index('primary', 'hash', { unique = true, parts = {0, 'num'}}) +--- +... +s:insert(1, 1) +--- +- [1, 1] +... +s:create_index('secondary', 'tree', { unique = false, parts = {1, 'num'}}) +--- +... +s:insert(2, 1) +--- +- [2, 1] +... +s.index.secondary:alter({ unique = true }) +--- +- error: Duplicate key exists in unique index 1 +... +s:delete(2) +--- +- [2, 1] +... +s.index.secondary:alter({ unique = true }) +--- +... +s:insert(2, 1) +--- +- error: Duplicate key exists in unique index 1 +... +s:insert(2, 2) +--- +- [2, 2] +... +s.index.secondary:alter({ unique = false}) +--- +... +s:insert(3, 2) +--- +- [3, 2] +... +s:drop() +--- +... +-- ----------- -- --- - add identical index - verify there is no rebuild --- - rename index (all non-essential propeties) --- -> duplicate key --- - inject fiber sleep during commit, so that some stuff is added --- (test crap which happens while there is a record to the wal --- - test ambiguous field type when adding an index (ER_FIELD_TYPE_MISMATCH) --- - test addition of a new index on data which it can't handle -- -- space cache -- ----------- @@ -521,6 +868,8 @@ s:drop() -- -- -- inject error at various stages of commit and see that -- the alter has no effects +-- - test that during commit phase +-- -> inject error at commit, inject error at rollback -- -- usability -- --------- diff --git a/test/box/alter_limits.test.lua b/test/box/alter_limits.test.lua index 582c3ba0b292aa2fa754186fed5dd1a28a1cc45d..9dae0f4ae83df86da2ad24466386d8ceba90010b 100644 --- a/test/box/alter_limits.test.lua +++ b/test/box/alter_limits.test.lua @@ -179,36 +179,122 @@ s:create_index('t1', 'hash', {parts = parts}); #s.index[0].key_field -- cleanup s:drop() --- add index: --- --------- --- - a test case for contraints in tuple_format_new --- - index rebuild: --- - a duplicate in the new index --- - no field for the new index --- - wrong field type in the new index --- - alter algorithm correctly detects --- test that during the rebuild there is a duplicate --- according to the new index --- - index rebuild -> no field in the index (validate tuple --- during build) --- - alter unique -> non unique --- - alter index type --- - index access by name --- - alter add key part --- - arbitrary index --- - test that during commit phase --- -> inject error at commit, inject error at rollback --- - add check that doesn't allow drop of a primary --- key in presence of other keys, or moves the space --- to disabled state otherwise. +-- check costraints in tuple_format_new() +s = box.schema.create_space('test') +s:create_index('t1', 'hash', { parts = { 0, 'num' }}) +-- field type contradicts field type of another index +s:create_index('t2', 'hash', { parts = { 0, 'str' }}) +-- ok +s:create_index('t2', 'hash', { parts = { 1, 'str' }}) +-- don't allow drop of the primary key in presence of other keys +s.index[0]:drop() +-- cleanup +s:drop() +-- index name, name manipulation +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}) +-- unique -> non-unique, index type +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 +s:drop() +-- ---------------------------------------------------------------- +-- BUILD INDEX: changes of a non-empty index +-- ---------------------------------------------------------------- +s = box.schema.create_space('full') +s:create_index('primary', 'tree', {parts = { 0, 'str' }}) +s:insert('No such movie', 999) +s:insert('Barbara', 2012) +s:insert('Cloud Atlas', 2012) +s:insert('Almanya - Willkommen in Deutschland', 2011) +s:insert('Halt auf freier Strecke', 2011) +s:insert('Homevideo', 2011) +s:insert('Die Fremde', 2010) +-- create index with data +s:create_index('year', 'tree', { unique=false, parts = { 1, 'num'} }) +s.index.primary:select() +-- a duplicate in the created index +s:create_index('nodups', 'tree', { unique=true, parts = { 1, 'num'} }) +-- change of non-unique index to unique: same effect +s.index.year:alter({unique=true}) +-- num -> str -> num transition +box.space['_index']:update({s.n, s.index.year.id}, "=p", 7, 'str') +s.index.primary:select() +box.space['_index']:update({s.n, s.index.year.id}, "=p", 7, 'num') +-- ambiguous field type +s:create_index('str', 'tree', {unique = false, parts = { 1, 'str'}}) +-- create index on a non-existing field +s:create_index('nosuchfield', 'tree', {unique = true, parts = { 2, 'str'}}) +s.index.year:drop() +s:insert('Der Baader Meinhof Komplex', '2009 ') +-- create an index on a field with a wrong type +s:create_index('year', 'tree', {unique = false, parts = { 1, 'num'}}) +-- a field is missing +s:replace('Der Baader Meinhof Komplex') +s:create_index('year', 'tree', {unique = false, parts = { 1, 'num'}}) +s:drop() +-- unique -> non-unique transition +s = box.schema.create_space('test') +-- primary key must be unique +s:create_index('primary', 'tree', { unique = false, parts = {0, 'num'}}) +-- create primary key +s:create_index('primary', 'hash', { unique = true, parts = {0, 'num'}}) +s:insert(1, 1) +s:create_index('secondary', 'tree', { unique = false, parts = {1, 'num'}}) +s:insert(2, 1) +s.index.secondary:alter({ unique = true }) +s:delete(2) +s.index.secondary:alter({ unique = true }) +s:insert(2, 1) +s:insert(2, 2) +s.index.secondary:alter({ unique = false}) +s:insert(3, 2) +s:drop() +-- ----------- -- --- - add identical index - verify there is no rebuild --- - rename index (all non-essential propeties) --- -> duplicate key --- - inject fiber sleep during commit, so that some stuff is added --- (test crap which happens while there is a record to the wal --- - test ambiguous field type when adding an index (ER_FIELD_TYPE_MISMATCH) --- - test addition of a new index on data which it can't handle -- -- space cache -- ----------- @@ -223,6 +309,8 @@ s:drop() -- -- -- inject error at various stages of commit and see that -- the alter has no effects +-- - test that during commit phase +-- -> inject error at commit, inject error at rollback -- -- usability -- --------- diff --git a/test/box/lua.result b/test/box/lua.result index 62b57b9fb1cde397ddc3036646eaa2698492099b..efbea0f96c638ff4639574e246ce623f8e01f453 100644 --- a/test/box/lua.result +++ b/test/box/lua.result @@ -581,23 +581,23 @@ box.cfg.nosuchoption = 1 box.space[300] = 1 --- ... -box.index.new('abc', 'cde') +box.index.bind('abc', 'cde') --- - error: 'bad argument #1 to ''?'' (number expected, got string)' ... -box.index.new(1, 2) +box.index.bind(1, 2) --- - error: Space 1 does not exist ... -box.index.new(0, 1) +box.index.bind(0, 1) --- - error: 'No index #1 is defined in space 0' ... -box.index.new(0, 0) +box.index.bind(0, 0) --- --index 0 +- index 0 ... -#box.index.new(0,0) +#box.index.bind(0,0) --- - 0 ... @@ -613,7 +613,7 @@ box.insert(0, 'abcd') --- - [1684234849] ... -#box.index.new(0,0) +#box.index.bind(0,0) --- - 2 ... @@ -625,7 +625,7 @@ box.delete(0, 'test') --- - [1953719668] ... -#box.index.new(0,0) +#box.index.bind(0,0) --- - 1 ... @@ -637,7 +637,7 @@ box.delete(0, 'abcd') --- - 0 ... -#box.index.new(0,0) +#box.index.bind(0,0) --- - 0 ... @@ -1300,7 +1300,7 @@ call box.update('0', 'tes4', '#p', 0, '') ... box.update(0, 'tes5', '#p', 0, '') --- -- error: Illegal parameters, tuple must have all indexed fields +- error: Tuple field count 0 is less than required by a defined index (expected 1) ... box.space[0]:truncate() --- diff --git a/test/box/lua.test.py b/test/box/lua.test.py index 4cdf7618e559aa109aa8ab40132a0b844cc18852..8852e9f9b1d5dd8f764e2d8974526c6d7813beb1 100644 --- a/test/box/lua.test.py +++ b/test/box/lua.test.py @@ -145,21 +145,21 @@ admin("t") admin("box.cfg.nosuchoption = 1") admin("box.space[300] = 1") -admin("box.index.new('abc', 'cde')") -admin("box.index.new(1, 2)") -admin("box.index.new(0, 1)") -admin("box.index.new(0, 0)") -admin("#box.index.new(0,0)") +admin("box.index.bind('abc', 'cde')") +admin("box.index.bind(1, 2)") +admin("box.index.bind(0, 1)") +admin("box.index.bind(0, 0)") +admin("#box.index.bind(0,0)") admin("#box.space[0].index[0].idx") admin("box.insert(0, 'test')") admin("box.insert(0, 'abcd')") -admin("#box.index.new(0,0)") +admin("#box.index.bind(0,0)") admin("#box.space[0].index[0].idx") admin("box.delete(0, 'test')") -admin("#box.index.new(0,0)") +admin("#box.index.bind(0,0)") admin("box.delete(0, 'abcd')") admin("#box.space[0].index[0].idx") -admin("#box.index.new(0,0)") +admin("#box.index.bind(0,0)") admin("box.space[0]:insert('test', 'hello world')") admin("box.space[0]:update('test', '=p', 1, 'bye, world')") admin("box.space[0]:delete('test')") diff --git a/test/box/lua_misc.result b/test/box/lua_misc.result index 2fcff38cde65a8f4e99a55d3ea0bfea7969c424a..4f741cc54d826e82e9ab7a92d4a6967c357e0ace 100644 --- a/test/box/lua_misc.result +++ b/test/box/lua_misc.result @@ -137,9 +137,10 @@ t; - 'box.error.ER_FIELD_TYPE : 10242' - 'box.error.ER_OK : 0' - 'box.error.ER_TUPLE_NOT_FOUND : 12546' + - 'box.error.ER_INDEX_ARITY : 8194' - 'box.error.ER_WAL_IO : 9986' - 'box.error.ER_INJECTION : 2306' - - 'box.error.ER_DROP_PRIMARY_KEY : 7682' + - 'box.error.ER_LAST_DROP : 7426' - 'box.error.ER_INDEX_TYPE : 1282' - 'box.error.ER_ARG_TYPE : 10498' - 'box.error.ER_KEY_PART_COUNT : 12034' @@ -153,7 +154,7 @@ t; - 'box.error.ER_SECONDARY : 770' - 'box.error.ER_UPDATE_FIELD : 14338' - 'box.error.ER_DROP_SPACE : 6146' - - 'box.error.ER_UNKNOWN_UPDATE_OP : 11266' + - 'box.error.ER_SPLICE : 10754' - 'box.error.ER_NO_SUCH_SPACE : 14594' - 'box.error.ER_UNSUPPORTED : 2562' - 'box.error.ER_TUPLE_FOUND : 14082' @@ -161,12 +162,12 @@ t; - 'box.error.ER_SPACE_DISABLED : 13314' - 'box.error.ER_PROC_LUA : 13058' - 'box.error.ER_ALTER_SPACE : 6402' - - 'box.error.ER_TUPLE_IS_RO : 1025' - 'box.error.ER_FIBER_STACK : 6658' + - 'box.error.ER_TUPLE_IS_RO : 1025' - 'box.error.ER_NO_SUCH_PROC : 12802' - - 'box.error.ER_LAST_DROP : 7426' - - 'box.error.ER_SPLICE : 10754' + - 'box.error.ER_DROP_PRIMARY_KEY : 7682' - 'box.error.ER_SPACE_ARITY : 7938' + - 'box.error.ER_UNKNOWN_UPDATE_OP : 11266' - 'box.error.ER_FIELD_TYPE_MISMATCH : 11778' - 'box.error.ER_SPACE_EXISTS : 1538' ... diff --git a/test/lib/sql_ast.py b/test/lib/sql_ast.py index 88884e31b18cf1e0ee12bbf83b60f7af99ba74f5..620da0d198a361b40a38ab0661b9a0d2d4b983e5 100644 --- a/test/lib/sql_ast.py +++ b/test/lib/sql_ast.py @@ -53,7 +53,7 @@ ER = { 29: "ER_LAST_DROP" , 30: "ER_DROP_PRIMARY_KEY" , 31: "ER_SPACE_ARITY" , - 32: "ER_UNUSED32" , + 32: "ER_INDEX_ARITY" , 33: "ER_UNUSED33" , 34: "ER_UNUSED34" , 35: "ER_UNUSED35" ,