diff --git a/cmake/rpm.cmake b/cmake/rpm.cmake index 75247c85aa7bac7519dfcf64feec6622ed32308e..45e53f85c3cff7444bf25dea17f1f206c036fb7c 100644 --- a/cmake/rpm.cmake +++ b/cmake/rpm.cmake @@ -14,9 +14,9 @@ if (RPMBUILD) OUTPUT_VARIABLE RELEASE OUTPUT_STRIP_TRAILING_WHITESPACE) - set (SCL_VERSION "1.0" CACHE STRING "" FORCE) - set (SCL_RELEASE "1" CACHE STRING "" FORCE) - set (SCL_TARANTOOL "16" CACHE STRING "" FORCE) + set (SCL_VERSION "1.0" CACHE STRING "" FORCE) + set (SCL_RELEASE "1" CACHE STRING "" FORCE) + set (SCL_TARANTOOL "mailru-16" CACHE STRING "" FORCE) set (RPM_PACKAGE_VERSION ${VERSION} CACHE STRING "" FORCE) set (RPM_PACKAGE_RELEASE ${RELEASE} CACHE STRING "" FORCE) diff --git a/extra/rpm/tarantool-scl.rpm.spec b/extra/rpm/tarantool-scl.rpm.spec index 5b71713268e0a39d04b8cb0f5359d9d4415615ae..4c08ae6215ebed170c0a23f01277b134638a9668 100644 --- a/extra/rpm/tarantool-scl.rpm.spec +++ b/extra/rpm/tarantool-scl.rpm.spec @@ -1,4 +1,4 @@ -%global scl 16 +%global scl mailru-16 %define _source_filedigest_algorithm 0 %define _binary_filedigest_algorithm 0 @@ -6,8 +6,6 @@ %global _scl_prefix /opt/tarantool %scl_package -%global scl_name tarantool-%scl - BuildRequires: scl-utils-build BuildRequires: iso-codes diff --git a/extra/rpm/tarantool.rpm.spec.in b/extra/rpm/tarantool.rpm.spec.in index 171ab495307dc976dc13c17204e4b9d06bc3f952..c7dc52640d1b37615eae9ed193d86b62b21d364b 100644 --- a/extra/rpm/tarantool.rpm.spec.in +++ b/extra/rpm/tarantool.rpm.spec.in @@ -1,8 +1,9 @@ #################################################### ################# MACROS AND DEFAULTS ############## #################################################### -%{?scl:%{?scl_package:%scl_package tarantool}} -%global scl_runtime tarantool-15-runtime + +%{?scl:%global _scl_prefix /opt/tarantool} +%{?scl:%scl_package tarantool} %define _source_filedigest_algorithm 0 %define _binary_filedigest_algorithm 0 diff --git a/src/box/alter.cc b/src/box/alter.cc index 784e6c8948b5df0f3abdd052b68ba8f6566867b7..6899fee6b92f53c7c14bfc88f6302fe13aba1a8c 100644 --- a/src/box/alter.cc +++ b/src/box/alter.cc @@ -307,8 +307,7 @@ 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), - false); + index_id(new_index)); } } /* @@ -626,7 +625,8 @@ 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, true); + old_key_def->iid, new_key_def->iid); + key_def_copy(old_key_def, new_key_def); } ModifyIndex::~ModifyIndex() diff --git a/src/box/key_def.h b/src/box/key_def.h index bdbd9d87a4a4b0051cbbfafdb574c9d30bc1e7cc..96028f7a5bd91451121899f1786ebd6706e6049a 100644 --- a/src/box/key_def.h +++ b/src/box/key_def.h @@ -137,6 +137,23 @@ key_def_dup(struct key_def *def) return dup; } +/** + * Copy one key def into another, preserving the membership + * in rlist. This only works for key defs with equal number of + * parts. + */ +static inline void +key_def_copy(struct key_def *to, const struct key_def *from) +{ + struct rlist save_link = to->link; + int part_count = (to->part_count < from->part_count ? + to->part_count : from->part_count); + size_t size = (sizeof(struct key_def) + + sizeof(struct key_part) * part_count); + memcpy(to, from, size); + to->link = save_link; +} + /** * Set a single key part in a key def. * @pre part_no < part_count diff --git a/src/box/lua/call.cc b/src/box/lua/call.cc index f0f6b38e9593d0b8814a30d740dbd516ce3e816f..0ed7344ca48cfbd31dfc91edd7d3d1650c79fc7e 100644 --- a/src/box/lua/call.cc +++ b/src/box/lua/call.cc @@ -361,6 +361,7 @@ lbox_update(lua_State *L) struct request *request = lbox_request_create(L, IPROTO_UPDATE, 3, 4); /* Ignore index_id for now */ + request->field_base = 1; /* field ids are one-indexed */ box_process(port_lua_create(L), request); return lua_gettop(L) - 4; } diff --git a/src/box/lua/index.cc b/src/box/lua/index.cc index 48088402c26fdd0fffc0eea9c8269f2fa2461b36..44341362e890f0b77e4540e009ae7191381febc0 100644 --- a/src/box/lua/index.cc +++ b/src/box/lua/index.cc @@ -39,91 +39,32 @@ /** {{{ box.index Lua library: access to spaces and indexes */ -static const char *indexlib_name = "box.index"; - -/* Index userdata. */ -struct lbox_index -{ - Index *index; - /* space id. */ - uint32_t id; - /* index id. */ - uint32_t iid; - /* space cache version at the time of push. */ - int sc_version; -}; - -static Index * -lua_checkindex(struct lua_State *L, int i) +static inline Index * +check_index(uint32_t space_id, uint32_t index_id) { - struct lbox_index *index = - (struct lbox_index *) luaL_checkudata(L, i, indexlib_name); - assert(index != NULL); - if (index->sc_version != sc_version) { - index->index = index_find(space_cache_find(index->id), - index->iid); - index->sc_version = sc_version; - } - return index->index; + struct space *space = space_cache_find(space_id); + space_check_access(space, PRIV_R); + return index_find(space, index_id); } -static int -lbox_index_bind(struct lua_State *L) +size_t +boxffi_index_len(uint32_t space_id, uint32_t index_id) { - 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 */ - /* locate the appropriate index */ - struct space *space = space_cache_find(id); - Index *i = index_find(space, iid); - - /* create a userdata object */ - struct lbox_index *index = (struct lbox_index *) - lua_newuserdata(L, sizeof(struct lbox_index)); - index->id = id; - index->iid = iid; - index->sc_version = sc_version; - index->index = i; - /* set userdata object metatable to indexlib */ - luaL_getmetatable(L, indexlib_name); - lua_setmetatable(L, -2); - - return 1; -} - -static int -lbox_index_tostring(struct lua_State *L) -{ - Index *index = lua_checkindex(L, 1); - lua_pushfstring(L, " index %d", (int) index_id(index)); - return 1; -} - -static int -lbox_index_len(struct lua_State *L) -{ - Index *index = lua_checkindex(L, 1); - lua_pushinteger(L, index->size()); - return 1; -} - -static int -lbox_index_part_count(struct lua_State *L) -{ - Index *index = lua_checkindex(L, 1); - lua_pushinteger(L, index->key_def->part_count); - return 1; + try { + return check_index(space_id, index_id)->size(); + } catch (Exception *) { + return (size_t) -1; /* handled by box.raise() in Lua */ + } } -static int -lbox_index_random(struct lua_State *L) +struct tuple * +boxffi_index_random(uint32_t space_id, uint32_t index_id, uint32_t rnd) { - if (lua_gettop(L) != 2 || lua_isnil(L, 2)) - luaL_error(L, "Usage: index:random((uint32) rnd)"); - - Index *index = lua_checkindex(L, 1); - uint32_t rnd = lua_tointeger(L, 2); - lbox_pushtuple(L, index->random(rnd)); - return 1; + try { + return check_index(space_id, index_id)->random(rnd); + } catch (Exception *) { + return (struct tuple *) -1; /* handled by box.raise() in Lua */ + } } static void @@ -148,9 +89,7 @@ boxffi_index_iterator(uint32_t space_id, uint32_t index_id, int type, struct iterator *it = NULL; enum iterator_type itype = (enum iterator_type) type; try { - struct space *space = space_cache_find(space_id); - space_check_access(space, PRIV_R); - Index *index = index_find(space, index_id); + Index *index = check_index(space_id, index_id); assert(mp_typeof(*key) == MP_ARRAY); /* checked by Lua */ uint32_t part_count = mp_decode_array(&key); key_validate(index->key_def, itype, key, part_count); @@ -170,22 +109,11 @@ boxffi_index_iterator(uint32_t space_id, uint32_t index_id, int type, void box_lua_index_init(struct lua_State *L) { - static const struct luaL_reg lbox_index_meta[] = { - {"__tostring", lbox_index_tostring}, - {"__len", lbox_index_len}, - {"part_count", lbox_index_part_count}, - {"random", lbox_index_random}, - {NULL, NULL} - }; - static const struct luaL_reg indexlib [] = { - {"bind", lbox_index_bind}, {NULL, NULL} }; - /* box.index */ - luaL_register_type(L, indexlib_name, lbox_index_meta); luaL_register(L, "box.index", indexlib); box_index_init_iterator_types(L, -2); lua_pop(L, 1); diff --git a/src/box/lua/index.h b/src/box/lua/index.h index 757ed9e4d59fd3db2bab7ddf7fa3ccf21076db60..2ea1a53e68237d1815a6a921171f153bd0c73658 100644 --- a/src/box/lua/index.h +++ b/src/box/lua/index.h @@ -29,6 +29,7 @@ * SUCH DAMAGE. */ +#include <stddef.h> #include <stdint.h> struct lua_State; @@ -41,6 +42,12 @@ box_lua_index_init(struct lua_State *L); extern "C" { #endif /* defined(__cplusplus) */ +size_t +boxffi_index_len(uint32_t space_id, uint32_t index_id); + +struct tuple * +boxffi_index_random(uint32_t space_id, uint32_t index_id, uint32_t rnd); + struct iterator * boxffi_index_iterator(uint32_t space_id, uint32_t index_id, int type, const char *key); diff --git a/src/box/lua/schema.lua b/src/box/lua/schema.lua index 0a38b7ac3ec4681eb37edb69f53af7f9b742eca7..f7c10d78e9daf0ccb1f0f578444007d092195830 100644 --- a/src/box/lua/schema.lua +++ b/src/box/lua/schema.lua @@ -17,6 +17,10 @@ ffi.cdef[[ void (*free)(struct iterator *); void (*close)(struct iterator *); }; + size_t + boxffi_index_len(uint32_t space_id, uint32_t index_id); + struct tuple * + boxffi_index_random(uint32_t space_id, uint32_t index_id, uint32_t rnd); struct iterator * boxffi_index_iterator(uint32_t space_id, uint32_t index_id, int type, const char *key); @@ -124,7 +128,7 @@ box.schema.space.drop = function(space_id) end box.schema.space.rename = function(space_id, space_name) local _space = box.space[box.schema.SPACE_ID] - _space:update(space_id, {{"=", 2, space_name}}) + _space:update(space_id, {{"=", 3, space_name}}) end box.schema.index = {} @@ -175,7 +179,7 @@ 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}, {{"=", 2, name}}) + _index:update({space_id, index_id}, {{"=", 3, name}}) end box.schema.index.alter = function(space_id, index_id, options) if box.space[space_id] == nil then @@ -210,10 +214,10 @@ box.schema.index.alter = function(space_id, index_id, options) table.insert(ops, {'=', field_no, value}) end end - add_op(options.id, 1) - add_op(options.name, 2) - add_op(options.type, 3) - add_op(options.unique, 4) + add_op(options.id, 2) + add_op(options.name, 3) + add_op(options.type, 4) + add_op(options.unique, 5) _index:update({space_id, index_id}, ops) return end @@ -305,7 +309,14 @@ local port_t = ffi.typeof('struct port *') function box.schema.space.bless(space) local index_mt = {} -- __len and __index - index_mt.len = function(index) return #index.idx end + index_mt.len = function(index) + local ret = builtin.boxffi_index_len(index.space.id, index.id) + if ret == -1 then + box.raise() + end + return tonumber(ret) + end + index_mt.__len = index_mt.len -- Lua 5.2 compatibility index_mt.__newindex = function(table, index) return error('Attempt to modify a read-only table') end index_mt.__index = index_mt @@ -332,7 +343,17 @@ function box.schema.space.bless(space) return end end - index_mt.random = function(index, rnd) return index.idx:random(rnd) end + index_mt.random = function(index, rnd) + rnd = rnd or math.random() + local tuple = builtin.boxffi_index_random(index.space.id, index.id, rnd) + if tuple == ffi.cast('void *', -1) then + box.raise() -- error + elseif tuple ~= nil then + return box.tuple.bless(tuple) + else + return nil + end + end -- iteration index_mt.pairs = function(index, key, opts) local pkey, pkey_end = msgpackffi.encode_tuple(key) @@ -373,7 +394,7 @@ function box.schema.space.bless(space) end if key == nil or type(key) == "table" and #key == 0 then - return #index.idx + return index:len() end local state, tuple @@ -516,7 +537,7 @@ function box.schema.space.bless(space) -- space_mt.inc = function(space, key) local key = keify(key) - local cnt_index = #key + local cnt_index = #key + 1 local tuple while true do tuple = space:update(key, {{'+', cnt_index, 1}}) @@ -526,7 +547,7 @@ function box.schema.space.bless(space) tuple = space:insert(data) if tuple ~= nil then break end end - return tuple[cnt_index + 1] + return tuple[cnt_index] end -- @@ -536,15 +557,15 @@ function box.schema.space.bless(space) -- space_mt.dec = function(space, key) local key = keify(key) - local cnt_index = #key + local cnt_index = #key + 1 local tuple = space:get(key) if tuple == nil then return 0 end - if tuple[cnt_index + 1] == 1 then + if tuple[cnt_index] == 1 then space:delete(key) return 0 else tuple = space:update(key, {{'-', cnt_index, 1}}) - return tuple[cnt_index + 1] + return tuple[cnt_index] end end @@ -564,7 +585,7 @@ function box.schema.space.bless(space) end check_index(space, 0) local pk = space.index[0] - while #pk.idx > 0 do + while pk:len() > 0 do local state, t for state, t in pk:pairs() do local key = {} @@ -597,7 +618,6 @@ function box.schema.space.bless(space) if type(space.index) == 'table' and space.enabled then for j, index in pairs(space.index) do if type(j) == 'number' then - rawset(index, 'idx', box.index.bind(space.id, j)) setmetatable(index, index_mt) end end @@ -709,7 +729,7 @@ box.schema.user.passwd = function(new_password) auth_mech_list = {} auth_mech_list["chap-sha1"] = box.schema.user.password(new_password) require('session').su('admin') - _user:update({uid}, {{"=", 4, auth_mech_list}}) + _user:update({uid}, {{"=", 5, auth_mech_list}}) require('session').su(uid) end @@ -787,7 +807,7 @@ box.schema.user.revoke = function(user_name, privilege, object_type, object_name local old_privilege = tuple[5] if old_privilege ~= privilege then privilege = bit.band(old_privilege, bit.bnot(privilege)) - _priv:update({uid, object_type, oid}, { "=", 4, privilege}) + _priv:update({uid, object_type, oid}, { "=", 5, privilege}) else _priv:delete{uid, object_type, oid} end diff --git a/src/box/lua/tuple.cc b/src/box/lua/tuple.cc index e09cbf54c3d6136b034564815fbe8f2d1923544a..e6e1918b321026f8551ead191fe89599ef06305b 100644 --- a/src/box/lua/tuple.cc +++ b/src/box/lua/tuple.cc @@ -231,12 +231,17 @@ lbox_tuple_transform(struct lua_State *L) uint32_t field_count = tuple_field_count(tuple); /* validate offset and len */ - if (offset < 0) { + if (offset == 0) { + luaL_error(L, "tuple.transform(): offset is out of bound"); + } else if (offset < 0) { if (-offset > field_count) luaL_error(L, "tuple.transform(): offset is out of bound"); offset += field_count; - } else if (offset > field_count) { - offset = field_count; + } else { + --offset; /* offset is one-indexed */ + if (offset > field_count) { + offset = field_count; + } } if (len < 0) luaL_error(L, "tuple.transform(): len is negative"); @@ -285,7 +290,8 @@ lbox_tuple_transform(struct lua_State *L) struct tuple *new_tuple = tuple_update(tuple_format_ber, tuple_update_region_alloc, &fiber()->gc, - tuple, tbuf_str(b), tbuf_end(b)); + tuple, tbuf_str(b), tbuf_end(b), + 0); lbox_pushtuple(L, new_tuple); return 1; } diff --git a/src/box/lua/tuple.lua b/src/box/lua/tuple.lua index f731fa31514df9a8d241d07b015ec4b7cdbed570..f452f009f52b4d89869fd8bb1545e1d7c5db4f78 100644 --- a/src/box/lua/tuple.lua +++ b/src/box/lua/tuple.lua @@ -117,7 +117,7 @@ local function tuple_find(tuple, offset, val) offset = 0 end local r = tuple:pairs(offset):index(val) - return r ~= nil and offset + r - 1 or nil -- tuple is zero-indexed + return r ~= nil and offset + r or nil end local function tuple_findall(tuple, offset, val) @@ -126,7 +126,7 @@ local function tuple_findall(tuple, offset, val) offset = 0 end return tuple:pairs(offset):indexes(val) - :map(function(i) return offset + i - 1 end) -- tuple is zero-indexed + :map(function(i) return offset + i end) :totable() end diff --git a/src/box/request.cc b/src/box/request.cc index 01e76b5e3b4af6e8d260ab9f597ddea6d66c9310..759f3bbb754102825374f882da6f42aa5b1fd0b2 100644 --- a/src/box/request.cc +++ b/src/box/request.cc @@ -123,7 +123,8 @@ execute_update(struct request *request, struct txn *txn, region_alloc_cb, &fiber()->gc, old_tuple, request->tuple, - request->tuple_end); + request->tuple_end, + request->field_base); TupleGuard guard(new_tuple); space_validate_tuple(space, new_tuple); txn_replace(txn, space, old_tuple, new_tuple, DUP_INSERT); diff --git a/src/box/request.h b/src/box/request.h index 46acbcd1177c8a16c6c767af27193b76a86a39ab..6a188098f70710a83187df2371265f688cb618ff 100644 --- a/src/box/request.h +++ b/src/box/request.h @@ -54,12 +54,14 @@ struct request uint32_t offset; uint32_t limit; uint32_t iterator; - /* Search key or proc name. */ + /** Search key or proc name. */ const char *key; const char *key_end; - /* Insert/replace tuple or proc argument or update operations. */ + /** Insert/replace tuple or proc argument or update operations. */ const char *tuple; const char *tuple_end; + /** Base field offset, e.g. 0 for C and 1 for Lua */ + int field_base; request_execute_f execute; }; diff --git a/src/box/space.cc b/src/box/space.cc index 7312c87062e4e31c9220f809fe0bb58db74958e4..ebfc0681cec0734606dba2be327f52d0a7b3551c 100644 --- a/src/box/space.cc +++ b/src/box/space.cc @@ -325,18 +325,12 @@ 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, bool keep_key_def) +space_swap_index(struct space *lhs, struct space *rhs, + uint32_t lhs_id, uint32_t rhs_id) { 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 923c0d6cb1af4d5095dc744019debeb0d1e676d9..73bf6ce8f1e5846e9200a2697385e305df63d8fb 100644 --- a/src/box/space.h +++ b/src/box/space.h @@ -239,8 +239,8 @@ space_dump_def(const struct space *space, struct rlist *key_list); * making sure the old index doesn't leak. */ void -space_swap_index(struct space *lhs, struct space *rhs, uint32_t lhs_id, - uint32_t rhs_id, bool keep_key_def); +space_swap_index(struct space *lhs, struct space *rhs, + uint32_t lhs_id, uint32_t rhs_id); /** 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 f6dca523f782d48d4b8ba73455fbcde0faee642f..383304acec6c9566ef2e31e66ebb717eb5a4a030 100644 --- a/src/box/tuple.cc +++ b/src/box/tuple.cc @@ -380,13 +380,13 @@ struct tuple * tuple_update(struct tuple_format *format, void *(*region_alloc)(void *, size_t), void *alloc_ctx, const struct tuple *old_tuple, const char *expr, - const char *expr_end) + const char *expr_end, int field_base) { uint32_t new_size = 0; const char *new_data = tuple_update_execute(region_alloc, alloc_ctx, expr, expr_end, old_tuple->data, old_tuple->data + old_tuple->bsize, - &new_size); + &new_size, field_base); /* Allocate a new tuple. */ assert(mp_typeof(*new_data) == MP_ARRAY); diff --git a/src/box/tuple.h b/src/box/tuple.h index 571a7ea33c47594ab137f144f62d0227511c54b4..b07a3e4db7f11f3515e790424d45f67e800ecd3a 100644 --- a/src/box/tuple.h +++ b/src/box/tuple.h @@ -388,7 +388,7 @@ struct tuple * tuple_update(struct tuple_format *new_format, void *(*region_alloc)(void *, size_t), void *alloc_ctx, const struct tuple *old_tuple, - const char *expr, const char *expr_end); + const char *expr, const char *expr_end, int field_base); /** * @brief Compare two tuple fields using using field type definition diff --git a/src/box/tuple_update.cc b/src/box/tuple_update.cc index 5e9a83b6ac1d2edd6eb2543bcdc9dd6faef18340..5ce86d636581b876feafb8e420c475ca775e9dd7 100644 --- a/src/box/tuple_update.cc +++ b/src/box/tuple_update.cc @@ -294,9 +294,9 @@ do_op_arith(struct tuple_update *update, struct update_op *op, case '+': arg->val += val; break; case '&': arg->val &= val; break; case '^': arg->val ^= val; break; - case '|': arg->val |= val; - case '-': - default: arg->val = val - arg->val; break; + case '|': arg->val |= val; break; + case '-': arg->val = val - arg->val; break; + default: assert(false); /* checked by update_read_ops */ } op->new_field_len = mp_sizeof_uint(arg->val); } @@ -547,7 +547,7 @@ update_write_tuple(struct tuple_update *update, char *buffer, char *buffer_end) static void update_read_ops(struct tuple_update *update, const char *expr, - const char *expr_end) + const char *expr_end, int field_base) { /* number of operations */ update->op_count = mp_decode_array(&expr); @@ -599,6 +599,14 @@ update_read_ops(struct tuple_update *update, const char *expr, if (args != op->meta->args) tnt_raise(ClientError, ER_UNKNOWN_UPDATE_OP); op->field_no = mp_read_int(&expr, "expected a field no (integer)"); + if (op->field_no != UINT32_MAX) { + /* Check that field_no is not zero for Lua (base = 1) */ + if (op->field_no < field_base) { + tnt_raise(ClientError, ER_NO_SUCH_FIELD, + op->field_no); + } + op->field_no -= field_base; + } op->meta->do_op(update, op, &expr); } @@ -611,7 +619,7 @@ const char * tuple_update_execute(region_alloc_func alloc, void *alloc_ctx, const char *expr,const char *expr_end, const char *old_data, const char *old_data_end, - uint32_t *p_tuple_len) + uint32_t *p_tuple_len, int field_base) { struct tuple_update *update = (struct tuple_update *) alloc(alloc_ctx, sizeof(*update)); @@ -621,7 +629,7 @@ tuple_update_execute(region_alloc_func alloc, void *alloc_ctx, update->alloc_ctx = alloc_ctx; update_create_rope(update, old_data, old_data_end); - update_read_ops(update, expr, expr_end); + update_read_ops(update, expr, expr_end, field_base); uint32_t tuple_len = update_calc_tuple_length(update); char *buffer = (char *) alloc(alloc_ctx, tuple_len); diff --git a/src/box/tuple_update.h b/src/box/tuple_update.h index acfd304f5212e22a58b4969acc8ca3220673cb6a..17348c70cda4b831461e2cfd3061b9a961c966e9 100644 --- a/src/box/tuple_update.h +++ b/src/box/tuple_update.h @@ -43,6 +43,6 @@ const char * tuple_update_execute(region_alloc_func alloc, void *alloc_ctx, const char *expr,const char *expr_end, const char *old_data, const char *old_data_end, - uint32_t *p_new_size); + uint32_t *p_new_size, int field_base); #endif /* TARANTOOL_BOX_TUPLE_UPDATE_H_INCLUDED */ diff --git a/src/ffisyms.cc b/src/ffisyms.cc index 3edf46520bce0bfa02a23f6ff7b293bd89319401..20178da7a68522efa88f3cbd0123567831be06b1 100644 --- a/src/ffisyms.cc +++ b/src/ffisyms.cc @@ -25,6 +25,8 @@ void *ffi_symbols[] = { (void *) tuple_seek, (void *) tuple_next, (void *) tuple_ref, + (void *) boxffi_index_len, + (void *) boxffi_index_random, (void *) boxffi_index_iterator, (void *) port_ffi_create, (void *) port_ffi_destroy, diff --git a/src/tarantool.cc b/src/tarantool.cc index 54427961a44fe46cfe547af7c8f35ae753d56ccb..fe1dcb54851b53b4c57b3f6e5456c2b0a1cc1bfd 100644 --- a/src/tarantool.cc +++ b/src/tarantool.cc @@ -538,6 +538,7 @@ main(int argc, char **argv) */ __libc_stack_end = (void*) &argv; #endif + start_time = ev_time(); /* set locale to make iswXXXX function work */ if (setlocale(LC_CTYPE, "en_US.UTF-8") == NULL) fprintf(stderr, "Failed to set locale to en_US.UTF-8\n"); @@ -650,7 +651,6 @@ main(int argc, char **argv) if (start_loop) { say_crit("entering the event loop"); ev_now_update(loop()); - start_time = ev_now(loop()); signal_start(); ev_run(loop(), 0); } diff --git a/test/big/lua.result b/test/big/lua.result index 66fd9b16a053ca4a0d94b1a05d7ee2ac005b82c7..9476a6d404ef1dfbe36db1bd2a5fbd6fee436353 100644 --- a/test/big/lua.result +++ b/test/big/lua.result @@ -591,15 +591,15 @@ space:create_index('primary', { type = 'hash', parts = {1, 'str'}, unique = true t = space:insert{'1', '2', '3', '4', '5', '6', '7'} --- ... -t:transform(7, 0, '8', '9', '100') +t:transform(8, 0, '8', '9', '100') --- - ['1', '2', '3', '4', '5', '6', '7', '8', '9', '100'] ... -t:transform(0, 1) +t:transform(1, 1) --- - ['2', '3', '4', '5', '6', '7'] ... -t:transform(1, 4) +t:transform(2, 4) --- - ['1', '6', '7'] ... @@ -611,7 +611,7 @@ t:transform(-3, 2) --- - ['1', '2', '3', '4', '7'] ... -t:transform(0, 0, 'A') +t:transform(1, 0, 'A') --- - ['A', '1', '2', '3', '4', '5', '6', '7'] ... @@ -619,7 +619,7 @@ t:transform(-1, 0, 'A') --- - ['1', '2', '3', '4', '5', '6', 'A', '7'] ... -t:transform(0, 1, 'A') +t:transform(1, 1, 'A') --- - ['A', '2', '3', '4', '5', '6', '7'] ... @@ -627,19 +627,19 @@ t:transform(-1, 1, 'B') --- - ['1', '2', '3', '4', '5', '6', 'B'] ... -t:transform(0, 2, 'C') +t:transform(1, 2, 'C') --- - ['C', '3', '4', '5', '6', '7'] ... -t:transform(2, 0, 'hello') +t:transform(3, 0, 'hello') --- - ['1', '2', 'hello', '3', '4', '5', '6', '7'] ... -t:transform(0, -1, 'C') +t:transform(1, -1, 'C') --- - error: 'tuple.transform(): len is negative' ... -t:transform(0, 100) +t:transform(1, 100) --- - [] ... @@ -647,15 +647,15 @@ t:transform(-100, 1) --- - error: 'tuple.transform(): offset is out of bound' ... -t:transform(0, 3, 1, 2, 3) +t:transform(1, 3, 1, 2, 3) --- - [1, 2, 3, '4', '5', '6', '7'] ... -t:transform(3, 1, tonumber64(4)) +t:transform(4, 1, tonumber64(4)) --- - ['1', '2', '3', 4, '5', '6', '7'] ... -t:transform(0, 1, {}) +t:transform(1, 1, {}) --- - [[], '2', '3', '4', '5', '6', '7'] ... @@ -675,7 +675,7 @@ tab = {}; for i=1,n,1 do table.insert(tab, i) end t = box.tuple.new(tab) --- ... -t:transform(0, n - 1) +t:transform(1, n - 1) --- - [2000] ... @@ -691,19 +691,19 @@ t = space:insert{'A', '2', '3', '4', '3', '2', '5', '6', '3', '7'} ... t:find('2') --- -- 1 +- 2 ... t:find('4') --- -- 3 +- 4 ... t:find('5') --- -- 6 +- 7 ... t:find('A') --- -- 0 +- 1 ... t:find('0') --- @@ -711,18 +711,18 @@ t:find('0') ... t:findall('A') --- -- - 0 +- - 1 ... t:findall('2') --- -- - 1 - - 5 +- - 2 + - 6 ... t:findall('3') --- -- - 2 - - 4 - - 8 +- - 3 + - 5 + - 9 ... t:findall('0') --- @@ -730,7 +730,7 @@ t:findall('0') ... t:find(2, '2') --- -- 5 +- 6 ... t:find(89, '2') --- @@ -738,24 +738,24 @@ t:find(89, '2') ... t:findall(4, '3') --- -- - 4 - - 8 +- - 5 + - 9 ... t = space:insert{'Z', '2', 2, 3, tonumber64(2)} --- ... t:find(2) --- -- 2 +- 3 ... t:findall(tonumber64(2)) --- -- - 2 - - 4 +- - 3 + - 5 ... t:find('2') --- -- 1 +- 2 ... space:drop() --- diff --git a/test/big/lua.test.lua b/test/big/lua.test.lua index 8ec7bbd81fbbd7fc4272a35320e8e744d62691e1..1a2531d4d123f8446f3b8253f56b5195fe8c7e1e 100644 --- a/test/big/lua.test.lua +++ b/test/big/lua.test.lua @@ -212,23 +212,23 @@ space:drop() space = box.schema.create_space('tweedledum') space:create_index('primary', { type = 'hash', parts = {1, 'str'}, unique = true }) t = space:insert{'1', '2', '3', '4', '5', '6', '7'} -t:transform(7, 0, '8', '9', '100') -t:transform(0, 1) -t:transform(1, 4) +t:transform(8, 0, '8', '9', '100') +t:transform(1, 1) +t:transform(2, 4) t:transform(-1, 1) t:transform(-3, 2) -t:transform(0, 0, 'A') +t:transform(1, 0, 'A') t:transform(-1, 0, 'A') -t:transform(0, 1, 'A') +t:transform(1, 1, 'A') t:transform(-1, 1, 'B') -t:transform(0, 2, 'C') -t:transform(2, 0, 'hello') -t:transform(0, -1, 'C') -t:transform(0, 100) +t:transform(1, 2, 'C') +t:transform(3, 0, 'hello') +t:transform(1, -1, 'C') +t:transform(1, 100) t:transform(-100, 1) -t:transform(0, 3, 1, 2, 3) -t:transform(3, 1, tonumber64(4)) -t:transform(0, 1, {}) +t:transform(1, 3, 1, 2, 3) +t:transform(4, 1, tonumber64(4)) +t:transform(1, 1, {}) space:truncate() -- @@ -239,7 +239,7 @@ space:truncate() n = 2000 tab = {}; for i=1,n,1 do table.insert(tab, i) end t = box.tuple.new(tab) -t:transform(0, n - 1) +t:transform(1, n - 1) t = nil -- diff --git a/test/big/lua/push.lua b/test/big/lua/push.lua index 423946433eb56c6e8600193f91ff254f9298233f..154126f8e1b1cf9a998495cd7363f2ce5243ac52 100644 --- a/test/big/lua/push.lua +++ b/test/big/lua/push.lua @@ -8,9 +8,9 @@ function push_collection(space, size, cid, ...) if #append == 0 then return tuple end - tuple = tuple:transform( #tuple, 0, unpack( append ) ) + tuple = tuple:transform( #tuple + 1, 0, unpack( append ) ) if #tuple - 1 > tonumber(size) then - tuple = tuple:transform( 1, #tuple - 1 - tonumber(size) ) + tuple = tuple:transform( 2, #tuple - 1 - tonumber(size) ) end return space:replace{tuple:unpack()} end diff --git a/test/big/tree_pk_multipart.result b/test/big/tree_pk_multipart.result index 42fdc0a697043e948bd72f7174401b2f295d06a1..e5653c703b8d6cc6178eae9d5bb522e9d29f41fa 100644 --- a/test/big/tree_pk_multipart.result +++ b/test/big/tree_pk_multipart.result @@ -267,11 +267,11 @@ space:delete{'Vincent', 'The Wolf!', 0} --- - ['Vincent', 'The Wolf!', 0, 'A please would be nice.'] ... -space:update({'Vincent', 'The Wolf!', 1}, {{ '=', 0, 'Updated' }, {'=', 4, 'New'}}) +space:update({'Vincent', 'The Wolf!', 1}, {{ '=', 1, 'Updated' }, {'=', 5, 'New'}}) --- - ['Updated', 'The Wolf!', 1, 'I said a please would be nice.', 'New'] ... -space:update({'Updated', 'The Wolf!', 1}, {{ '=', 0, 'Vincent'}, { '#', 4, 1 }}) +space:update({'Updated', 'The Wolf!', 1}, {{ '=', 1, 'Vincent'}, { '#', 5, 1 }}) --- - ['Vincent', 'The Wolf!', 1, 'I said a please would be nice.'] ... @@ -309,11 +309,11 @@ space:delete{'The Wolf!', 'Vincent', 1, 'Come again?'} -- -- Update test -- -space:update({'The Wolf!', 'Vincent', 1}, {{'=', 3, '<ooops>'}}) +space:update({'The Wolf!', 'Vincent', 1}, {{'=', 4, '<ooops>'}}) --- - ['The Wolf!', 'Vincent', 1, '<ooops>'] ... -space:update({'Vincent', 'The Wolf!', 1}, {{'=', 3, '<ooops>'}}) +space:update({'Vincent', 'The Wolf!', 1}, {{'=', 4, '<ooops>'}}) --- - ['Vincent', 'The Wolf!', 1, '<ooops>'] ... @@ -335,16 +335,16 @@ space.index['primary']:select({'The Wolf!', 'Vincent'}) help`s not appreciated then lotsa luck, gentlemen.'] ... -- try to update a nonexistent message -space:update({'Vincent', 'The Wolf!', 3}, {{'=', 3, '<ooops>'}}) +space:update({'Vincent', 'The Wolf!', 4}, {{'=', 4, '<ooops>'}}) --- ... -- try to update patrial defined key -space:update({'Vincent', 'The Wolf!'}, {{'=', 3, '<ooops>'}}) +space:update({'Vincent', 'The Wolf!'}, {{'=', 4, '<ooops>'}}) --- - error: Invalid key part count in an exact match (expected 3, got 2) ... -- try to update by invalid key -space:update({'The Wolf!', 'Vincent', 1, 'Come again?'}, {{'=', 3, '<ooops>'}}) +space:update({'The Wolf!', 'Vincent', 1, 'Come again?'}, {{'=', 4, '<ooops>'}}) --- - error: Invalid key part count in an exact match (expected 3, got 4) ... diff --git a/test/big/tree_pk_multipart.test.lua b/test/big/tree_pk_multipart.test.lua index ec12c7a9f5bbf620137c70ca6603410580de4796..d80454726878658c5438228ad9f634fbcec4b39d 100644 --- a/test/big/tree_pk_multipart.test.lua +++ b/test/big/tree_pk_multipart.test.lua @@ -78,8 +78,8 @@ space:delete{'The Wolf!', 'Vincent', 0} space:delete{'The Wolf!', 'Vincent', 3} space:delete{'Vincent', 'The Wolf!', 0} -space:update({'Vincent', 'The Wolf!', 1}, {{ '=', 0, 'Updated' }, {'=', 4, 'New'}}) -space:update({'Updated', 'The Wolf!', 1}, {{ '=', 0, 'Vincent'}, { '#', 4, 1 }}) +space:update({'Vincent', 'The Wolf!', 1}, {{ '=', 1, 'Updated' }, {'=', 5, 'New'}}) +space:update({'Updated', 'The Wolf!', 1}, {{ '=', 1, 'Vincent'}, { '#', 5, 1 }}) -- Checking Vincent's last messages space.index['primary']:select({'Vincent', 'The Wolf!'}) -- Checking The Wolf's last messages @@ -95,8 +95,8 @@ space:delete{'The Wolf!', 'Vincent', 1, 'Come again?'} -- -- Update test -- -space:update({'The Wolf!', 'Vincent', 1}, {{'=', 3, '<ooops>'}}) -space:update({'Vincent', 'The Wolf!', 1}, {{'=', 3, '<ooops>'}}) +space:update({'The Wolf!', 'Vincent', 1}, {{'=', 4, '<ooops>'}}) +space:update({'Vincent', 'The Wolf!', 1}, {{'=', 4, '<ooops>'}}) -- Checking Vincent's last messages space.index['primary']:select({'Vincent', 'The Wolf!'}) @@ -104,11 +104,11 @@ space.index['primary']:select({'Vincent', 'The Wolf!'}) space.index['primary']:select({'The Wolf!', 'Vincent'}) -- try to update a nonexistent message -space:update({'Vincent', 'The Wolf!', 3}, {{'=', 3, '<ooops>'}}) +space:update({'Vincent', 'The Wolf!', 4}, {{'=', 4, '<ooops>'}}) -- try to update patrial defined key -space:update({'Vincent', 'The Wolf!'}, {{'=', 3, '<ooops>'}}) +space:update({'Vincent', 'The Wolf!'}, {{'=', 4, '<ooops>'}}) -- try to update by invalid key -space:update({'The Wolf!', 'Vincent', 1, 'Come again?'}, {{'=', 3, '<ooops>'}}) +space:update({'The Wolf!', 'Vincent', 1, 'Come again?'}, {{'=', 4, '<ooops>'}}) space:len() space:truncate() space:len() diff --git a/test/box/alter.result b/test/box/alter.result index ef6754c69c7a155f917d8534b6702d0597033256..1d454079d4b400085b3c122fb1ee105c30f1e6c0 100644 --- a/test/box/alter.result +++ b/test/box/alter.result @@ -69,11 +69,11 @@ _space:delete{_index.id} -- -- Can't change properties of a space -- -_space:update({_space.id}, {{'+', 0, 1}}) +_space:update({_space.id}, {{'+', 1, 1}}) --- - error: 'Can''t modify space 280: space id is immutable' ... -_space:update({_space.id}, {{'+', 0, 2}}) +_space:update({_space.id}, {{'+', 1, 2}}) --- - error: 'Can''t modify space 280: space id is immutable' ... @@ -114,7 +114,7 @@ space:replace{0, 0} --- - error: 'No index #0 is defined in space 321' ... -space:update({0}, {{'+', 0, 1}}) +space:update({0}, {{'+', 1, 1}}) --- - error: 'No index #0 is defined in space 321' ... @@ -340,3 +340,34 @@ box.schema.create_space('auto_original', {id = auto.id}) auto:drop() --- ... +-- ------------------------------------------------------------------ +-- gh-281 Crash after rename + replace + delete with multi-part index +-- ------------------------------------------------------------------ +s = box.schema.create_space('space') +--- +... +s:create_index('primary', {unique = true, parts = {1, 'NUM', 2, 'STR'}}) +--- +... +s:insert{1, 'a'} +--- +- [1, 'a'] +... +box.space.space.index.primary:rename('secondary') +--- +... +box.space.space:replace{1,'The rain in Spain'} +--- +- [1, 'The rain in Spain'] +... +box.space.space:delete{1,'The rain in Spain'} +--- +- [1, 'The rain in Spain'] +... +box.space.space:select{} +--- +- - [1, 'a'] +... +s:drop() +--- +... diff --git a/test/box/alter.test.lua b/test/box/alter.test.lua index aa815766d579a7a4afa61937d5eac4a47939588c..5a2345ed07d9e26d1e7ba94c07cfa175930d8a9c 100644 --- a/test/box/alter.test.lua +++ b/test/box/alter.test.lua @@ -33,8 +33,8 @@ _space:delete{_index.id} -- -- Can't change properties of a space -- -_space:update({_space.id}, {{'+', 0, 1}}) -_space:update({_space.id}, {{'+', 0, 2}}) +_space:update({_space.id}, {{'+', 1, 1}}) +_space:update({_space.id}, {{'+', 1, 2}}) -- -- Create a space -- @@ -50,7 +50,7 @@ space.index[0] space:select{0} space:insert{0, 0} space:replace{0, 0} -space:update({0}, {{'+', 0, 1}}) +space:update({0}, {{'+', 1, 1}}) space:delete{0} t = _space:delete{space.id} space_deleted = box.space[t[1]] @@ -127,3 +127,15 @@ box.schema.space.drop('auto') auto2 box.schema.create_space('auto_original', {id = auto.id}) auto:drop() + +-- ------------------------------------------------------------------ +-- gh-281 Crash after rename + replace + delete with multi-part index +-- ------------------------------------------------------------------ +s = box.schema.create_space('space') +s:create_index('primary', {unique = true, parts = {1, 'NUM', 2, 'STR'}}) +s:insert{1, 'a'} +box.space.space.index.primary:rename('secondary') +box.space.space:replace{1,'The rain in Spain'} +box.space.space:delete{1,'The rain in Spain'} +box.space.space:select{} +s:drop() diff --git a/test/box/alter_limits.result b/test/box/alter_limits.result index 6a2a8374f64d69dd3df56cdc7afa87bec3192dc4..f03a38d38630c715a302a785cab82b37fb0201f8 100644 --- a/test/box/alter_limits.result +++ b/test/box/alter_limits.result @@ -145,7 +145,7 @@ s:delete{0} --- - error: 'No index #0 is defined in space 512' ... -s:update(0, {{"=", 0, 0}}) +s:update(0, {{"=", 1, 0}}) --- - error: 'No index #0 is defined in space 512' ... @@ -257,7 +257,7 @@ FIELD_COUNT = 4 --- ... -- increase field_count -- error -box.space['_space']:update(s.id, {{"=", FIELD_COUNT, 3}}) +box.space['_space']:update(s.id, {{"=", FIELD_COUNT + 1, 3}}) --- - error: 'Can''t modify space 512: can not change field count on a non-empty space' ... @@ -266,12 +266,12 @@ s:select{} - - [1, 2] ... -- decrease field_count - error -box.space['_space']:update(s.id, {{"=", FIELD_COUNT, 1}}) +box.space['_space']:update(s.id, {{"=", FIELD_COUNT + 1, 1}}) --- - error: 'Can''t modify space 512: can not change field count on a non-empty space' ... -- remove field_count - ok -box.space['_space']:update(s.id, {{"=", FIELD_COUNT, 0}}) +box.space['_space']:update(s.id, {{"=", FIELD_COUNT + 1, 0}}) --- - [512, 1, 'test', 'memtx', 0, ''] ... @@ -280,7 +280,7 @@ s:select{} - - [1, 2] ... -- increase field_count - error -box.space['_space']:update(s.id, {{"=", FIELD_COUNT, 3}}) +box.space['_space']:update(s.id, {{"=", FIELD_COUNT + 1, 3}}) --- - error: 'Can''t modify space 512: can not change field count on a non-empty space' ... @@ -292,7 +292,7 @@ s:select{} - [] ... -- set field_count of an empty space -box.space['_space']:update(s.id, {{"=", FIELD_COUNT, 3}}) +box.space['_space']:update(s.id, {{"=", FIELD_COUNT + 1, 3}}) --- - [512, 1, 'test', 'memtx', 3, ''] ... @@ -639,7 +639,6 @@ s.index.primary fieldno: 1 id: 0 type: HASH - idx: ' index 0' space: index: 0: *0 @@ -779,7 +778,7 @@ s.index.primary:select{} - ['Homevideo', 2011] - ['No such movie', 999] ... -box.space['_index']:update({s.id, s.index.year.id}, {{"=", 7, 'num'}}) +box.space['_index']:update({s.id, s.index.year.id}, {{"=", 8, 'num'}}) --- - [512, 1, 'year', 'tree', 0, 1, 1, 'num'] ... diff --git a/test/box/alter_limits.test.lua b/test/box/alter_limits.test.lua index 8bad5a54ebfaf5e03d29275874dbadd7c3d304aa..1406fec524dd76b1c4e1e354fdb551d12712eb1f 100644 --- a/test/box/alter_limits.test.lua +++ b/test/box/alter_limits.test.lua @@ -52,7 +52,7 @@ s = box.schema.create_space('tweedledum') s:insert{0} s:select{} s:delete{0} -s:update(0, {{"=", 0, 0}}) +s:update(0, {{"=", 1, 0}}) s:insert{0} s.index[0] s:truncate() @@ -91,19 +91,19 @@ s:select{} FIELD_COUNT = 4 -- increase field_count -- error -box.space['_space']:update(s.id, {{"=", FIELD_COUNT, 3}}) +box.space['_space']:update(s.id, {{"=", FIELD_COUNT + 1, 3}}) s:select{} -- decrease field_count - error -box.space['_space']:update(s.id, {{"=", FIELD_COUNT, 1}}) +box.space['_space']:update(s.id, {{"=", FIELD_COUNT + 1, 1}}) -- remove field_count - ok -box.space['_space']:update(s.id, {{"=", FIELD_COUNT, 0}}) +box.space['_space']:update(s.id, {{"=", FIELD_COUNT + 1, 0}}) s:select{} -- increase field_count - error -box.space['_space']:update(s.id, {{"=", FIELD_COUNT, 3}}) +box.space['_space']:update(s.id, {{"=", FIELD_COUNT + 1, 3}}) s:truncate() s:select{} -- set field_count of an empty space -box.space['_space']:update(s.id, {{"=", FIELD_COUNT, 3}}) +box.space['_space']:update(s.id, {{"=", FIELD_COUNT + 1, 3}}) s:select{} -- field_count actually works s:insert{3, 4} @@ -270,7 +270,7 @@ s:create_index('nodups', { type = 'tree', unique=true, parts = { 2, 'num'} }) -- change of non-unique index to unique: same effect s.index.year:alter({unique=true}) s.index.primary:select{} -box.space['_index']:update({s.id, s.index.year.id}, {{"=", 7, 'num'}}) +box.space['_index']:update({s.id, s.index.year.id}, {{"=", 8, 'num'}}) -- ambiguous field type s:create_index('str', { type = 'tree', unique = false, parts = { 2, 'str'}}) -- create index on a non-existing field diff --git a/test/box/call.result b/test/box/call.result index 0f05df40b861b10ba1de97bd29cb8ee46debc8bd..85128be8445e3e45f84b9430bcbb8533f011b301 100644 --- a/test/box/call.result +++ b/test/box/call.result @@ -326,7 +326,7 @@ call myinsert(3, 'old', 2) errcode: ER_TUPLE_FOUND errmsg: Duplicate key exists in unique index 0 ... -space:update({3}, {{'=', 0, 4}, {'=', 1, 'new'}}) +space:update({3}, {{'=', 1, 4}, {'=', 2, 'new'}}) --- - [4, 'new', 2] ... @@ -338,11 +338,11 @@ call space:select(4) --- - [4, 'new', 2] ... -space:update({4}, {{'+', 2, 1}}) +space:update({4}, {{'+', 3, 1}}) --- - [4, 'new', 3] ... -space:update({4}, {{'-', 2, 1}}) +space:update({4}, {{'-', 3, 1}}) --- - [4, 'new', 2] ... diff --git a/test/box/call.test.py b/test/box/call.test.py index 0cccbc9dc57de1cd81f63ecdf0389f3edc499553..30e9c12d2e6d87f64c0aa47120685540dad931af 100644 --- a/test/box/call.test.py +++ b/test/box/call.test.py @@ -108,11 +108,11 @@ sql("call space:delete(2)") sql("call myinsert(3, 'old', 2)") # test that insert produces a duplicate key error sql("call myinsert(3, 'old', 2)") -admin("space:update({3}, {{'=', 0, 4}, {'=', 1, 'new'}})") +admin("space:update({3}, {{'=', 1, 4}, {'=', 2, 'new'}})") sql("call space:get(4)") sql("call space:select(4)") -admin("space:update({4}, {{'+', 2, 1}})") -admin("space:update({4}, {{'-', 2, 1}})") +admin("space:update({4}, {{'+', 3, 1}})") +admin("space:update({4}, {{'-', 3, 1}})") sql("call space:get(4)") sql("call space:select(4)") admin("function field_x(key, field_index) return space:get(key)[field_index] end") diff --git a/test/box/errinj.result b/test/box/errinj.result index 98730488624ee0fe13b87b8b8bd779456c619633..b12dcf3861ef1132049fb4c0361740b3e3b92460 100644 --- a/test/box/errinj.result +++ b/test/box/errinj.result @@ -65,7 +65,7 @@ errinj.set("ERRINJ_WAL_IO", true) --- - ok ... -space:update(1, {{'=', 0, 2}}) +space:update(1, {{'=', 1, 2}}) --- - error: Failed to write to disk ... @@ -107,7 +107,7 @@ errinj.set("ERRINJ_WAL_ROTATE", true) --- - ok ... -space:update(1, {{'=', 0, 2}}) +space:update(1, {{'=', 1, 2}}) --- - error: Failed to write to disk ... @@ -122,7 +122,7 @@ errinj.set("ERRINJ_WAL_ROTATE", false) --- - ok ... -space:update(1, {{'=', 0, 2}}) +space:update(1, {{'=', 1, 2}}) --- - [2] ... diff --git a/test/box/errinj.test.lua b/test/box/errinj.test.lua index cfcdc98e19523f50413d37c729028267fddfc373..45bebb3f53f9415929048e0466303c325c8ef814 100644 --- a/test/box/errinj.test.lua +++ b/test/box/errinj.test.lua @@ -18,7 +18,7 @@ space:get{1} errinj.set("ERRINJ_WAL_IO", false) space:insert{1} errinj.set("ERRINJ_WAL_IO", true) -space:update(1, {{'=', 0, 2}}) +space:update(1, {{'=', 1, 2}}) space:get{1} space:get{2} errinj.set("ERRINJ_WAL_IO", false) @@ -31,11 +31,11 @@ space:get{1} errinj.set("ERRINJ_WAL_ROTATE", false) space:insert{1} errinj.set("ERRINJ_WAL_ROTATE", true) -space:update(1, {{'=', 0, 2}}) +space:update(1, {{'=', 1, 2}}) space:get{1} space:get{2} errinj.set("ERRINJ_WAL_ROTATE", false) -space:update(1, {{'=', 0, 2}}) +space:update(1, {{'=', 1, 2}}) space:get{1} space:get{2} errinj.set("ERRINJ_WAL_ROTATE", true) diff --git a/test/box/fiber.result b/test/box/fiber.result index fa4ab8e60ff2347455204a5683a5c2c9e527cfbb..a6f61ceb1fc557816885a27ae5dd08a148906269 100644 --- a/test/box/fiber.result +++ b/test/box/fiber.result @@ -143,26 +143,26 @@ space:insert{1953719668, 'old', 1684234849} --- - error: Duplicate key exists in unique index 0 ... -space:update(1953719668, {{'=', 0, 1936941424}, {'=', 1, 'new'}}) +space:update(1953719668, {{'=', 1, 1936941424}, {'=', 2, 'new'}}) --- - [1936941424, 'new', 1684234849] ... -space:update(1234567890, {{'+', 2, 1}}) +space:update(1234567890, {{'+', 3, 1}}) --- ... -space:update(1936941424, {{'+', 2, 1}}) +space:update(1936941424, {{'+', 3, 1}}) --- - [1936941424, 'new', 1684234850] ... -space:update(1936941424, {{'-', 2, 1}}) +space:update(1936941424, {{'-', 3, 1}}) --- - [1936941424, 'new', 1684234849] ... -space:update(1936941424, {{'-', 2, 1}}) +space:update(1936941424, {{'-', 3, 1}}) --- - [1936941424, 'new', 1684234848] ... -space:update(1936941424, {{'+', 2, 1}}) +space:update(1936941424, {{'+', 3, 1}}) --- - [1936941424, 'new', 1684234849] ... @@ -191,7 +191,7 @@ space:insert{1953719668, 'hello world'} --- - [1953719668, 'hello world'] ... -space:update(1953719668, {{'=', 1, 'bye, world'}}) +space:update(1953719668, {{'=', 2, 'bye, world'}}) --- - [1953719668, 'bye, world'] ... diff --git a/test/box/fiber.test.lua b/test/box/fiber.test.lua index 08d422aeac79b01dbfb5c65ef56ac3d693958ce5..87c8b1a03f84d3eca36ce9f838cb52365285a128 100644 --- a/test/box/fiber.test.lua +++ b/test/box/fiber.test.lua @@ -42,12 +42,12 @@ space:delete{1667655012} space:insert{1953719668, 'old', 1684234849} -- test that insert produces a duplicate key error space:insert{1953719668, 'old', 1684234849} -space:update(1953719668, {{'=', 0, 1936941424}, {'=', 1, 'new'}}) -space:update(1234567890, {{'+', 2, 1}}) -space:update(1936941424, {{'+', 2, 1}}) -space:update(1936941424, {{'-', 2, 1}}) -space:update(1936941424, {{'-', 2, 1}}) -space:update(1936941424, {{'+', 2, 1}}) +space:update(1953719668, {{'=', 1, 1936941424}, {'=', 2, 'new'}}) +space:update(1234567890, {{'+', 3, 1}}) +space:update(1936941424, {{'+', 3, 1}}) +space:update(1936941424, {{'-', 3, 1}}) +space:update(1936941424, {{'-', 3, 1}}) +space:update(1936941424, {{'+', 3, 1}}) space:delete{1936941424} -- must be read-only @@ -56,7 +56,7 @@ space:insert{1684234849} space:delete{1953719668} space:delete{1684234849} space:insert{1953719668, 'hello world'} -space:update(1953719668, {{'=', 1, 'bye, world'}}) +space:update(1953719668, {{'=', 2, 'bye, world'}}) space:delete{1953719668} -- test tuple iterators t = space:insert{1953719668} diff --git a/test/box/lua/fifo.lua b/test/box/lua/fifo.lua index b181c7c3b3cf438c054b3d2a8f69050062cb2681..ae1cd835b41daa11bba8824d5eb24babb1fa40ea 100644 --- a/test/box/lua/fifo.lua +++ b/test/box/lua/fifo.lua @@ -23,7 +23,7 @@ function fifo_push(space, name, val) elseif bottom == top then bottom = bottom + 1 end - return space:update({name}, {{'=', 1, top}, {'=', 2, bottom }, {'=', top - 1, val}}) + return space:update({name}, {{'=', 2, top}, {'=', 3, bottom }, {'=', top, val}}) end function fifo_top(space, name) fifo = find_or_create_fifo(space, name) diff --git a/test/box/net.box.result b/test/box/net.box.result index 6b99b180672543749b26b18180c883119902ffc4..6adeae9833e6ad5dcdc9199c128828bb152a57cd 100644 --- a/test/box/net.box.result +++ b/test/box/net.box.result @@ -213,7 +213,7 @@ type(foo) --- - table ... -space:update(123, {{'=', 1, 'test1-updated'}}) +space:update(123, {{'=', 2, 'test1-updated'}}) --- - [123, 'test1-updated', 'test2'] ... diff --git a/test/box/net.box.test.lua b/test/box/net.box.test.lua index b983d359f1b4df267b6dd3cdfd81f2a7e89b3a72..b4f98eed617fa03a11fece3f82d05f262cb6e2db 100644 --- a/test/box/net.box.test.lua +++ b/test/box/net.box.test.lua @@ -66,7 +66,7 @@ slf, foo = require('box.internal').call_loadproc('box.net.self:select') type(slf) type(foo) -space:update(123, {{'=', 1, 'test1-updated'}}) +space:update(123, {{'=', 2, 'test1-updated'}}) remote:update(space.id, 123, {{'=', 2, 'test2-updated'}}) space:insert{123, 'test1', 'test2'} diff --git a/test/box/schema.result b/test/box/schema.result index c647cae51c2aa943ab4818a011b0032b9676bc5a..6a658d3f0c727fca7b2f6a0295bf92f45e104053 100644 --- a/test/box/schema.result +++ b/test/box/schema.result @@ -16,69 +16,6 @@ t - 'name: tweedledum' - 'field_count: 0' ... -box.space[300] = 1 ---- -... -box.index.bind('abc', 'cde') ---- -- error: 'bad argument #1 to ''?'' (number expected, got string)' -... -box.index.bind(1, 2) ---- -- error: Space 1 does not exist -... -box.index.bind(0, 1) ---- -- error: 'No index #1 is defined in space 0' -... -box.index.bind(0, 0) ---- -- ' index 0' -... -#box.index.bind(0,0) ---- -- 0 -... -#box.space[0].index[0].idx ---- -- 0 -... -space:insert{1953719668} ---- -- [1953719668] -... -space:insert{1684234849} ---- -- [1684234849] -... -#box.index.bind(0,0) ---- -- 2 -... -#box.space[0].index[0].idx ---- -- 2 -... -space:delete{1953719668} ---- -- [1953719668] -... -#box.index.bind(0,0) ---- -- 1 -... -space:delete{1684234849} ---- -- [1684234849] -... -#box.space[0].index[0].idx ---- -- 0 -... -#box.index.bind(0,0) ---- -- 0 -... space:drop() --- ... diff --git a/test/box/schema.test.lua b/test/box/schema.test.lua index 364ba133f9bd608dca49235fb535386f0deaee13..9e589c1a24f032dd7c6a5ca620b006dfd3d60497 100644 --- a/test/box/schema.test.lua +++ b/test/box/schema.test.lua @@ -3,21 +3,5 @@ space:create_index('primary', { type = 'hash' }) t = {} for k,v in pairs(box.space[0]) do if type(v) ~= 'table' and type(v) ~= 'function' then table.insert(t, k..': '..tostring(v)) end end t -box.space[300] = 1 -box.index.bind('abc', 'cde') -box.index.bind(1, 2) -box.index.bind(0, 1) -box.index.bind(0, 0) -#box.index.bind(0,0) -#box.space[0].index[0].idx -space:insert{1953719668} -space:insert{1684234849} -#box.index.bind(0,0) -#box.space[0].index[0].idx -space:delete{1953719668} -#box.index.bind(0,0) -space:delete{1684234849} -#box.space[0].index[0].idx -#box.index.bind(0,0) space:drop() diff --git a/test/box/temp_spaces.result b/test/box/temp_spaces.result index 54cdd138b5b4ac55f0f1e6a1b463fc72078c8fe5..1fc7150176400cefce9d3ed93b79b199f4de1253 100644 --- a/test/box/temp_spaces.result +++ b/test/box/temp_spaces.result @@ -1,6 +1,6 @@ -- temporary spaces -- not a temporary -FLAGS = 5 +FLAGS = 6 --- ... s = box.schema.create_space('t', { temporary = true }) @@ -63,7 +63,7 @@ box.space[box.schema.SPACE_ID]:update(s.id, {{'=', FLAGS, ''}}) ... --# stop server default --# start server default -FLAGS = 5 +FLAGS = 6 --- ... s = box.space.t @@ -79,7 +79,7 @@ s.temporary ... box.space[box.schema.SPACE_ID]:update(s.id, {{'=', FLAGS, 'no-temporary'}}) --- -- [512, 1, 't', 'memtx', 0, 'no-temporary'] +- [512, 1, 't', 'memtx', 0, 'no-temporary', 'temporary'] ... s.temporary --- @@ -87,7 +87,7 @@ s.temporary ... box.space[box.schema.SPACE_ID]:update(s.id, {{'=', FLAGS, ',:asfda:temporary'}}) --- -- [512, 1, 't', 'memtx', 0, ',:asfda:temporary'] +- [512, 1, 't', 'memtx', 0, ',:asfda:temporary', 'temporary'] ... s.temporary --- @@ -95,7 +95,7 @@ s.temporary ... box.space[box.schema.SPACE_ID]:update(s.id, {{'=', FLAGS, 'a,b,c,d,e'}}) --- -- [512, 1, 't', 'memtx', 0, 'a,b,c,d,e'] +- [512, 1, 't', 'memtx', 0, 'a,b,c,d,e', 'temporary'] ... s.temporary --- @@ -103,7 +103,7 @@ s.temporary ... box.space[box.schema.SPACE_ID]:update(s.id, {{'=', FLAGS, 'temporary'}}) --- -- [512, 1, 't', 'memtx', 0, 'temporary'] +- [512, 1, 't', 'memtx', 0, 'temporary', 'temporary'] ... s.temporary --- @@ -118,7 +118,7 @@ s:insert{1, 2, 3} ... box.space[box.schema.SPACE_ID]:update(s.id, {{'=', FLAGS, 'temporary'}}) --- -- [512, 1, 't', 'memtx', 0, 'temporary'] +- [512, 1, 't', 'memtx', 0, 'temporary', 'temporary'] ... box.space[box.schema.SPACE_ID]:update(s.id, {{'=', FLAGS, 'no-temporary'}}) --- @@ -130,7 +130,7 @@ s:delete{1} ... box.space[box.schema.SPACE_ID]:update(s.id, {{'=', FLAGS, 'no-temporary'}}) --- -- [512, 1, 't', 'memtx', 0, 'no-temporary'] +- [512, 1, 't', 'memtx', 0, 'no-temporary', 'temporary'] ... s:drop() --- diff --git a/test/box/temp_spaces.test.lua b/test/box/temp_spaces.test.lua index 56830b91a3ec2c2b3736d6bee81b6c001f616555..82e4953fd05227aa035fbfc3d3db6560104a0a5f 100644 --- a/test/box/temp_spaces.test.lua +++ b/test/box/temp_spaces.test.lua @@ -1,6 +1,6 @@ -- temporary spaces -- not a temporary -FLAGS = 5 +FLAGS = 6 s = box.schema.create_space('t', { temporary = true }) s.temporary s:drop() @@ -27,7 +27,7 @@ box.space[box.schema.SPACE_ID]:update(s.id, {{'=', FLAGS, ''}}) --# stop server default --# start server default -FLAGS = 5 +FLAGS = 6 s = box.space.t s:len() diff --git a/test/box/tuple.result b/test/box/tuple.result index f0387de5fc6012b0005b8fcf499a13f0eb07836f..7989466aab480dd255e6ce96a08d6f57025c6b45 100644 --- a/test/box/tuple.result +++ b/test/box/tuple.result @@ -602,15 +602,15 @@ t = box.tuple.new({'a','b','c','a', -1, 0, 1, 2, true, 9223372036854775807ULL, ... t:find('a') --- -- 0 +- 1 ... t:find(1, 'a') --- -- 3 +- 4 ... t:find('c') --- -- 2 +- 3 ... t:find('xxxxx') --- @@ -622,12 +622,12 @@ t:find(1, 'xxxxx') ... t:findall('a') --- -- - 0 - - 3 +- - 1 + - 4 ... t:findall(1, 'a') --- -- - 3 +- - 4 ... t:findall('xxxxx') --- @@ -658,83 +658,83 @@ t:findall(100, 'xxxxx') --- t:find(2) --- -- 7 +- 8 ... t:findall(2) --- -- - 7 +- - 8 ... t:find(2ULL) --- -- 7 +- 8 ... t:findall(2ULL) --- -- - 7 +- - 8 ... t:find(2LL) --- -- 7 +- 8 ... t:findall(2LL) --- -- - 7 +- - 8 ... t:find(2) --- -- 7 +- 8 ... t:findall(2) --- -- - 7 +- - 8 ... t:find(-1) --- -- 4 +- 5 ... t:findall(-1) --- -- - 4 +- - 5 ... t:find(-1LL) --- -- 4 +- 5 ... t:findall(-1LL) --- -- - 4 +- - 5 ... t:find(true) --- -- 8 +- 9 ... t:findall(true) --- -- - 8 +- - 9 ... t:find(9223372036854775807LL) --- -- 9 +- 10 ... t:findall(9223372036854775807LL) --- -- - 9 +- - 10 ... t:find(9223372036854775807ULL) --- -- 9 +- 10 ... t:findall(9223372036854775807ULL) --- -- - 9 +- - 10 ... t:find(-9223372036854775807LL) --- -- 10 +- 11 ... t:findall(-9223372036854775807LL) --- -- - 10 +- - 11 ... -------------------------------------------------------------------------------- -- test msgpack.encode + tuple diff --git a/test/box/update.result b/test/box/update.result index 55e0a8fe226c4b3de3121ca067352f943660893b..89329cfdc859fbcf7cde378a8bdfc83f2dbf0077 100644 --- a/test/box/update.result +++ b/test/box/update.result @@ -9,29 +9,77 @@ s:insert{1000001, 1000002, 1000003, 1000004, 1000005} --- - [1000001, 1000002, 1000003, 1000004, 1000005] ... -s:update({1000001}, {{'#', 0, 1}}) +s:update({1000001}, {{'#', 1, 1}}) --- - [1000002, 1000003, 1000004, 1000005] ... -s:update({1000002}, {{'#', 0, 1}}) +s:update({1000002}, {{'#', 1, 1}}) --- - [1000003, 1000004, 1000005] ... -s:update({1000003}, {{'#', 0, 1}}) +s:update({1000003}, {{'#', 1, 1}}) --- - [1000004, 1000005] ... -s:update({1000004}, {{'#', 0, 1}}) +s:update({1000004}, {{'#', 1, 1}}) --- - [1000005] ... -s:update({1000005}, {{'#', 0, 1}}) +s:update({1000005}, {{'#', 1, 1}}) --- - error: Tuple field count 0 is less than required by a defined index (expected 1) ... s:truncate() --- ... +-- test arithmetic +s:insert{1, 0} +--- +- [1, 0] +... +s:update(1, {{'+', 2, 10}}) +--- +- [1, 10] +... +s:update(1, {{'+', 2, 15}}) +--- +- [1, 25] +... +s:update(1, {{'-', 2, 5}}) +--- +- [1, 20] +... +s:update(1, {{'-', 2, 20}}) +--- +- [1, 0] +... +s:update(1, {{'|', 2, 0x9}}) +--- +- [1, 9] +... +s:update(1, {{'|', 2, 0x6}}) +--- +- [1, 15] +... +s:update(1, {{'&', 2, 0xabcde}}) +--- +- [1, 14] +... +s:update(1, {{'&', 2, 0x2}}) +--- +- [1, 2] +... +s:update(1, {{'^', 2, 0xa2}}) +--- +- [1, 160] +... +s:update(1, {{'^', 2, 0xa2}}) +--- +- [1, 2] +... +s:truncate() +--- +... -- test delete multiple fields s:insert{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15} --- @@ -39,30 +87,30 @@ s:insert{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15} ... s:update({0}, {{'#', 42, 1}}) --- -- error: Field 42 was not found in the tuple +- error: Field 41 was not found in the tuple ... -s:update({0}, {{'#', 3, 'abirvalg'}}) +s:update({0}, {{'#', 4, 'abirvalg'}}) --- - error: 'Argument type in operation on field 3 does not match field type: expected a UINT' ... -s:update({0}, {{'#', 1, 1}, {'#', 3, 2}, {'#', 5, 1}}) +s:update({0}, {{'#', 2, 1}, {'#', 4, 2}, {'#', 6, 1}}) --- - [0, 2, 3, 6, 7, 9, 10, 11, 12, 13, 14, 15] ... -s:update({0}, {{'#', 3, 3}}) +s:update({0}, {{'#', 4, 3}}) --- - [0, 2, 3, 10, 11, 12, 13, 14, 15] ... -s:update({0}, {{'#', 4, 123456}}) +s:update({0}, {{'#', 5, 123456}}) --- - [0, 2, 3, 10] ... -s:update({0}, {{'#', 2, 4294967295}}) +s:update({0}, {{'#', 3, 4294967295}}) --- - [0, 2] ... -s:update({0}, {{'#', 1, 0}}) +s:update({0}, {{'#', 2, 0}}) --- - error: 'Field 1 UPDATE error: cannot delete 0 fields' ... @@ -74,15 +122,15 @@ s:insert{1, 3, 6, 9} --- - [1, 3, 6, 9] ... -s:update({1}, {{'!', 1, 2}}) +s:update({1}, {{'!', 2, 2}}) --- - [1, 2, 3, 6, 9] ... -s:update({1}, {{'!', 3, 4}, {'!', 3, 5}, {'!', 4, 7}, {'!', 4, 8}}) +s:update({1}, {{'!', 4, 4}, {'!', 4, 5}, {'!', 5, 7}, {'!', 5, 8}}) --- - [1, 2, 3, 5, 8, 7, 4, 6, 9] ... -s:update({1}, {{'!', 9, 10}, {'!', 9, 11}, {'!', 9, 12}}) +s:update({1}, {{'!', 10, 10}, {'!', 10, 11}, {'!', 10, 12}}) --- - [1, 2, 3, 5, 8, 7, 4, 6, 9, 12, 11, 10] ... @@ -93,7 +141,7 @@ s:insert{1, 'tuple'} --- - [1, 'tuple'] ... -s:update({1}, {{'#', 1, 1}, {'!', 1, 'inserted tuple'}, {'=', 2, 'set tuple'}}) +s:update({1}, {{'#', 2, 1}, {'!', 2, 'inserted tuple'}, {'=', 3, 'set tuple'}}) --- - [1, 'inserted tuple', 'set tuple'] ... @@ -104,11 +152,11 @@ s:insert{1, 'tuple'} --- - [1, 'tuple'] ... -s:update({1}, {{'=', 1, 'set tuple'}, {'!', 1, 'inserted tuple'}, {'#', 2, 1}}) +s:update({1}, {{'=', 2, 'set tuple'}, {'!', 2, 'inserted tuple'}, {'#', 3, 1}}) --- - [1, 'inserted tuple'] ... -s:update({1}, {{'!', 0, 3}, {'!', 0, 2}}) +s:update({1}, {{'!', 1, 3}, {'!', 1, 2}}) --- - [2, 3, 1, 'inserted tuple'] ... @@ -120,17 +168,17 @@ s:replace{1, 'field string value'} --- - [1, 'field string value'] ... -s:update({1}, {{'=', 1, 'new field string value'}, {'=', 2, 42}, {'=', 3, 0xdeadbeef}}) +s:update({1}, {{'=', 2, 'new field string value'}, {'=', 3, 42}, {'=', 4, 0xdeadbeef}}) --- - [1, 'new field string value', 42, 3735928559] ... -- test multiple update opearations on the same field -s:update({1}, {{'+', 2, 16}, {'&', 3, 0xffff0000}, {'|', 3, 0x0000a0a0}, {'^', 3, 0xffff00aa}}) +s:update({1}, {{'+', 3, 16}, {'&', 4, 0xffff0000}, {'|', 4, 0x0000a0a0}, {'^', 4, 0xffff00aa}}) --- - error: 'Field 3 UPDATE error: double update of the same field' ... -- test update splice operation -s:update({1}, {{':', 1, 0, 3, 'the newest'}}) +s:update({1}, {{':', 2, 0, 3, 'the newest'}}) --- - [1, 'the newest field string value', 42, 3735928559] ... @@ -138,20 +186,20 @@ s:replace{1953719668, 'something to splice'} --- - [1953719668, 'something to splice'] ... -s:update(1953719668, {{':', 1, 0, 4, 'no'}}) +s:update(1953719668, {{':', 2, 0, 4, 'no'}}) --- - [1953719668, 'nothing to splice'] ... -s:update(1953719668, {{':', 1, 0, 2, 'every'}}) +s:update(1953719668, {{':', 2, 0, 2, 'every'}}) --- - [1953719668, 'everything to splice'] ... -- check an incorrect offset -s:update(1953719668, {{':', 1, 100, 2, 'every'}}) +s:update(1953719668, {{':', 2, 100, 2, 'every'}}) --- - [1953719668, 'everything to spliceevery'] ... -s:update(1953719668, {{':', 1, -100, 2, 'every'}}) +s:update(1953719668, {{':', 2, -100, 2, 'every'}}) --- - error: 'Field SPLICE error: offset is out of bound' ... @@ -172,7 +220,7 @@ s:insert{1953719668, 'hello world'} --- - [1953719668, 'hello world'] ... -s:update(1953719668, {{'=', 1, 'bye, world'}}) +s:update(1953719668, {{'=', 2, 'bye, world'}}) --- - [1953719668, 'bye, world'] ... @@ -181,12 +229,24 @@ s:delete{1953719668} - [1953719668, 'bye, world'] ... -- test update delete operations -s:update({1}, {{'#', 3, 1}, {'#', 2, 1}}) +s:update({1}, {{'#', 4, 1}, {'#', 3, 1}}) --- ... -- test update insert operations -s:update({1}, {{'!', 1, 1}, {'!', 1, 2}, {'!', 1, 3}, {'!', 1, 4}}) +s:update({1}, {{'!', 2, 1}, {'!', 2, 2}, {'!', 2, 3}, {'!', 2, 4}}) +--- +... +s:truncate() +--- +... +-- s:update: zero field +s:insert{48} +--- +- [48] +... +s:update(48, {{'=', 0, 'hello'}}) --- +- error: Field 0 was not found in the tuple ... s:truncate() --- @@ -196,7 +256,7 @@ s:insert{1684234849} --- - [1684234849] ... -s:update({1684234849}, {{'#', 1, 1}}) +s:update({1684234849}, {{'#', 2, 1}}) --- - error: Field 1 was not found in the tuple ... @@ -212,15 +272,15 @@ s:update({1684234849}, {{'=', -1, 'push3'}}) --- - [1684234849, 'push1', 'push2', 'push3'] ... -s:update({1684234849}, {{'#', 1, 1}, {'=', -1, 'swap1'}}) +s:update({1684234849}, {{'#', 2, 1}, {'=', -1, 'swap1'}}) --- - [1684234849, 'push2', 'push3', 'swap1'] ... -s:update({1684234849}, {{'#', 1, 1}, {'=', -1, 'swap2'}}) +s:update({1684234849}, {{'#', 2, 1}, {'=', -1, 'swap2'}}) --- - [1684234849, 'push3', 'swap1', 'swap2'] ... -s:update({1684234849}, {{'#', 1, 1}, {'=', -1, 'swap3'}}) +s:update({1684234849}, {{'#', 2, 1}, {'=', -1, 'swap3'}}) --- - [1684234849, 'swap1', 'swap2', 'swap3'] ... diff --git a/test/box/update.test.lua b/test/box/update.test.lua index 4d532c3a0a04928340c549ea3a2def192d6ff699..4eec6c4af720c3daef27ce1222fa05a0212e4821 100644 --- a/test/box/update.test.lua +++ b/test/box/update.test.lua @@ -3,78 +3,97 @@ s:create_index('pk') -- test delete field s:insert{1000001, 1000002, 1000003, 1000004, 1000005} -s:update({1000001}, {{'#', 0, 1}}) -s:update({1000002}, {{'#', 0, 1}}) -s:update({1000003}, {{'#', 0, 1}}) -s:update({1000004}, {{'#', 0, 1}}) -s:update({1000005}, {{'#', 0, 1}}) +s:update({1000001}, {{'#', 1, 1}}) +s:update({1000002}, {{'#', 1, 1}}) +s:update({1000003}, {{'#', 1, 1}}) +s:update({1000004}, {{'#', 1, 1}}) +s:update({1000005}, {{'#', 1, 1}}) +s:truncate() + +-- test arithmetic +s:insert{1, 0} +s:update(1, {{'+', 2, 10}}) +s:update(1, {{'+', 2, 15}}) +s:update(1, {{'-', 2, 5}}) +s:update(1, {{'-', 2, 20}}) +s:update(1, {{'|', 2, 0x9}}) +s:update(1, {{'|', 2, 0x6}}) +s:update(1, {{'&', 2, 0xabcde}}) +s:update(1, {{'&', 2, 0x2}}) +s:update(1, {{'^', 2, 0xa2}}) +s:update(1, {{'^', 2, 0xa2}}) s:truncate() -- test delete multiple fields s:insert{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15} s:update({0}, {{'#', 42, 1}}) -s:update({0}, {{'#', 3, 'abirvalg'}}) -s:update({0}, {{'#', 1, 1}, {'#', 3, 2}, {'#', 5, 1}}) -s:update({0}, {{'#', 3, 3}}) -s:update({0}, {{'#', 4, 123456}}) -s:update({0}, {{'#', 2, 4294967295}}) -s:update({0}, {{'#', 1, 0}}) +s:update({0}, {{'#', 4, 'abirvalg'}}) +s:update({0}, {{'#', 2, 1}, {'#', 4, 2}, {'#', 6, 1}}) +s:update({0}, {{'#', 4, 3}}) +s:update({0}, {{'#', 5, 123456}}) +s:update({0}, {{'#', 3, 4294967295}}) +s:update({0}, {{'#', 2, 0}}) s:truncate() -- test insert field s:insert{1, 3, 6, 9} -s:update({1}, {{'!', 1, 2}}) -s:update({1}, {{'!', 3, 4}, {'!', 3, 5}, {'!', 4, 7}, {'!', 4, 8}}) -s:update({1}, {{'!', 9, 10}, {'!', 9, 11}, {'!', 9, 12}}) +s:update({1}, {{'!', 2, 2}}) +s:update({1}, {{'!', 4, 4}, {'!', 4, 5}, {'!', 5, 7}, {'!', 5, 8}}) +s:update({1}, {{'!', 10, 10}, {'!', 10, 11}, {'!', 10, 12}}) s:truncate() s:insert{1, 'tuple'} -s:update({1}, {{'#', 1, 1}, {'!', 1, 'inserted tuple'}, {'=', 2, 'set tuple'}}) +s:update({1}, {{'#', 2, 1}, {'!', 2, 'inserted tuple'}, {'=', 3, 'set tuple'}}) s:truncate() s:insert{1, 'tuple'} -s:update({1}, {{'=', 1, 'set tuple'}, {'!', 1, 'inserted tuple'}, {'#', 2, 1}}) -s:update({1}, {{'!', 0, 3}, {'!', 0, 2}}) +s:update({1}, {{'=', 2, 'set tuple'}, {'!', 2, 'inserted tuple'}, {'#', 3, 1}}) +s:update({1}, {{'!', 1, 3}, {'!', 1, 2}}) s:truncate() -- test update's assign opearations s:replace{1, 'field string value'} -s:update({1}, {{'=', 1, 'new field string value'}, {'=', 2, 42}, {'=', 3, 0xdeadbeef}}) +s:update({1}, {{'=', 2, 'new field string value'}, {'=', 3, 42}, {'=', 4, 0xdeadbeef}}) -- test multiple update opearations on the same field -s:update({1}, {{'+', 2, 16}, {'&', 3, 0xffff0000}, {'|', 3, 0x0000a0a0}, {'^', 3, 0xffff00aa}}) +s:update({1}, {{'+', 3, 16}, {'&', 4, 0xffff0000}, {'|', 4, 0x0000a0a0}, {'^', 4, 0xffff00aa}}) -- test update splice operation -s:update({1}, {{':', 1, 0, 3, 'the newest'}}) +s:update({1}, {{':', 2, 0, 3, 'the newest'}}) s:replace{1953719668, 'something to splice'} -s:update(1953719668, {{':', 1, 0, 4, 'no'}}) -s:update(1953719668, {{':', 1, 0, 2, 'every'}}) +s:update(1953719668, {{':', 2, 0, 4, 'no'}}) +s:update(1953719668, {{':', 2, 0, 2, 'every'}}) -- check an incorrect offset -s:update(1953719668, {{':', 1, 100, 2, 'every'}}) -s:update(1953719668, {{':', 1, -100, 2, 'every'}}) +s:update(1953719668, {{':', 2, 100, 2, 'every'}}) +s:update(1953719668, {{':', 2, -100, 2, 'every'}}) s:truncate() s:insert{1953719668, 'hello', 'october', '20th'}:unpack() s:truncate() s:insert{1953719668, 'hello world'} -s:update(1953719668, {{'=', 1, 'bye, world'}}) +s:update(1953719668, {{'=', 2, 'bye, world'}}) s:delete{1953719668} -- test update delete operations -s:update({1}, {{'#', 3, 1}, {'#', 2, 1}}) +s:update({1}, {{'#', 4, 1}, {'#', 3, 1}}) -- test update insert operations -s:update({1}, {{'!', 1, 1}, {'!', 1, 2}, {'!', 1, 3}, {'!', 1, 4}}) +s:update({1}, {{'!', 2, 1}, {'!', 2, 2}, {'!', 2, 3}, {'!', 2, 4}}) + +s:truncate() +-- s:update: zero field +s:insert{48} +s:update(48, {{'=', 0, 'hello'}}) s:truncate() -- s:update: push/pop fields s:insert{1684234849} -s:update({1684234849}, {{'#', 1, 1}}) +s:update({1684234849}, {{'#', 2, 1}}) s:update({1684234849}, {{'=', -1, 'push1'}}) s:update({1684234849}, {{'=', -1, 'push2'}}) s:update({1684234849}, {{'=', -1, 'push3'}}) -s:update({1684234849}, {{'#', 1, 1}, {'=', -1, 'swap1'}}) -s:update({1684234849}, {{'#', 1, 1}, {'=', -1, 'swap2'}}) -s:update({1684234849}, {{'#', 1, 1}, {'=', -1, 'swap3'}}) +s:update({1684234849}, {{'#', 2, 1}, {'=', -1, 'swap1'}}) +s:update({1684234849}, {{'#', 2, 1}, {'=', -1, 'swap2'}}) +s:update({1684234849}, {{'#', 2, 1}, {'=', -1, 'swap3'}}) s:update({1684234849}, {{'#', -1, 1}, {'=', -1, 'noop1'}}) s:update({1684234849}, {{'#', -1, 1}, {'=', -1, 'noop2'}}) s:update({1684234849}, {{'#', -1, 1}, {'=', -1, 'noop3'}})