diff --git a/.gitmodules b/.gitmodules index 3b7522d45fa654cd4617bddbe8e24dd9361c8de8..6afb7a5c39f9188c276840859b619c70bd5cdb5b 100644 --- a/.gitmodules +++ b/.gitmodules @@ -19,3 +19,6 @@ [submodule "third_party/sophia"] path = third_party/sophia url = git://github.com/tarantool/sophia.git +[submodule "third_party/luafun"] + path = third_party/luafun + url = https://github.com/rtsisyk/luafun.git diff --git a/client/tarantool/main.h b/client/tarantool/main.h index fd809f6d3611ae2d1e68506aabd30eb905db6ac4..1195a2735b4a1cc41801ea0feb0d61a90b15e907 100644 --- a/client/tarantool/main.h +++ b/client/tarantool/main.h @@ -33,8 +33,8 @@ #define TC_VERSION_MINOR "3" #define TC_DEFAULT_HOST "localhost" -#define TC_DEFAULT_PORT 33013 -#define TC_DEFAULT_ADMIN_PORT 33015 +#define TC_DEFAULT_PORT 3301 +#define TC_DEFAULT_ADMIN_PORT 3313 #define TC_DEFAULT_HISTORY_FILE ".tarantool_history" struct tarantool_client { diff --git a/cmake/BuildMisc.cmake b/cmake/BuildMisc.cmake index a78d9b049dbb1a10f80916a70e69d08e885d2fa9..1b12412d631221575879dd73ec83459fb610787c 100644 --- a/cmake/BuildMisc.cmake +++ b/cmake/BuildMisc.cmake @@ -3,6 +3,7 @@ macro(libmisc_build) set(misc_src ${PROJECT_SOURCE_DIR}/third_party/crc32.c + ${PROJECT_SOURCE_DIR}/third_party/sha1.c ${PROJECT_SOURCE_DIR}/third_party/proctitle.c ${PROJECT_SOURCE_DIR}/third_party/PMurHash.c ${PROJECT_SOURCE_DIR}/third_party/base64.c diff --git a/debian/etc/example.cfg b/debian/etc/example.cfg index 8c2bd75eb104980bd03d68b4ff07993ae97225e8..2c1dd18de7d148df414927a1755d0b2417dc1689 100644 --- a/debian/etc/example.cfg +++ b/debian/etc/example.cfg @@ -11,10 +11,7 @@ slab_alloc_arena = 0.1 # # Read only and read-write port. -primary_port = 33013 - -# Read-only port. -secondary_port = 33014 +primary_port = 3301 # ************* Debian option *********************** # count of file descriptors @@ -39,13 +36,7 @@ opt snapshot_period = 12 # # The port for administrative commands. # -admin_port = 33015 - -# -# directory that contains lua procedures -# (the first script must have name 'init.lua') -# -script_dir = /usr/share/tarantool/lua/ +admin_port = 3313 # # Each write ahead log contains this many rows. @@ -53,11 +44,3 @@ script_dir = /usr/share/tarantool/lua/ # the WAL and starts a new one. rows_per_wal = 50000 -# Define a simple space with 1 HASH-based -# primary key. -space[0].enabled = 1 -space[0].index[0].type = "HASH" -space[0].index[0].unique = 1 -space[0].index[0].key_field[0].fieldno = 0 -space[0].index[0].key_field[0].type = "NUM" - diff --git a/extra/schema_erase.lua b/extra/schema_erase.lua index ce0d2f094a1785d5a727f168cfd12d67c975cd31..6ee9acfee3d7e9cb7e70b39e1a94d3e6277ff820 100644 --- a/extra/schema_erase.lua +++ b/extra/schema_erase.lua @@ -1,6 +1,9 @@ _schema = box.space[box.schema.SCHEMA_ID] _space = box.space[box.schema.SPACE_ID] _index = box.space[box.schema.INDEX_ID] +_user = box.space[box.schema.USER_ID] +_func = box.space[box.schema.FUNC_ID] +_priv = box.space[box.schema.PRIV_ID] -- destroy everything - save snapshot produces an empty snapshot now _schema:run_triggers(false) _schema:truncate() @@ -8,4 +11,9 @@ _space:run_triggers(false) _space:truncate() _index:run_triggers(false) _index:truncate() - +_user:run_triggers(false) +_user:truncate() +_func:run_triggers(false) +_func:truncate() +_priv:run_triggers(false) +_priv:truncate() diff --git a/extra/schema_fill.lua b/extra/schema_fill.lua index b9170c45828a31bd01ac802bd0506a80fb7885ac..975caba8ce9f031ef7482e112631f84c067d44ba 100644 --- a/extra/schema_fill.lua +++ b/extra/schema_fill.lua @@ -1,20 +1,52 @@ +-- Super User ID +GUEST = 0 +ADMIN = 1 _schema = box.space[box.schema.SCHEMA_ID] _space = box.space[box.schema.SPACE_ID] _index = box.space[box.schema.INDEX_ID] +_func = box.space[box.schema.FUNC_ID] +_user = box.space[box.schema.USER_ID] +_priv = box.space[box.schema.PRIV_ID] -- define schema version _schema:insert{'version', 1, 6} -- define system spaces -_space:insert{_schema.n, 0, '_schema'} -_space:insert{_space.n, 0, '_space'} -_space:insert{_index.n, 0, '_index'} +_space:insert{_schema.n, ADMIN, '_schema', 'memtx', 0} +_space:insert{_space.n, ADMIN, '_space', 'memtx', 0} +_space:insert{_index.n, ADMIN, '_index', 'memtx', 0} +_space:insert{_func.n, ADMIN, '_func', 'memtx', 0} +_space:insert{_user.n, ADMIN, '_user', 'memtx', 0} +_space:insert{_priv.n, ADMIN, '_priv', 'memtx', 0} -- define indexes _index:insert{_schema.n, 0, 'primary', 'tree', 1, 1, 0, 'str'} +-- stick to the following convention: +-- prefer user id (owner id) in field #1 +-- prefer object name in field #2 +-- index on owner id is index #1 +-- index on object name is index #2 +-- -- space name is unique _index:insert{_space.n, 0, 'primary', 'tree', 1, 1, 0, 'num'} -_index:insert{_space.n, 1, 'name', 'tree', 1, 1, 2, 'str'} +_index:insert{_space.n, 1, 'owner', 'tree', 0, 1, 1, 'num'} +_index:insert{_space.n, 2, 'name', 'tree', 1, 1, 2, 'str'} -- index name is unique within a space _index:insert{_index.n, 0, 'primary', 'tree', 1, 2, 0, 'num', 1, 'num'} -_index:insert{_index.n, 1, 'name', 'tree', 1, 2, 0, 'num', 2, 'str'} +_index:insert{_index.n, 2, 'name', 'tree', 1, 2, 0, 'num', 2, 'str'} +-- user name and id are unique +_index:insert{_user.n, 0, 'primary', 'tree', 1, 1, 0, 'num'} +_index:insert{_user.n, 2, 'name', 'tree', 1, 1, 2, 'str'} +-- function name and id are unique +_index:insert{_func.n, 0, 'primary', 'tree', 1, 1, 0, 'num'} +_index:insert{_func.n, 1, 'owner', 'tree', 0, 1, 1, 'num'} +_index:insert{_func.n, 2, 'name', 'tree', 1, 1, 2, 'str'} +-- +-- space schema is: grantor id, user id, object_type, object_id, privilege +-- primary key: user id, object type, object id +_index:insert{_priv.n, 0, 'primary', 'tree', 1, 3, 1, 'num', 2, 'str', 3, 'num'} +_index:insert{_priv.n, 1, 'owner', 'tree', 0, 1, 1, 'num'} + -- +-- Pre-create user and grants +_user:insert{GUEST, '', 'guest'} +_user:insert{ADMIN, '', 'admin'} diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index bb1dc7719e8cdc3f06a13f2573d89156b5f25e9c..d1f8cac069e55235baf727a9e507f0bd2ff71501 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -23,6 +23,8 @@ set(lua_sources) lua_source(lua_sources lua/uuid.lua) lua_source(lua_sources lua/session.lua) lua_source(lua_sources lua/msgpackffi.lua) +file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/third_party/luafun) +lua_source(lua_sources ../third_party/luafun/fun.lua) set(bin_sources) bin_source(bin_sources bootstrap.snap bootstrap.h) @@ -70,6 +72,8 @@ set (common_sources say.c fio.c crc32.c + random.c + scramble.c tbuf.c opts.c cpu_feature.c diff --git a/src/admin.cc b/src/admin.cc index bcb22099ed37a5e9db18a5c8d7f4cec8fe0a14aa..15ee0af3249ff3c82d572079d33946be69ac68e0 100644 --- a/src/admin.cc +++ b/src/admin.cc @@ -88,7 +88,9 @@ admin_handler(va_list ap) * a remote client: it's used in Lua * stored procedures. */ - (void) session_create(coio.fd, *(uint64_t *) addr); + + session_set_user(session_create(coio.fd, *(uint64_t *) addr), + ADMIN, ADMIN); for (;;) { if (admin_dispatch(&coio, iobuf, L) < 0) diff --git a/src/bootstrap.snap b/src/bootstrap.snap index c392eda096eb41250bec15c2e5d69636511e60a6..70257782f59a443cdd8e51a3358586f571749bbd 100644 Binary files a/src/bootstrap.snap and b/src/bootstrap.snap differ diff --git a/src/box/CMakeLists.txt b/src/box/CMakeLists.txt index 0dac09813a5628e03946c0167fd40954ae6617c6..980678e2f7cb40ed45900db3095211b43a5551f1 100644 --- a/src/box/CMakeLists.txt +++ b/src/box/CMakeLists.txt @@ -32,6 +32,8 @@ tarantool_module("box" request.cc txn.cc box.cc + access.cc + authentication.cc ${lua_sources} lua/call.cc lua/tuple.cc diff --git a/src/box/access.cc b/src/box/access.cc new file mode 100644 index 0000000000000000000000000000000000000000..a541a32345621e1883ad39323371adba77d4fb69 --- /dev/null +++ b/src/box/access.cc @@ -0,0 +1,174 @@ +/* + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * 1. Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * <COPYRIGHT HOLDER> OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include "access.h" +#include "assoc.h" +#include "schema.h" + +struct user users[BOX_USER_MAX]; +/** Bitmap type for used/unused authentication token map. */ +typedef unsigned long user_map_t; + +/** A map to quickly look up free slots in users[] array. */ +user_map_t user_map[BOX_USER_MAX/(CHAR_BIT*sizeof(user_map_t)) + 1]; + +int user_map_idx = 0; +struct mh_i32ptr_t *user_registry; + +uint8_t +user_map_get_slot() +{ + uint32_t idx = __builtin_ffsl(user_map[user_map_idx]); + while (idx == 0) { + if (user_map_idx == sizeof(user_map)/sizeof(*user_map)) + panic("Out of slots for new users"); + + user_map_idx++; + idx = __builtin_ffsl(user_map[user_map_idx]); + } + /* + * find-first-set returns bit index starting from 1, + * or 0 if no bit is set. Rebase the index to offset 0. + */ + idx--; + if (idx == BOX_USER_MAX) { + /* A cap on the number of users was reached. */ + tnt_raise(LoggedError, ER_USER_MAX, BOX_USER_MAX); + } + user_map[user_map_idx] ^= ((user_map_t) 1) << idx; + idx += user_map_idx * sizeof(*user_map) * CHAR_BIT; + assert(idx < UINT8_MAX); + return idx; +} + +void +user_map_put_slot(uint8_t auth_token) +{ + memset(users + auth_token, 0, sizeof(struct user)); + uint32_t bit_no = auth_token & (sizeof(user_map_t) * CHAR_BIT - 1); + auth_token /= sizeof(user_map_t) * CHAR_BIT; + user_map[auth_token] |= ((user_map_t) 1) << bit_no; + if (auth_token > user_map_idx) + user_map_idx = auth_token; +} + +const char * +priv_name(uint8_t access) +{ + if (access & PRIV_R) + return "Read"; + if (access & PRIV_W) + return "Write"; + return "Execute"; +} + +void +user_cache_replace(struct user *user) +{ + struct user *old = user_cache_find(user->uid); + if (old == NULL) { + uint8_t auth_token = user_map_get_slot(); + old = users + auth_token; + assert(old->auth_token == 0); + old->auth_token = auth_token; + } + user->auth_token = old->auth_token; + *old = *user; + struct mh_i32ptr_node_t node = { old->uid, old }; + mh_i32ptr_put(user_registry, &node, NULL, NULL); +} + +void +user_cache_delete(uint32_t uid) +{ + struct user *old = user_cache_find(uid); + if (old) { + assert(old->auth_token > ADMIN); + user_map_put_slot(old->auth_token); + old->auth_token = 0; + old->uid = 0; + mh_i32ptr_del(user_registry, uid, NULL); + } +} + +/** Find user by id. */ +struct user * +user_cache_find(uint32_t uid) +{ + mh_int_t k = mh_i32ptr_find(user_registry, uid, NULL); + if (k == mh_end(user_registry)) + return NULL; + return (struct user *) mh_i32ptr_node(user_registry, k)->val; +} + +/** Find user by name. */ +struct user * +user_by_name(const char *name, uint32_t len) +{ + uint32_t uid = schema_find_id(SC_USER_ID, 2, name, len); + return user_cache_find(uid); +} + +void +user_cache_init() +{ + memset(user_map, 0xFF, sizeof(user_map)); + user_registry = mh_i32ptr_new(); + /* + * Solve a chicken-egg problem: + * we need a functional user cache entry for superuser to + * perform recovery, but the superuser credentials are + * stored in the snapshot. So, pre-create cache entries + * for 'guest' and 'admin' users here, they will be + * updated with snapshot contents during recovery. + */ + struct user guest; + memset(&guest, 0, sizeof(guest)); + snprintf(guest.name, sizeof(guest.name), "guest"); + user_cache_replace(&guest); + /* 0 is the auth token and user id by default. */ + assert(guest.auth_token == GUEST && + guest.uid == GUEST && + users[guest.auth_token].uid == guest.uid); + + struct user admin; + memset(&admin, 0, sizeof(admin)); + snprintf(admin.name, sizeof(admin.name), "admin"); + admin.uid = ADMIN; + user_cache_replace(&admin); + /* ADMIN is both the auth token and user id for 'admin' user. */ + assert(admin.auth_token == ADMIN && + users[admin.auth_token].uid == ADMIN); +} + +void +user_cache_free() +{ + if (user_registry) + mh_i32ptr_delete(user_registry); +} diff --git a/src/box/access.h b/src/box/access.h new file mode 100644 index 0000000000000000000000000000000000000000..ad53e9165230fc688572d1647093ba5f846714e1 --- /dev/null +++ b/src/box/access.h @@ -0,0 +1,153 @@ +#ifndef INCLUDES_TARANTOOL_BOX_ACCESS_H +#define INCLUDES_TARANTOOL_BOX_ACCESS_H +/* + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * 1. Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * <COPYRIGHT HOLDER> OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include "iproto_constants.h" +#include "key_def.h" +#include "scramble.h" +#include "fiber.h" +#include "session.h" + +enum { + /* SELECT */ + PRIV_R = 1, + /* INSERT, UPDATE, DELETE, REPLACE */ + PRIV_W = 2, + /* CALL */ + PRIV_X = 4, +}; + +/* Privilege name for error messages */ +const char * +priv_name(uint8_t access); + +/** + * A cache entry for an existing user. Entries for all existing + * users are always present in the cache. The entry is maintained + * in sync with _user and _priv system spaces by system space + * triggers. + * @sa alter.cc + */ +struct user { + /** User id. */ + uint32_t uid; + /** User password - hash2 */ + char hash2[SCRAMBLE_SIZE]; + /** User name - for error messages and debugging */ + char name[BOX_NAME_MAX + 1]; + /** Global privileges this user has on the universe. */ + uint8_t universal_access; + /** An id in users[] array to quickly find user */ + uint8_t auth_token; +}; + +/** + * For best performance, all users are maintained in this array. + * Position in the array is store in user->auth_token and also + * in session->auth_token. This way it's easy to quickly find + * the current user of the session. + * An auth token, instead of a direct pointer, is stored in the + * session because it make dropping of a signed in user safe. + * The same auth token (index in an array) + * is also used to find out user privileges when accessing stored + * objects, such as spaces and functions. + */ +extern struct user users[]; + +/* + * Insert or update user object (a cache entry + * for user). + * This is called from a trigger on _user table + * and from trigger on _priv table, (in the latter + * case, only when making a grant on the universe). + * + * If a user already exists, update it, otherwise + * find space in users[] array and store the new + * user in it. Update user->auth_token + * with an index in the users[] array. + */ +void +user_cache_replace(struct user *user); + +/** + * Find a user by id and delete it from the + * users cache. + */ +void +user_cache_delete(uint32_t uid); + +/** Find user by id. */ +struct user * +user_cache_find(uint32_t uid); + +/* Find a user by name. Used by authentication. */ +struct user * +user_by_name(const char *name, uint32_t len); + +/** + * Return the current user. + * + * @todo: this doesn't account for the case when a user + * was dropped, its slot in users array was reused + * for a new user, and some sessions exist which still + * use the old auth_token. In this case, already + * authenticated sessions use grants of the new user, + * not the old one. + * + * This can be easily fixed by checking that uid of the + * user found by means of auth_token matches the uid + * stored in the session, and invalidating the session + * auth_token when it doesn't. + * + * Alternatively, one could invalidate the session + * auth_token whenever sc_version changes. Alternatively, + * one could invalidate auth_token in all sessions whenever + * any tuple in _user or _priv spaces is modified. + * + * None of these 3 solutions seems to be worth the while + * at the moment. + */ +#define user() \ +({ \ + struct session *s = fiber()->session; \ + uint8_t auth_token = s ? s->auth_token : (int) ADMIN; \ + struct user *u = &users[auth_token]; \ + assert(u->auth_token == auth_token); \ + u; \ +}) + +/** Initialize the user cache and access control subsystem. */ +void +user_cache_init(); + +/** Cleanup the user cache and access control subsystem */ +void +user_cache_free(); + +#endif /* INCLUDES_TARANTOOL_BOX_ACCESS_H */ diff --git a/src/box/alter.cc b/src/box/alter.cc index 3ff8239331f35f3c863f000d71423ae5f44166f1..74bb31ff5dc9d398156c3ef9240d21cb67cab31b 100644 --- a/src/box/alter.cc +++ b/src/box/alter.cc @@ -28,28 +28,54 @@ */ #include "alter.h" #include "schema.h" +#include "access.h" #include "space.h" #include "txn.h" #include "tuple.h" #include "fiber.h" /* for gc_pool */ #include "scoped_guard.h" +#include "third_party/base64.h" #include <new> /* for placement new */ #include <stdio.h> /* snprintf() */ #include <ctype.h> /** _space columns */ -#define ID 0 -#define ARITY 1 -#define NAME 2 -#define FLAGS 3 +#define ID 0 +#define UID 1 +#define NAME 2 +#define ENGINE 3 +#define ARITY 4 +#define FLAGS 5 /** _index columns */ -#define INDEX_ID 1 -#define INDEX_TYPE 3 -#define INDEX_IS_UNIQUE 4 -#define INDEX_PART_COUNT 5 +#define INDEX_ID 1 +#define INDEX_TYPE 3 +#define INDEX_IS_UNIQUE 4 +#define INDEX_PART_COUNT 5 + +/** _user columns */ +#define AUTH_DATA 3 + +/** _priv columns */ +#define PRIV_OBJECT_TYPE 2 +#define PRIV_OBJECT_ID 3 +#define PRIV_ACCESS 4 /* {{{ Auxiliary functions and methods. */ +void +access_check_ddl(uint32_t owner_uid) +{ + struct user *user = user(); + /* + * Only the creator of the space or superuser can modify + * the space, since we don't have ALTER privilege. + */ + if (owner_uid != user->uid && user->uid != ADMIN) { + tnt_raise(ClientError, ER_ACCESS_DENIED, + "Write", user->name); + } +} + /** * Create a key_def object from a record in _index * system space. @@ -125,12 +151,15 @@ space_def_create_from_tuple(struct space_def *def, struct tuple *tuple, uint32_t errcode) { def->id = tuple_field_u32(tuple, ID); + def->uid = tuple_field_u32(tuple, UID); def->arity = tuple_field_u32(tuple, ARITY); - int n = snprintf(def->name, sizeof(def->name), + int namelen = snprintf(def->name, sizeof(def->name), "%s", tuple_field_cstr(tuple, NAME)); + int engine_namelen = snprintf(def->engine_name, sizeof(def->engine_name), + "%s", tuple_field_cstr(tuple, ENGINE)); space_def_init_flags(def, tuple); - space_def_check(def, n, errcode); + space_def_check(def, namelen, engine_namelen, errcode); if (errcode != ER_ALTER_SPACE && def->id >= SC_SYSTEM_ID_MIN && def->id < SC_SYSTEM_ID_MAX) { say_warn("\n" @@ -143,6 +172,7 @@ space_def_create_from_tuple(struct space_def *def, struct tuple *tuple, (unsigned) SC_SYSTEM_ID_MIN, (unsigned) SC_SYSTEM_ID_MAX); } + access_check_ddl(def->uid); } /* }}} */ @@ -413,6 +443,8 @@ alter_space_do(struct txn *txn, struct alter_space *alter, * the recovery phase. */ alter->new_space->engine = alter->old_space->engine; + memcpy(alter->new_space->access, alter->old_space->access, + sizeof(alter->old_space->access)); /* * Change the new space: build the new index, rename, * change arity. @@ -455,6 +487,11 @@ ModifySpace::prepare(struct alter_space *alter) (unsigned) space_id(alter->old_space), "space id is immutable"); + if (strcmp(def.engine_name, alter->old_space->def.engine_name) != 0) + tnt_raise(ClientError, ER_ALTER_SPACE, + (unsigned) space_id(alter->old_space), + "can not change space engine"); + if (def.arity != 0 && def.arity != alter->old_space->def.arity && alter->old_space->engine.state != READY_NO_KEYS && @@ -940,6 +977,7 @@ on_replace_dd_space(struct trigger * /* trigger */, void *event) */ trigger_set(&txn->on_rollback, &drop_space_trigger); } else if (new_tuple == NULL) { /* DELETE */ + access_check_ddl(old_space->def.uid); /* Verify that the space is empty (has no indexes) */ if (old_space->index_count) { tnt_raise(ClientError, ER_DROP_SPACE, @@ -1016,7 +1054,8 @@ on_replace_dd_index(struct trigger * /* trigger */, void *event) uint32_t id = tuple_field_u32(old_tuple ? old_tuple : new_tuple, ID); uint32_t iid = tuple_field_u32(old_tuple ? old_tuple : new_tuple, INDEX_ID); - struct space *old_space = space_find(id); + struct space *old_space = space_cache_find(id); + access_check_ddl(old_space->def.uid); Index *old_index = space_index(old_space, iid); struct alter_space *alter = alter_space_new(); auto scoped_guard = @@ -1040,6 +1079,417 @@ on_replace_dd_index(struct trigger * /* trigger */, void *event) scoped_guard.is_active = false; } +/* {{{ access control */ + +/** True if the space has records identified by key 'uid' + * Uses 'owner' index. + */ +bool +space_has_data(uint32_t id, uint32_t iid, uint32_t uid) +{ + struct space *space = space_by_id(id); + if (space == NULL) + return false; + + Index *index = space_index(space, iid); + if (index == NULL) + return false; + assert(strcmp(index->key_def->name, "owner") == 0); + struct iterator *it = index->position(); + char key[6]; + assert(mp_sizeof_uint(SC_SYSTEM_ID_MIN) <= sizeof(key)); + mp_encode_uint(key, uid); + + index->initIterator(it, ITER_EQ, key, 1); + if (it->next(it)) + return true; + return false; +} + +bool +user_has_data(uint32_t uid) +{ + uint32_t spaces[] = { SC_SPACE_ID, SC_FUNC_ID, SC_PRIV_ID }; + uint32_t *end = spaces + sizeof(spaces)/sizeof(*spaces); + for (uint32_t *i = spaces; i < end; i++) { + if (space_has_data(*i, 1, uid)) + return true; + } + return false; +} + +/** Supposedly a user may have many authentication mechanisms + * defined, but for now we only support chap-sha1. Get + * password of chap-sha1 from the _user space. + */ + +void +user_fill_auth_data(struct user *user, const char *auth_data) +{ + if (mp_typeof(*auth_data) != MP_MAP) + return; + uint32_t mech_count = mp_decode_map(&auth_data); + for (uint32_t i = 0; i < mech_count; i++) { + if (mp_typeof(*auth_data) != MP_STR) { + mp_next(&auth_data); + mp_next(&auth_data); + continue; + } + uint32_t len; + const char *mech_name = mp_decode_str(&auth_data, &len); + if (strncasecmp(mech_name, "chap-sha1", 9) != 0) { + mp_next(&auth_data); + continue; + } + const char *hash2_base64 = mp_decode_str(&auth_data, &len); + if (len != 0 && len != SCRAMBLE_BASE64_SIZE) { + tnt_raise(ClientError, ER_CREATE_USER, + user->name, "invalid user password"); + } + base64_decode(hash2_base64, len, user->hash2, + sizeof(user->hash2)); + break; + } +} + +void +user_create_from_tuple(struct user *user, struct tuple *tuple) +{ + /* In case user password is empty, fill it with \0 */ + memset(user, 0, sizeof(*user)); + user->uid = tuple_field_u32(tuple, ID); + const char *name = tuple_field_cstr(tuple, NAME); + uint32_t len = strlen(name); + if (len >= sizeof(user->name)) { + tnt_raise(ClientError, ER_CREATE_USER, + name, "user name is too long"); + } + snprintf(user->name, sizeof(user->name), "%s", name); + /* + * AUTH_DATA field in _user space should contain + * chap-sha1 -> base64_encode(sha1(sha1(password)). + * Check for trivial errors when a plain text + * password is saved in this field instead. + */ + if (tuple_arity(tuple) > AUTH_DATA) { + const char *auth_data = tuple_field(tuple, AUTH_DATA); + user_fill_auth_data(user, auth_data); + } +} + +static void +user_cache_remove_user(struct trigger * /* trigger */, void *event) +{ + struct txn *txn = (struct txn *) event; + uint32_t uid = tuple_field_u32(txn->old_tuple ? + txn->old_tuple : txn->new_tuple, ID); + user_cache_delete(uid); +} + +static struct trigger drop_user_trigger = + { rlist_nil, user_cache_remove_user, NULL, NULL }; + +static void +user_cache_replace_user(struct trigger * /* trigger */, void *event) +{ + struct txn *txn = (struct txn *) event; + struct user user; + user_create_from_tuple(&user, txn->new_tuple); + user_cache_replace(&user); +} + +static struct trigger modify_user_trigger = + { rlist_nil, user_cache_replace_user, NULL, NULL }; + +/** + * A trigger invoked on replace in the user table. + */ +static void +on_replace_dd_user(struct trigger * /* trigger */, void *event) +{ + struct txn *txn = (struct txn *) event; + struct tuple *old_tuple = txn->old_tuple; + struct tuple *new_tuple = txn->new_tuple; + + uint32_t uid = tuple_field_u32(old_tuple ? + old_tuple : new_tuple, ID); + struct user *old_user = user_cache_find(uid); + if (new_tuple != NULL && old_user == NULL) { /* INSERT */ + struct user user; + user_create_from_tuple(&user, new_tuple); + (void) user_cache_replace(&user); + trigger_set(&txn->on_rollback, &drop_user_trigger); + } else if (new_tuple == NULL) { /* DELETE */ + access_check_ddl(uid); + /* Can't drop guest or super user */ + if (uid == GUEST || uid == ADMIN) { + tnt_raise(ClientError, ER_DROP_USER, + old_user->name, + "the user is a system user"); + } + /* + * Can only delete user if it has no spaces, + * no functions and no grants. + */ + if (user_has_data(uid)) { + tnt_raise(ClientError, ER_DROP_USER, + old_user->name, "the user has objects"); + } + trigger_set(&txn->on_commit, &drop_user_trigger); + } else { /* UPDATE, REPLACE */ + assert(old_user != NULL && new_tuple != NULL); + /* + * Allow change of user properties (name, + * password) but first check that the change is + * correct. + */ + struct user user; + user_create_from_tuple(&user, new_tuple); + trigger_set(&txn->on_commit, &modify_user_trigger); + } +} + +/** Create a function definition from tuple. */ +static void +func_def_create_from_tuple(struct func_def *func, struct tuple *tuple) +{ + func->fid = tuple_field_u32(tuple, ID); + func->uid = tuple_field_u32(tuple, UID); + const char *name = tuple_field_cstr(tuple, NAME); + uint32_t len = strlen(name); + if (len >= sizeof(func->name)) { + tnt_raise(ClientError, ER_CREATE_FUNCTION, + name, "function name is too long"); + } + snprintf(func->name, sizeof(func->name), "%s", name); +} + +/** Remove a function from function cache */ +static void +func_cache_remove_func(struct trigger * /* trigger */, void *event) +{ + struct txn *txn = (struct txn *) event; + uint32_t fid = tuple_field_u32(txn->old_tuple ? + txn->old_tuple : txn->new_tuple, ID); + func_cache_delete(fid); +} + +static struct trigger drop_func_trigger = + { rlist_nil, func_cache_remove_func, NULL, NULL }; + +/** Remove a function from function cache */ +static void +func_cache_replace_func(struct trigger * /* trigger */, void *event) +{ + struct txn *txn = (struct txn *) event; + struct func_def func; + func_def_create_from_tuple(&func, txn->new_tuple); + func_cache_replace(&func); +} + +static struct trigger modify_func_trigger = + { rlist_nil, func_cache_replace_func, NULL, NULL }; + +/** + * A trigger invoked on replace in a space containing + * functions on which there were defined any grants. + */ +static void +on_replace_dd_func(struct trigger * /* trigger */, void *event) +{ + struct func_def func; + struct txn *txn = (struct txn *) event; + struct tuple *old_tuple = txn->old_tuple; + struct tuple *new_tuple = txn->new_tuple; + + uint32_t fid = tuple_field_u32(old_tuple ? + old_tuple : new_tuple, ID); + struct func_def *old_func = func_by_id(fid); + if (new_tuple != NULL && old_func == NULL) { /* INSERT */ + func_def_create_from_tuple(&func, new_tuple); + func_cache_replace(&func); + trigger_set(&txn->on_rollback, &drop_func_trigger); + } else if (new_tuple == NULL) { /* DELETE */ + func_def_create_from_tuple(&func, old_tuple); + /* + * Can only delete func if you're the one + * who created it or a superuser. + */ + access_check_ddl(func.uid); + /* @todo can only delete func if it has no grants */ + trigger_set(&txn->on_commit, &drop_func_trigger); + } else { /* UPDATE, REPLACE */ + func_def_create_from_tuple(&func, new_tuple); + access_check_ddl(func.uid); + trigger_set(&txn->on_commit, &modify_func_trigger); + } +} + +/** + * Create a privilege definition from tuple. + */ +static void +priv_def_create_from_tuple(struct priv_def *priv, struct tuple *tuple) +{ + priv->grantor_id = tuple_field_u32(tuple, ID); + priv->grantee_id = tuple_field_u32(tuple, UID); + const char *object_type = tuple_field_cstr(tuple, PRIV_OBJECT_TYPE); + priv->object_id = tuple_field_u32(tuple, PRIV_OBJECT_ID); + priv->object_type = schema_object_type(object_type); + if (priv->object_type == SC_UNKNOWN) { + tnt_raise(ClientError, ER_UNKNOWN_SCHEMA_OBJECT, + object_type); + } + priv->access = tuple_field_u32(tuple, PRIV_ACCESS); +} + +/* + * This function checks that: + * - a privilege is granted from an existing user to an existing + * user on an existing object + * - the grantor has the right to grant (is the owner of the object) + * + * @XXX Potentially there is a race in case of rollback, since an + * object can be changed during WAL write. + * In the future we must protect grant/revoke with a logical lock. + */ +static void +priv_def_check(struct priv_def *priv) +{ + struct user *grantor = user_cache_find(priv->grantor_id); + struct user *grantee = user_cache_find(priv->grantee_id); + if (grantor == NULL) { + tnt_raise(ClientError, ER_NO_SUCH_USER, + int2str(priv->grantor_id)); + } + if (grantee == NULL) { + tnt_raise(ClientError, ER_NO_SUCH_USER, + int2str(priv->grantee_id)); + } + access_check_ddl(grantor->uid); + switch (priv->object_type) { + case SC_UNIVERSE: + if (grantor->uid != ADMIN) { + tnt_raise(ClientError, ER_ACCESS_DENIED, + priv_name(priv->access), grantor->name); + } + break; + case SC_SPACE: + { + struct space *space = space_cache_find(priv->object_id); + if (space->def.uid != grantor->uid) { + tnt_raise(ClientError, ER_ACCESS_DENIED, + priv_name(priv->access), grantor->name); + } + break; + } + case SC_FUNCTION: + { + struct func_def *func = func_cache_find(priv->object_id); + if (func->uid != grantor->uid) { + tnt_raise(ClientError, ER_ACCESS_DENIED, + priv_name(priv->access), grantor->name); + } + break; + } + default: + break; + } +} + +/** + * Update a metadata cache object with the new access + * data. + */ +static void +grant_or_revoke(struct priv_def *priv) +{ + struct user *grantee = user_cache_find(priv->grantee_id); + if (grantee == NULL) + return; + switch (priv->object_type) { + case SC_UNIVERSE: + grantee->universal_access = priv->access; + break; + case SC_SPACE: + { + struct space *space = space_by_id(priv->object_id); + if (space) + space->access[grantee->auth_token] = priv->access; + break; + } + case SC_FUNCTION: + { + struct func_def *func = func_by_id(priv->object_id); + if (func) + func->access[grantee->auth_token] = priv->access; + break; + } + default: + break; + } +} + +/** A trigger called on rollback of grant, or on commit of revoke. */ +static void +revoke_priv(struct trigger * /* trigger */, void *event) +{ + struct txn *txn = (struct txn *) event; + struct tuple *tuple = (txn->new_tuple ? + txn->new_tuple : txn->old_tuple); + struct priv_def priv; + priv_def_create_from_tuple(&priv, tuple); + priv.access = 0; + grant_or_revoke(&priv); +} + +static struct trigger revoke_priv_trigger = + { rlist_nil, revoke_priv, NULL, NULL }; + +/** A trigger called on rollback of grant, or on commit of revoke. */ +static void +modify_priv(struct trigger * /* trigger */, void *event) +{ + struct txn *txn = (struct txn *) event; + struct priv_def priv; + priv_def_create_from_tuple(&priv, txn->new_tuple); + grant_or_revoke(&priv); +} + +static struct trigger modify_priv_trigger = + { rlist_nil, modify_priv, NULL, NULL }; + +/** + * A trigger invoked on replace in the space containing + * all granted privileges. + */ +static void +on_replace_dd_priv(struct trigger * /* trigger */, void *event) +{ + struct priv_def priv; + struct txn *txn = (struct txn *) event; + struct tuple *old_tuple = txn->old_tuple; + struct tuple *new_tuple = txn->new_tuple; + + if (new_tuple != NULL && old_tuple == NULL) { /* grant */ + priv_def_create_from_tuple(&priv, new_tuple); + priv_def_check(&priv); + grant_or_revoke(&priv); + trigger_set(&txn->on_rollback, &revoke_priv_trigger); + } else if (new_tuple == NULL) { /* revoke */ + assert(old_tuple); + priv_def_create_from_tuple(&priv, old_tuple); + access_check_ddl(priv.grantor_id); + trigger_set(&txn->on_commit, &revoke_priv_trigger); + } else { /* modify */ + priv_def_create_from_tuple(&priv, new_tuple); + priv_def_check(&priv); + trigger_set(&txn->on_commit, &modify_priv_trigger); + } +} + +/* }}} access control */ + struct trigger alter_space_on_replace_space = { rlist_nil, on_replace_dd_space, NULL, NULL }; @@ -1048,4 +1498,16 @@ struct trigger alter_space_on_replace_index = { rlist_nil, on_replace_dd_index, NULL, NULL }; +struct trigger on_replace_user = { + rlist_nil, on_replace_dd_user, NULL, NULL +}; + +struct trigger on_replace_func = { + rlist_nil, on_replace_dd_func, NULL, NULL +}; + +struct trigger on_replace_priv = { + rlist_nil, on_replace_dd_priv, NULL, NULL +}; + /* vim: set foldmethod=marker */ diff --git a/src/box/alter.h b/src/box/alter.h index 089412c59a3946c812294e805d03f24a45f97453..a563c3771e1fe06e7ba2f19c05d6093b298d7860 100644 --- a/src/box/alter.h +++ b/src/box/alter.h @@ -32,5 +32,8 @@ extern struct trigger alter_space_on_replace_space; extern struct trigger alter_space_on_replace_index; +extern struct trigger on_replace_user; +extern struct trigger on_replace_func; +extern struct trigger on_replace_priv; #endif /* INCLUDES_TARANTOOL_BOX_ALTER_H */ diff --git a/src/box/authentication.cc b/src/box/authentication.cc new file mode 100644 index 0000000000000000000000000000000000000000..fed6a96c2ca0d5d7e13456cba477070fde853241 --- /dev/null +++ b/src/box/authentication.cc @@ -0,0 +1,63 @@ +/* + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * 1. Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * <COPYRIGHT HOLDER> OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include "access.h" + +void +authenticate(const char *user_name, uint32_t len, + const char *tuple, const char * /* tuple_end */) +{ + struct user *user = user_by_name(user_name, len); + if (user == NULL) { + char name[BOX_NAME_MAX + 1]; + /* \0 - to correctly print user name the error message. */ + snprintf(name, sizeof(name), "%.*s", len, user_name); + tnt_raise(ClientError, ER_NO_SUCH_USER, name); + } + struct session *session = fiber()->session; + uint32_t part_count = mp_decode_array(&tuple); + if (part_count < 2) { + /* Expected at least: authentication mechanism and data. */ + tnt_raise(ClientError, ER_INVALID_MSGPACK, + "authentication request body"); + } + mp_next(&tuple); /* Skip authentication mechanism. */ + uint32_t scramble_len; + const char *scramble = mp_decode_str(&tuple, &scramble_len); + if (scramble_len != SCRAMBLE_SIZE) { + /* Authentication mechanism, data. */ + tnt_raise(ClientError, ER_INVALID_MSGPACK, + "scramble is too short"); + } + + if (scramble_check(scramble, session->salt, user->hash2)) + tnt_raise(ClientError, ER_PASSWORD_MISMATCH, user->name); + + session_set_user(session, user->auth_token, user->uid); +} + diff --git a/src/box/authentication.h b/src/box/authentication.h new file mode 100644 index 0000000000000000000000000000000000000000..c665e0d3c95392c0021d22fc3ef5747be4091082 --- /dev/null +++ b/src/box/authentication.h @@ -0,0 +1,35 @@ +#ifndef INCLUDES_TARANTOOL_BOX_AUTHENTICATION_H +#define INCLUDES_TARANTOOL_BOX_AUTHENTICATION_H +/* + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * 1. Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * <COPYRIGHT HOLDER> OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +void +authenticate(const char *user_name, uint32_t len, + const char *tuple, const char *tuple_end); +#endif /* INCLUDES_TARANTOOL_BOX_AUTHENTICATION_H */ diff --git a/src/box/box.cc b/src/box/box.cc index 5146aaa5204f5f03e5f68d9345f1ef2e7509b8cc..9bf639e61363396a7c486a79e759d95f418501f8 100644 --- a/src/box/box.cc +++ b/src/box/box.cc @@ -51,6 +51,7 @@ extern "C" { #include "request.h" #include "txn.h" #include "fiber.h" +#include "access.h" static void process_replica(struct port *port, struct request *request); static void process_ro(struct port *port, struct request *request); @@ -268,6 +269,7 @@ box_reload_config(struct tarantool_cfg *old_conf, struct tarantool_cfg *new_conf void box_free(void) { + user_cache_free(); schema_free(); tuple_free(); recovery_free(); @@ -283,6 +285,7 @@ box_init() tuple_init(cfg.slab_alloc_arena, cfg.slab_alloc_minimal, cfg.slab_alloc_factor); schema_init(); + user_cache_init(); /* recovery initialization */ recovery_init(cfg.snap_dir, cfg.wal_dir, diff --git a/src/box/index.h b/src/box/index.h index 9129c83e545cb9aa8b9aa881ea6c919bd240686e..4262b2dfbed4bc12f1b5e6b481f363bf903f6db1 100644 --- a/src/box/index.h +++ b/src/box/index.h @@ -59,9 +59,10 @@ struct tuple; * For ITER_EQ, the key must not be NULL. */ #define ITERATOR_TYPE(_) \ - _(ITER_ALL, 0) /* all tuples */ \ - _(ITER_EQ, 1) /* key == x ASC order */ \ - _(ITER_REQ, 2) /* key == x DESC order */ \ + /* ITER_EQ must be the first member for request_create */ \ + _(ITER_EQ, 0) /* key == x ASC order */ \ + _(ITER_REQ, 1) /* key == x DESC order */ \ + _(ITER_ALL, 2) /* all tuples */ \ _(ITER_LT, 3) /* key < x */ \ _(ITER_LE, 4) /* key <= x */ \ _(ITER_GE, 5) /* key >= x */ \ diff --git a/src/box/key_def.cc b/src/box/key_def.cc index 2cce6011ae71db570b63b7f24daccef1283c5b68..57a396eb3f3b9548b3877ca09cb24097dd96cda0 100644 --- a/src/box/key_def.cc +++ b/src/box/key_def.cc @@ -40,6 +40,15 @@ const uint32_t key_mp_type[] = { /* [_STR] = */ 1U << MP_STR }; +enum schema_object_type +schema_object_type(const char *name) +{ + static const char *strs[] = { + "unknown", "universe", "space", "function" }; + int index = strindex(strs, name, 4); + return (enum schema_object_type) (index == 4 ? 0 : index); +} + struct key_def * key_def_new(uint32_t space_id, uint32_t iid, const char *name, enum index_type type, bool is_unique, uint32_t part_count) @@ -210,7 +219,8 @@ key_def_check(struct key_def *key_def) } void -space_def_check(struct space_def *def, uint32_t namelen, uint32_t errcode) +space_def_check(struct space_def *def, uint32_t namelen, uint32_t engine_namelen, + int32_t errcode) { if (def->id > BOX_SPACE_MAX) { tnt_raise(ClientError, errcode, @@ -222,4 +232,9 @@ space_def_check(struct space_def *def, uint32_t namelen, uint32_t errcode) (unsigned) def->id, "space name is too long"); } + if (engine_namelen >= sizeof(def->engine_name)) { + tnt_raise(ClientError, errcode, + (unsigned) def->id, + "space engine name is too long"); + } } diff --git a/src/box/key_def.h b/src/box/key_def.h index b97cc70cf5d86556406089f8b78b9768e46933cc..e9efbe3cc79f0edffc84b88e88821cf41cf2dd69 100644 --- a/src/box/key_def.h +++ b/src/box/key_def.h @@ -36,9 +36,11 @@ enum { BOX_SPACE_MAX = INT32_MAX, + BOX_FUNCTION_MAX = 32000, BOX_INDEX_MAX = 10, BOX_NAME_MAX = 32, BOX_FIELD_MAX = INT32_MAX, + BOX_USER_MAX = 32, /** * A fairly arbitrary limit which is still necessary * to keep tuple_format object small. @@ -50,6 +52,20 @@ enum { BOX_INDEX_PART_MAX = UINT8_MAX }; +/* + * Different objects which can be subject to access + * control. + * + * Use 0 for unknown to use the same index consistently + * even when there are more object types in the future. + */ +enum schema_object_type { + SC_UNKNOWN = 0, SC_UNIVERSE = 1, SC_SPACE = 2, SC_FUNCTION = 3 +}; + +enum schema_object_type +schema_object_type(const char *name); + /* * Possible field data types. Can't use STRS/ENUM macros for them, * since there is a mismatch between enum name (STRING) and type @@ -189,6 +205,8 @@ key_def_check(struct key_def *key_def); struct space_def { /** Space id. */ uint32_t id; + /** User id of the creator of the space */ + uint32_t uid; /** * If not set (is 0), any tuple in the * space can have any number of fields. @@ -197,6 +215,7 @@ struct space_def { */ uint32_t arity; char name[BOX_NAME_MAX + 1]; + char engine_name[BOX_NAME_MAX + 1]; /** * The space is a temporary: * - it is empty at server start @@ -208,7 +227,9 @@ struct space_def { /** Check space definition structure for errors. */ void -space_def_check(struct space_def *def, uint32_t namelen, uint32_t errcode); +space_def_check(struct space_def *def, uint32_t namelen, + uint32_t engine_namelen, + int32_t errcode); /** A helper table for key_mp_type_validate */ extern const uint32_t key_mp_type[]; @@ -231,4 +252,40 @@ key_mp_type_validate(enum field_type key_type, enum mp_type mp_type, field_type_strs[key_type]); } +/** + * Definition of a function. Function body is not stored + * or replicated (yet). + */ + +struct func_def { + /** Function id. */ + uint32_t fid; + /** Owner of the function. */ + uint32_t uid; + /** Function name. */ + char name[BOX_NAME_MAX + 1]; + /** + * Strictly speaking, this doesn't belong + * to func def but belongs to func cache entry. + * Kept here for simplicity. + */ + uint8_t access[BOX_USER_MAX]; +}; + +/** + * Definition of a privilege + */ +struct priv_def { + /** Who grants the privilege. */ + uint32_t grantor_id; + /** Whom the privilege is granted. */ + uint32_t grantee_id; + /* Object id - is only defined for object type */ + uint32_t object_id; + /* Object type - function, space, universe */ + enum schema_object_type object_type; + /** What is being or has been granted. */ + uint8_t access; +}; + #endif /* TARANTOOL_BOX_KEY_DEF_H_INCLUDED */ diff --git a/src/box/lua/box_net.lua b/src/box/lua/box_net.lua index 2c7ce7b7c8b744c0a61bb392943626438e58abc9..507499802944ca04563236cf1fbcdcb212d394af 100644 --- a/src/box/lua/box_net.lua +++ b/src/box/lua/box_net.lua @@ -93,6 +93,7 @@ box.net = { FUNCTION_NAME = 0x22, DATA = 0x30, ERROR = 0x31, + GREETING_SIZE = 128, delete = function(self, space, key) local t = self:process(box.net.box.DELETE, @@ -149,9 +150,59 @@ box.net = { end end, - select = function(self, space, key) - -- unpack - is old behaviour - return unpack(self:eselect(space, 0, key, { limit = 4294967295 })) + get = function(self, space, key) + key = keify(key) + local result = self:process(box.net.box.SELECT, + msgpack.encode({ + [box.net.box.SPACE_ID] = space, + [box.net.box.KEY] = key, + [box.net.box.ITERATOR] = box.index.EQ, + [box.net.box.OFFSET] = 0, + [box.net.box.LIMIT] = 2 + })) + if #result == 0 then + return + elseif #result == 1 then + return result[1] + else + box.raise(box.error.ER_MORE_THAN_ONE_TUPLE, + "More than one tuple found without 'limit'") + end + end, + + select = function(self, space, key, opts) + local offset = 0 + local limit = 4294967295 + local iterator = box.index.EQ + + key = keify(key) + if #key == 0 then + iterator = box.index.ALL + end + + if opts ~= nil then + if opts.offset ~= nil then + offset = tonumber(opts.offset) + end + if type(opts.iterator) == "string" then + opts.iterator = box.index[opts.iterator] + end + if opts.iterator ~= nil then + iterator = tonumber(opts.iterator) + end + if opts.limit ~= nil then + limit = tonumber(opts.limit) + end + end + local result = self:process(box.net.box.SELECT, + msgpack.encode({ + [box.net.box.SPACE_ID] = space, + [box.net.box.KEY] = key, + [box.net.box.ITERATOR] = iterator, + [box.net.box.OFFSET] = offset, + [box.net.box.LIMIT] = limit + })) + return result end, ping = function(self) @@ -166,19 +217,6 @@ box.net = { [box.net.box.TUPLE] = {...}})) end, - eselect = function(self, sno, ino, key, opts) - local res = self:call('box.net.self:eselect', sno, ino, key, opts) - if opts and opts.limit == nil then - if res[1] ~= nil then - return res[1] - else - return - end - end - return res - end, - - -- To make use of timeouts safe across multiple -- concurrent fibers do not store timeouts as -- part of conection state, but put it inside @@ -214,23 +252,6 @@ box.net = { return box.process(...) end, - - eselect = function(self, sno, ino, key, opts) - local space = box.space[ sno ] - if space == nil then - box.raise(box.error.ER_NO_SUCH_SPACE, - sprintf("No such space #%s", tostring(sno))) - end - local index = space.index[ ino ] - if index == nil then - box.raise(box.error.ER_NO_SUCH_INDEX, - sprintf("No such index #%s in space #%s", - tostring(sno), tostring(ino))) - end - - return index:eselect(key, opts) - end, - -- for compatibility with the networked version, -- implement call call = function(self, proc_name, ...) @@ -258,6 +279,8 @@ box.net = { } } +box.net.box.put = box.net.box.replace; -- put is an alias for replace + -- box.net.self rpc works like remote.rpc box.net.self.rpc = { r = box.net.self } setmetatable(box.net.self.rpc, { __index = rpc_index }) @@ -401,6 +424,7 @@ box.net.box.new = function(host, port, reconnect_timeout) self.host, self.port, s[4]) return false end + sc:recv(box.net.box.GREETING_SIZE) self.s = sc @@ -445,7 +469,7 @@ box.net.box.new = function(host, port, reconnect_timeout) while not self.closed do local resp = self:read_response() - local header, offset = msgpack.next(resp); + local header, offset = msgpack.decode(resp); local code = header[box.net.box.CODE] local sync = header[box.net.box.SYNC] if sync == nil then diff --git a/src/box/lua/call.cc b/src/box/lua/call.cc index 2e1d3ac95a5e622033271ba12f32de5b4219e384..b9429b0638bab67991c0436d1d9b6543db697acd 100644 --- a/src/box/lua/call.cc +++ b/src/box/lua/call.cc @@ -44,6 +44,8 @@ #include "box/port.h" #include "box/request.h" #include "bit/bit.h" +#include "box/access.h" +#include "box/schema.h" /* contents of box.lua, misc.lua, box.net.lua respectively */ extern char schema_lua[], box_lua[], box_net_lua[], misc_lua[] ; @@ -263,20 +265,63 @@ lbox_request_create(struct lua_State *L, enum iproto_request_type type, return request; } -static int -lbox_select(lua_State *L) +static void +port_ffi_add_tuple(struct port *port, struct tuple *tuple) { - if (lua_gettop(L) != 3 || ! lua_isnumber(L, 1) || - ! lua_isnumber(L, 2)) { - return luaL_error(L, "Usage index:select(key)"); + struct port_ffi *port_ffi = (struct port_ffi *) port; + if (port_ffi->size >= port_ffi->capacity) { + uint32_t capacity = (port_ffi->capacity > 0) ? + 2 * port_ffi->capacity : 1024; + struct tuple **ret = (struct tuple **) + realloc(port_ffi->ret, sizeof(*ret) * capacity); + assert(ret != NULL); + port_ffi->ret = ret; + port_ffi->capacity = capacity; + } + port_ffi->ret[port_ffi->size++] = tuple; +} + +struct port_vtab port_ffi_vtab = { + port_ffi_add_tuple, + null_port_eof, +}; + +void +port_ffi_create(struct port_ffi *port) +{ + memset(port, 0, sizeof(*port)); + port->vtab = &port_ffi_vtab; +} + +void +port_ffi_destroy(struct port_ffi *port) +{ + free(port->ret); + port->capacity = port->size = 0; +} + +int +boxffi_select(struct port *port, uint32_t space_id, uint32_t index_id, + int iterator, uint32_t offset, uint32_t limit, + const char *key, const char *key_end) +{ + struct request request; + request_create(&request, IPROTO_SELECT); + request.space_id = space_id; + request.index_id = index_id; + request.limit = limit; + request.offset = offset; + request.iterator = iterator; + request.key = key; + request.key_end = key_end; + + try { + box_process(port, &request); + return 0; + } catch (Exception *e) { + /* will be hanled by box.raise() in Lua */ + return -1; } - RegionGuard region_guard(&fiber()->gc); - struct request *request = lbox_request_create(L, IPROTO_SELECT, - 3, -1); - request->index_id = lua_tointeger(L, 2); - request->limit = 4294967295; - box_process(port_lua_create(L), request); - return lua_gettop(L) - 3; } static int @@ -433,6 +478,25 @@ lbox_call_loadproc(struct lua_State *L) return box_lua_find(L, name, name + name_len); } +static inline void +access_check_func(const char *name, uint32_t name_len, + struct user *user, uint8_t access) +{ + if (access == 0) + return; + + struct func_def *func = func_by_name(name, name_len); + if (func == NULL || (func->uid != user->uid && user->uid != ADMIN && + access & ~func->access[user->auth_token])) { + + char name_buf[BOX_NAME_MAX + 1]; + snprintf(name_buf, sizeof(name_buf), "%.*s", name_len, name); + + tnt_raise(ClientError, ER_FUNCTION_ACCESS_DENIED, + priv_name(access), user->name, name_buf); + } +} + /** * Invoke a Lua stored procedure from the binary protocol * (implementation of 'CALL' command code). @@ -441,12 +505,16 @@ void box_lua_call(struct request *request, struct txn *txn, struct port *port) { + struct user *user = user(); (void) txn; lua_State *L = lua_newthread(tarantool_L); LuarefGuard coro_ref(tarantool_L); const char *name = request->key; uint32_t name_len = mp_decode_strl(&name); + uint8_t access = PRIV_X & ~user->universal_access; + access_check_func(name, name_len, user, access); + /* proc name */ int oc = box_lua_find(L, name, name + name_len); /* Push the rest of args (a tuple). */ @@ -853,7 +921,6 @@ lbox_unpack(struct lua_State *L) static const struct luaL_reg boxlib[] = { {"process", lbox_process}, - {"_select", lbox_select}, {"_insert", lbox_insert}, {"_replace", lbox_replace}, {"_update", lbox_update}, diff --git a/src/box/lua/call.h b/src/box/lua/call.h index 204c6cd7123322484be5ac822fb86f53620eaf2a..c5ad2c4bab7ff20b10ecb65db2ff0e6302b753c1 100644 --- a/src/box/lua/call.h +++ b/src/box/lua/call.h @@ -29,6 +29,8 @@ * SUCH DAMAGE. */ +#include <stdint.h> + struct txn; struct request; struct port; @@ -40,4 +42,26 @@ struct port; void box_lua_call(struct request *request, struct txn *txn, struct port *port); +extern "C" { +struct port_ffi +{ + struct port_vtab *vtab; + uint32_t size; + uint32_t capacity; + struct tuple **ret; +}; + +void +port_ffi_create(struct port_ffi *port); + +void +port_ffi_destroy(struct port_ffi *port); + +int +boxffi_select(struct port *port, uint32_t space_id, uint32_t index_id, + int iterator, uint32_t offset, uint32_t limit, + const char *key, const char *key_end); + +} /* extern "C" */ + #endif /* INCLUDES_TARANTOOL_MOD_BOX_LUA_CALL_H */ diff --git a/src/box/lua/index.cc b/src/box/lua/index.cc index 782dbf9eda1b2abe9945a56bbcb8ce8fbf5e3c8b..8afea6f27cb732ebc62576c7745e8e6d74c70bd0 100644 --- a/src/box/lua/index.cc +++ b/src/box/lua/index.cc @@ -59,7 +59,8 @@ lua_checkindex(struct lua_State *L, int i) (struct lbox_index *) luaL_checkudata(L, i, indexlib_name); assert(index != NULL); if (index->sc_version != sc_version) { - index->index = index_find(space_find(index->id), index->iid); + index->index = index_find(space_cache_find(index->id), + index->iid); index->sc_version = sc_version; } return index->index; @@ -71,7 +72,7 @@ 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 */ /* locate the appropriate index */ - struct space *space = space_find(id); + struct space *space = space_cache_find(id); Index *i = index_find(space, iid); /* create a userdata object */ @@ -146,7 +147,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_find(space_id); + struct space *space = space_cache_find(space_id); Index *index = index_find(space, index_id); assert(mp_typeof(*key) == MP_ARRAY); /* checked by Lua */ uint32_t part_count = mp_decode_array(&key); diff --git a/src/box/lua/misc.lua b/src/box/lua/misc.lua index 107e0bc89589f734a26d2cb9d69c06068854126a..b9172b05f7fa933283a95f970df5445303e75748 100644 --- a/src/box/lua/misc.lua +++ b/src/box/lua/misc.lua @@ -35,7 +35,7 @@ function box.counter.dec(spaceno, key) local cnt_index = #key local s = box.space[spaceno] - local tuple = s:select(key) + local tuple = s:get(key) if tuple == nil then return 0 end if tuple[cnt_index] == 1 then s:delete(key) diff --git a/src/box/lua/schema.lua b/src/box/lua/schema.lua index f8f031d73cfd38bc805ee8170c981e7bffecb030..a2e50ed5ee838f860cd4d81bc1297e924a659b75 100644 --- a/src/box/lua/schema.lua +++ b/src/box/lua/schema.lua @@ -12,9 +12,45 @@ ffi.cdef[[ struct iterator * boxffi_index_iterator(uint32_t space_id, uint32_t index_id, int type, const char *key); + + struct port; + struct port_ffi + { + struct port_vtab *vtab; + uint32_t size; + uint32_t capacity; + struct tuple **ret; + }; + + void + port_ffi_create(struct port_ffi *port); + void + port_ffi_destroy(struct port_ffi *port); + + int + boxffi_select(struct port *port, uint32_t space_id, uint32_t index_id, + int iterator, uint32_t offset, uint32_t limit, + const char *key, const char *key_end); + void password_prepare(const char *password, int len, + char *out, int out_len); ]] local builtin = ffi.C local msgpackffi = require('msgpackffi') +local fun = require('fun') + +local function user_resolve(user) + local _user = box.space[box.schema.USER_ID] + local tuple + if type(user) == 'string' then + tuple = _user.index['name']:get{user} + else + tuple = _user.index['primary']:get{user} + end + if tuple == nil then + return nil + end + return tuple[0] +end box.schema.space = {} box.schema.space.create = function(name, options) @@ -23,9 +59,11 @@ box.schema.space.create = function(name, options) options = {} end local if_not_exists = options.if_not_exists - local temporary = options.temporary and "temporary" or "" - + local engine = "memtx" + if options.engine then + engine = options.engine + end if box.space[name] then if options.if_not_exists then return box.space[name], "not created" @@ -48,14 +86,21 @@ box.schema.space.create = function(name, options) if options.arity == nil then options.arity = 0 end - _space:insert{id, options.arity, name, temporary} + local uid = nil + if options.user then + uid = user_resolve(options.user) + end + if uid == nil then + uid = box.session.uid() + end + _space:insert{id, uid, name, engine, options.arity, temporary} return box.space[id], "created" end box.schema.create_space = box.schema.space.create box.schema.space.drop = function(space_id) local _space = box.space[box.schema.SPACE_ID] local _index = box.space[box.schema.INDEX_ID] - local keys = { _index:select{space_id} } + local keys = _index:select(space_id) for i = #keys, 1, -1 do local v = keys[i] _index:delete{v[0], v[1]} @@ -93,8 +138,7 @@ box.schema.index.create = function(space_id, name, options) local iid = 0 -- max local tuple = _index.index[0] - :eselect(space_id, { limit = 1, iterator = 'LE' }) - tuple = tuple[1] + :select(space_id, { limit = 1, iterator = 'LE' })[1] if tuple then local id = tuple[0] if id == space_id then @@ -157,7 +201,7 @@ box.schema.index.alter = function(space_id, index_id, options) _index:update({space_id, index_id}, ops) return end - local tuple = _index:select{space_id, index_id} + local tuple = _index:get{space_id, index_id} if options.name == nil then options.name = tuple[2] end @@ -184,25 +228,57 @@ local function keify(key) return {key} end -local iterator_mt = { - __call = function(iterator) - local tuple = iterator.cdata.next(iterator.cdata) - if tuple ~= nil then - return box.tuple.bless(tuple) - else - return nil - end - end; +local iterator_t = ffi.typeof('struct iterator') +ffi.metatype(iterator_t, { __tostring = function(iterator) - return string.format("iterator on space %d index %d", - iterator.index.n, iterator.index.id) + return "<iterator state>" end; -} +}) + +local iterator_gen = function(param, state) + --[[ + index:pairs() mostly confirms to the Lua for-in loop conventions and + tries to follow the best practices of Lua community. + + - this generating function is stateless. + + - *param* should contain **immutable** data needed to fully define + an iterator. *param* is opaque for users. Currently it contains keybuf + string just to prevent GC from collecting it. In future some other + variables like space_id, index_id, sc_version will be stored here. + + - *state* should contain **immutable** transient state of an iterator. + *state* is opaque for users. Currently it contains `struct iterator` + cdata that is modified during iteration. This is a sad limitation of + underlying C API. Moreover, the separation of *param* and *state* is + not properly implemented here. These drawbacks can be fixed in + future without changing this API. + + Please checkout http://www.lua.org/pil/7.3.html for the further + information. + --]] + if not ffi.istype(iterator_t, state) then + error('usage gen(param, state)') + end + -- next() modifies state in-place + local tuple = state.next(state) + if tuple ~= nil then + return state, box.tuple.bless(tuple) -- new state, value + else + return nil + end +end -local iterator_cdata_gc = function(iterator_cdata) - return iterator_cdata.free(iterator_cdata) +local iterator_cdata_gc = function(iterator) + return iterator.free(iterator) end +-- global struct port instance to use by select()/get() +local port = ffi.new('struct port_ffi') +builtin.port_ffi_create(port) +ffi.gc(port, builtin.port_ffi_destroy) +local port_t = ffi.typeof('struct port *') + function box.schema.space.bless(space) local index_mt = {} -- __len and __index @@ -215,9 +291,9 @@ function box.schema.space.bless(space) if index.type == 'HASH' then box.raise(box.error.ER_UNSUPPORTED, 'HASH does not support min()') end - local lst = index:eselect(key, { iterator = 'GE', limit = 1 }) - if lst[1] ~= nil then - return lst[1] + local lst = index:select(key, { iterator = 'GE', limit = 1 })[1] + if lst ~= nil then + return lst else return end @@ -226,16 +302,16 @@ function box.schema.space.bless(space) if index.type == 'HASH' then box.raise(box.error.ER_UNSUPPORTED, 'HASH does not support max()') end - local lst = index:eselect(key, { iterator = 'LE', limit = 1 }) - if lst[1] ~= nil then - return lst[1] + local lst = index:select(key, { iterator = 'LE', limit = 1 })[1] + if lst ~= nil then + return lst else return end end index_mt.random = function(index, rnd) return index.idx:random(rnd) end -- iteration - index_mt.iterator = function(index, key, opts) + index_mt.pairs = function(index, key, opts) local pkey, pkey_end = msgpackffi.encode_tuple(key) -- Use ALL for {} and nil keys and EQ for other keys local itype = pkey + 1 < pkey_end and box.index.EQ or box.index.ALL @@ -256,17 +332,15 @@ function box.schema.space.bless(space) box.raise() end - return setmetatable({ - cdata = ffi.gc(cdata, iterator_cdata_gc); - keybuf = keybuf; - index = index; - }, iterator_mt) + return fun.wrap(iterator_gen, keybuf, ffi.gc(cdata, iterator_cdata_gc)) end + index_mt.__pairs = index_mt.pairs -- Lua 5.2 compatibility + index_mt.__ipairs = index_mt.pairs -- Lua 5.2 compatibility -- index subtree size index_mt.count = function(index, key, opts) local count = 0 local iterator - + if opts and opts.iterator ~= nil then iterator = opts.iterator else @@ -277,7 +351,8 @@ function box.schema.space.bless(space) return #index.idx end - for tuple in index:iterator(key, { iterator = iterator }) do + local state, tuple + for state, tuple in index:pairs(key, { iterator = iterator }) do count = count + 1 end return count @@ -291,74 +366,59 @@ function box.schema.space.bless(space) end end - -- eselect - index_mt.eselect = function(index, key, opts) - -- user can catch link to index - check_index(box.space[index.n], index.id) - - if opts == nil then - opts = {} + index_mt.get = function(index, key) + local key, key_end = msgpackffi.encode_tuple(key) + port.size = 0; + if builtin.boxffi_select(ffi.cast(port_t, port), index.n, + index.id, box.index.EQ, 0, 2, key, key_end) ~=0 then + return box.raise() end - - local iterator = opts.iterator - - if iterator == nil then - iterator = box.index.EQ - end - if type(iterator) == 'string' then - if box.index[ iterator ] == nil then - error(string.format("Wrong iterator: %s", tostring(iterator))) - end - iterator = box.index[ iterator ] + if port.size == 0 then + return + elseif port.size == 1 then + return box.tuple.bless(port.ret[0]) + else + box.raise(box.error.ER_MORE_THAN_ONE_TUPLE, + "More than one tuple found by get()") end + end - local result = {} + index_mt.select = function(index, key, opts) local offset = 0 - local skip = 0 - local count = 0 - if opts.offset ~= nil then - offset = tonumber(opts.offset) - end - local limit = opts.limit - local grep = opts.grep - local map = opts.map + local limit = 4294967295 + local iterator = box.index.EQ - if limit == 0 then - return result + local key, key_end = msgpackffi.encode_tuple(key) + if key_end == key + 1 then -- empty array + iterator = box.index.ALL end - for tuple in index:iterator(key, { iterator = iterator }) do - if grep == nil or grep(tuple) then - if skip < offset then - skip = skip + 1 - else - if map == nil then - table.insert(result, tuple) - else - table.insert(result, map(tuple)) - end - count = count + 1 - - if limit == nil then - if count > 1 then - box.raise(box.error.ER_MORE_THAN_ONE_TUPLE, - "More than one tuple found without 'limit'") - end - elseif count >= limit then - break - end - end + if opts ~= nil then + if opts.offset ~= nil then + offset = opts.offset + end + if type(opts.iterator) == "string" then + opts.iterator = box.index[opts.iterator] + end + if opts.iterator ~= nil then + iterator = opts.iterator + end + if opts.limit ~= nil then + limit = opts.limit end end - if limit == nil then - return result[1] + + port.size = 0; + if builtin.boxffi_select(ffi.cast(port_t, port), index.n, + index.id, iterator, offset, limit, key, key_end) ~=0 then + return box.raise() end - return result - end - -- - index_mt.select = function(index, key) - return box._select(index.n, index.id, keify(key)) + local ret = {} + for i=0,port.size - 1,1 do + table.insert(ret, box.tuple.bless(port.ret[i])) + end + return ret end index_mt.update = function(index, key, ops) return box._update(index.n, index.id, keify(key), ops); @@ -380,14 +440,13 @@ function box.schema.space.bless(space) space_mt.len = function(space) return space.index[0]:len() end space_mt.__newindex = index_mt.__newindex - space_mt.eselect = function(space, key, opts) + space_mt.get = function(space, key) check_index(space, 0) - return space.index[0]:eselect(key, opts) + return space.index[0]:get(key) end - - space_mt.select = function(space, key) + space_mt.select = function(space, key, opts) check_index(space, 0) - return space.index[0]:select(key) + return space.index[0]:select(key, opts) end space_mt.insert = function(space, tuple) return box._insert(space.n, tuple); @@ -395,6 +454,7 @@ function box.schema.space.bless(space) space_mt.replace = function(space, tuple) return box._replace(space.n, tuple); end + space_mt.put = space_mt.replace; -- put is an alias for replace space_mt.update = function(space, key, ops) check_index(space, 0) return space.index[0]:update(key, ops) @@ -415,15 +475,18 @@ function box.schema.space.bless(space) table.insert(tuple, 1, max + 1) return space:insert(tuple) end - space_mt.iterator = function(space, key) + space_mt.pairs = function(space, key) check_index(space, 0) - return space.index[0]:iterator(key) + return space.index[0]:pairs(key) end + space_mt.__pairs = space_mt.pairs -- Lua 5.2 compatibility + space_mt.__ipairs = space_mt.pairs -- Lua 5.2 compatibility space_mt.truncate = function(space) check_index(space, 0) local pk = space.index[0] while #pk.idx > 0 do - for t in pk:iterator() do + local state, t + for state, t in pk:pairs() do local key = {} -- ipairs does not work because pk.key_field is zero-indexed for _k2, key_field in pairs(pk.key_field) do @@ -462,3 +525,167 @@ function box.schema.space.bless(space) end end +local function privilege_resolve(privilege) + local numeric = 0 + if type(privilege) == 'string' then + privilege = string.lower(privilege) + if string.find(privilege, 'read') then + numeric = numeric + 1 + end + if string.find(privilege, 'write') then + numeric = numeric + 2 + end + if string.find(privilege, 'execute') then + numeric = numeric + 4 + end + else + numeric = privilege + end + return numeric +end + +local function object_resolve(object_type, object_name) + if object_type == 'universe' then + return 0 + end + if object_type == 'space' then + local space = box.space[object_name] + if space == nil then + box.raise(box.error.ER_NO_SUCH_SPACE, + "Space '"..object_name.."' does not exist") + end + return space.n + end + if object_type == 'function' then + local _func = box.space[box.schema.FUNC_ID] + local func + if type(object_name) == 'string' then + func = _func.index['name']:get{object_name} + else + func = _func.index['primary']:get{object_name} + end + if func then + return func[0] + else + box.raise(box.error.ER_NO_SUCH_FUNCTION, + "Function '"..object_name.."' does not exist") + end + end + box.raise(box.error.ER_UNKNOWN_SCHEMA_OBJECT, + "Unknown object type '"..object_type.."'") +end + +box.schema.func = {} +box.schema.func.create = function(name) + local _func = box.space[box.schema.FUNC_ID] + local func = _func.index['name']:get{name} + if func then + box.raise(box.error.ER_FUNCTION_EXISTS, + "Function '"..name.."' already exists") + end + _func:auto_increment{box.session.uid(), name} +end + +box.schema.func.drop = function(name) + local _func = box.space[box.schema.FUNC_ID] + local fid = object_resolve('function', name) + _func:delete{fid} +end + +box.schema.user = {} + +box.schema.user.password = function(password) + local BUF_SIZE = 128 + local buf = ffi.new("char[?]", BUF_SIZE) + ffi.C.password_prepare(password, #password, buf, BUF_SIZE) + return ffi.string(buf) +end + +box.schema.user.passwd = function(new_password) + local uid = box.session.uid() + local _user = box.space[box.schema.USER_ID] + auth_mech_list = {} + auth_mech_list["chap-sha1"] = box.schema.user.password(new_password) + _user:update({uid}, {"=", 3, auth_mech_list}) +end + +box.schema.user.create = function(name, opts) + local uid = user_resolve(name) + if uid then + box.raise(box.error.ER_USER_EXISTS, + "User '"..name.."' already exists") + end + if opts == nil then + opts = {} + end + auth_mech_list = {} + if opts.password then + auth_mech_list["chap-sha1"] = box.schema.user.password(opts.password) + end + local _user = box.space[box.schema.USER_ID] + _user:auto_increment{'', name, auth_mech_list} +end + +box.schema.user.drop = function(name) + local uid = user_resolve(name) + if uid == nil then + box.raise(box.error.ER_NO_SUCH_USER, + "User '"..name.."' does not exist") + end + -- recursive delete of user data + local _priv = box.space[box.schema.PRIV_ID] + local privs = _priv.index['owner']:select{uid} + for k, tuple in pairs(privs) do + box.schema.user.revoke(uid, tuple[4], tuple[2], tuple[3]) + end + local spaces = box.space[box.schema.SPACE_ID].index['owner']:select{uid} + for k, tuple in pairs(spaces) do + box.space[tuple[0]]:drop() + end + local funcs = box.space[box.schema.FUNC_ID].index['owner']:select{uid} + for k, tuple in pairs(spaces) do + box.schema.func.drop(tuple[0]) + end + box.space[box.schema.USER_ID]:delete{uid} +end + +box.schema.user.grant = function(user_name, privilege, object_type, + object_name, grantor) + local uid = user_resolve(user_name) + if uid == nil then + box.raise(box.error.ER_NO_SUCH_USER, + "User '"..user_name.."' does not exist") + end + privilege = privilege_resolve(privilege) + local oid = object_resolve(object_type, object_name) + if grantor == nil then + grantor = box.session.uid() + else + grantor = user_resolve(grantor) + end + local _priv = box.space[box.schema.PRIV_ID] + _priv:replace{grantor, uid, object_type, oid, privilege} +end + +box.schema.user.revoke = function(user_name, privilege, object_type, object_name) + local uid = user_resolve(user_name) + if uid == nil then + box.raise(box.error.ER_NO_SUCH_USER, + "User '"..name.."' does not exist") + end + privilege = privilege_resolve(privilege) + local oid = object_resolve(object_type, object_name) + local _priv = box.space[box.schema.PRIV_ID] + local tuple = _priv:get{uid, object_type, oid} + if tuple == nil then + return + end + local old_privilege = tuple[4] + if old_privilege ~= privilege then + privilege = bit.band(old_privilege, bit.bnot(privilege)) + _priv:update({uid, object_type, oid}, { "=", 4, privilege}) + else + _priv:delete{uid, object_type, oid} + end +end + diff --git a/src/box/lua/space.cc b/src/box/lua/space.cc index 02549dccd18aae6f094fb94e9ea709d5e8a8a9e0..cb0a525fc0dc385e14d325b99d8969361bc878fe 100644 --- a/src/box/lua/space.cc +++ b/src/box/lua/space.cc @@ -75,7 +75,8 @@ lbox_space_on_replace(struct lua_State *L) "usage: space:on_replace(function | nil, [function | nil])"); } lua_getfield(L, 1, "n"); /* Get space id. */ - struct space *space = space_find(lua_tointeger(L, lua_gettop(L))); + uint32_t id = lua_tointeger(L, lua_gettop(L)); + struct space *space = space_cache_find(id); lua_pop(L, 1); return lbox_trigger_reset(L, 3, @@ -113,6 +114,11 @@ lbox_fillspace(struct lua_State *L, struct space *space, int i) lua_pushstring(L, space_name(space)); lua_settable(L, i); + /* space.engine */ + lua_pushstring(L, "engine"); + lua_pushstring(L, space->def.engine_name); + lua_settable(L, i); + lua_pushstring(L, "enabled"); lua_pushboolean(L, space_index(space, 0) != 0); lua_settable(L, i); @@ -275,6 +281,12 @@ box_lua_space_init(struct lua_State *L) lua_setfield(L, -2, "SPACE_ID"); lua_pushnumber(L, SC_INDEX_ID); lua_setfield(L, -2, "INDEX_ID"); + lua_pushnumber(L, SC_USER_ID); + lua_setfield(L, -2, "USER_ID"); + lua_pushnumber(L, SC_FUNC_ID); + lua_setfield(L, -2, "FUNC_ID"); + lua_pushnumber(L, SC_PRIV_ID); + lua_setfield(L, -2, "PRIV_ID"); lua_pushnumber(L, SC_SYSTEM_ID_MIN); lua_setfield(L, -2, "SYSTEM_ID_MIN"); lua_pushnumber(L, SC_SYSTEM_ID_MAX); diff --git a/src/box/lua/tuple.lua b/src/box/lua/tuple.lua index 501e2a7735bf02bf858b214998eebdc083267501..779084d2af4c57c4cf470121568c5045ebd6a891 100644 --- a/src/box/lua/tuple.lua +++ b/src/box/lua/tuple.lua @@ -3,6 +3,7 @@ local ffi = require('ffi') local yaml = require('yaml') local msgpackffi = require('msgpackffi') +local fun = require('fun') ffi.cdef([[ struct tuple @@ -35,6 +36,9 @@ tuple_seek(struct tuple_iterator *it, uint32_t field_no); const char * tuple_next(struct tuple_iterator *it); + +void +tuple_to_buf(struct tuple *tuple, char *buf); ]]) local builtin = ffi.C @@ -80,7 +84,7 @@ end -- See http://www.lua.org/manual/5.2/manual.html#pdf-ipairs local function tuple_ipairs(tuple, pos) local it = ffi.new(tuple_iterator_t) - return it, tuple, pos + return fun.wrap(it, tuple, pos) end -- a precreated metatable for totable() @@ -107,6 +111,15 @@ local function tuple_unpack(tuple) return unpack(tuple_totable(tuple)) end +-- Set encode hooks for msgpackffi +local function tuple_to_msgpack(buf, tuple) + buf:reserve(tuple._bsize) + builtin.tuple_to_buf(tuple, buf.p) + buf.p = buf.p + tuple._bsize +end + +msgpackffi.on_encode(ffi.typeof('const struct tuple &'), tuple_to_msgpack) + -- cfuncs table is set by C part local methods = { @@ -132,8 +145,9 @@ end local tuple_bless = function(tuple) -- update in-place, do not spent time calling tuple_ref + local tuple2 = ffi.gc(ffi.cast(const_struct_tuple_ref_t, tuple), tuple_gc) tuple._refs = tuple._refs + 1 - return ffi.gc(ffi.cast(const_struct_tuple_ref_t, tuple), tuple_gc) + return tuple2 end local tuple_field = function(tuple, field_n) @@ -146,7 +160,6 @@ local tuple_field = function(tuple, field_n) end ffi.metatype('struct tuple', { - __gc = tuple_gc; __len = function(tuple) return builtin.tuple_arity(tuple) end; diff --git a/src/box/request.cc b/src/box/request.cc index 230942762c34eb92eda903a6e2973a2f3b5fa762..f4703f1f09689b0caa44ba1d820ddc3b5fbc29d7 100644 --- a/src/box/request.cc +++ b/src/box/request.cc @@ -39,6 +39,18 @@ #include <fiber.h> #include <scoped_guard.h> #include <third_party/base64.h> +#include "access.h" +#include "authentication.h" + +static inline void +access_check_space(uint8_t access, struct user *user, struct space *space) +{ + if (access && space->def.uid != user->uid && user->uid != ADMIN && + access & ~space->access[user->auth_token]) { + tnt_raise(ClientError, ER_SPACE_ACCESS_DENIED, + priv_name(access), user->name, space->def.name); + } +} #if 0 static const char * @@ -82,14 +94,23 @@ static void execute_replace(struct request *request, struct txn *txn, struct port *port) { (void) port; - txn_add_redo(txn, request); + struct user *user = user(); + /* + * If a user has a global permission, clear the respective + * privilege from the list of privileges required + * to execute the request. + */ + uint8_t access = PRIV_W & ~user->universal_access; + + struct space *space = space_cache_find(request->space_id); - struct space *space = space_find(request->space_id); + access_check_space(access, user, space); struct tuple *new_tuple = tuple_new(space->format, request->tuple, request->tuple_end); TupleGuard guard(new_tuple); space_validate_tuple(space, new_tuple); enum dup_replace_mode mode = dup_replace_mode(request->type); + txn_add_redo(txn, request); txn_replace(txn, space, NULL, new_tuple, mode); } @@ -98,11 +119,14 @@ execute_update(struct request *request, struct txn *txn, struct port *port) { (void) port; - txn_add_redo(txn, request); + struct user *user = user(); + uint8_t access = PRIV_W & ~user->universal_access; + /* Parse UPDATE request. */ /** Search key and key part count. */ - struct space *space = space_find(request->space_id); + struct space *space = space_cache_find(request->space_id); + access_check_space(access, user, space); Index *pk = index_find(space, 0); /* Try to find the tuple by primary key. */ const char *key = request->key; @@ -110,6 +134,7 @@ execute_update(struct request *request, struct txn *txn, primary_key_validate(pk->key_def, key, part_count); struct tuple *old_tuple = pk->findByKey(key, part_count); + txn_add_redo(txn, request); if (old_tuple == NULL) return; @@ -124,13 +149,38 @@ execute_update(struct request *request, struct txn *txn, txn_replace(txn, space, old_tuple, new_tuple, DUP_INSERT); } -/** }}} */ +static void +execute_delete(struct request *request, struct txn *txn, struct port *port) +{ + (void) port; + struct user *user = user(); + uint8_t access = PRIV_W & ~user->universal_access; + + struct space *space = space_cache_find(request->space_id); + access_check_space(access, user, space); + + /* Try to find tuple by primary key */ + Index *pk = index_find(space, 0); + const char *key = request->key; + uint32_t part_count = mp_decode_array(&key); + primary_key_validate(pk->key_def, key, part_count); + struct tuple *old_tuple = pk->findByKey(key, part_count); + + txn_add_redo(txn, request); + if (old_tuple == NULL) + return; + txn_replace(txn, space, old_tuple, NULL, DUP_REPLACE_OR_INSERT); +} + static void execute_select(struct request *request, struct txn *txn, struct port *port) { (void) txn; - struct space *space = space_find(request->space_id); + struct user *user = user(); + uint8_t access = PRIV_R & ~user->universal_access; + struct space *space = space_cache_find(request->space_id); + access_check_space(access, user, space); Index *index = index_find(space, request->index_id); ERROR_INJECT_EXCEPTION(ERRINJ_TESTING); @@ -138,13 +188,16 @@ execute_select(struct request *request, struct txn *txn, struct port *port) uint32_t found = 0; uint32_t offset = request->offset; uint32_t limit = request->limit; + if (request->iterator >= iterator_type_MAX) + tnt_raise(IllegalParams, "Invalid iterator type"); + enum iterator_type type = (enum iterator_type) request->iterator; const char *key = request->key; uint32_t part_count = mp_decode_array(&key); struct iterator *it = index->position(); - key_validate(index->key_def, ITER_EQ, key, part_count); - index->initIterator(it, ITER_EQ, key, part_count); + key_validate(index->key_def, type, key, part_count); + index->initIterator(it, type, key, part_count); struct tuple *tuple; while ((tuple = it->next(it)) != NULL) { @@ -158,31 +211,22 @@ execute_select(struct request *request, struct txn *txn, struct port *port) } } -static void -execute_delete(struct request *request, struct txn *txn, struct port *port) +void +execute_auth(struct request *request, struct txn * /* txn */, + struct port * /* port */) { - (void) port; - txn_add_redo(txn, request); - struct space *space = space_find(request->space_id); - - /* Try to find tuple by primary key */ - Index *pk = index_find(space, 0); - const char *key = request->key; - uint32_t part_count = mp_decode_array(&key); - primary_key_validate(pk->key_def, key, part_count); - struct tuple *old_tuple = pk->findByKey(key, part_count); - - if (old_tuple == NULL) - return; - - txn_replace(txn, space, old_tuple, NULL, DUP_REPLACE_OR_INSERT); + const char *user = request->key; + uint32_t len = mp_decode_strl(&user); + authenticate(user, len, request->tuple, request->tuple_end); } +/** }}} */ + void request_check_type(uint32_t type) { if (type < IPROTO_SELECT || type >= IPROTO_DML_REQUEST_MAX) - tnt_raise(IllegalParams, "unknown request type %u", type); + tnt_raise(LoggedError, ER_UNKNOWN_REQUEST_TYPE, type); } void @@ -191,7 +235,8 @@ request_create(struct request *request, uint32_t type) request_check_type(type); static const request_execute_f execute_map[] = { NULL, execute_select, execute_replace, execute_replace, - execute_update, execute_delete, box_lua_call + execute_update, execute_delete, box_lua_call, + execute_auth, }; memset(request, 0, sizeof(*request)); request->type = type; @@ -236,15 +281,19 @@ request_decode(struct request *request, const char *data, uint32_t len) case IPROTO_LIMIT: request->limit = mp_decode_uint(&value); break; + case IPROTO_ITERATOR: + request->iterator = mp_decode_uint(&value); + break; case IPROTO_TUPLE: request->tuple = value; request->tuple_end = data; break; case IPROTO_KEY: case IPROTO_FUNCTION_NAME: - default: + case IPROTO_USER_NAME: request->key = value; request->key_end = data; + default: break; } } diff --git a/src/box/request.h b/src/box/request.h index 6b7b40600e5be38a2cfb41a1b2177a31b46265bb..e87a46c4c918a273323b8d3b87ccd1a4e74cec72 100644 --- a/src/box/request.h +++ b/src/box/request.h @@ -45,6 +45,7 @@ struct request uint32_t index_id; uint32_t offset; uint32_t limit; + uint32_t iterator; /* Search key or proc name. */ const char *key; const char *key_end; diff --git a/src/box/schema.cc b/src/box/schema.cc index 5e242e2ab15076f4017e8561a3e32219ee42fee1..83399b6d1b915477e1ee610766973a7d9c37c339 100644 --- a/src/box/schema.cc +++ b/src/box/schema.cc @@ -27,6 +27,7 @@ * SUCH DAMAGE. */ #include "schema.h" +#include "access.h" #include "space.h" #include "tuple.h" #include "assoc.h" @@ -53,6 +54,7 @@ /** All existing spaces. */ static struct mh_i32ptr_t *spaces; +static struct mh_i32ptr_t *funcs; int sc_version; bool @@ -107,7 +109,7 @@ space_foreach(void (*func)(struct space *sp, void *udata), void *udata) while ((tuple = it->next(it))) { /* Get space id, primary key, field 0. */ uint32_t id = tuple_field_u32(tuple, 0); - space = space_find(id); + space = space_cache_find(id); if (! space_is_system(space)) break; func(space, udata); @@ -197,6 +199,24 @@ sc_space_new(struct space_def *space_def, return space; } +uint32_t +schema_find_id(uint32_t system_space_id, uint32_t index_id, + const char *name, uint32_t len) +{ + struct space *space = space_cache_find(system_space_id); + Index *index = index_find(space, index_id); + struct iterator *it = index->position(); + char key[5 /* str len */ + BOX_NAME_MAX]; + mp_encode_str(key, name, len); + index->initIterator(it, ITER_EQ, key, 1); + struct tuple *tuple; + while ((tuple = it->next(it))) { + /* id is always field #1 */ + return tuple_field_u32(tuple, 0); + } + return SC_ID_NIL; +} + /** * Initialize a prototype for the two mandatory data * dictionary spaces and create a cache entry for them. @@ -208,6 +228,7 @@ schema_init() { /* Initialize the space cache. */ spaces = mh_i32ptr_new(); + funcs = mh_i32ptr_new(); /* * Create surrogate space objects for the mandatory system * spaces (the primal eggs from which we get all the @@ -219,7 +240,9 @@ schema_init() * (and re-created) first. */ /* _schema - key/value space with schema description */ - struct space_def def = { SC_SCHEMA_ID, 0, "_schema", false }; + struct space_def def = { + SC_SCHEMA_ID, ADMIN, 0, "_schema", MEMTX, false + }; struct key_def *key_def = key_def_new(def.id, 0 /* index id */, "primary", /* name */ @@ -235,6 +258,23 @@ schema_init() key_def_set_part(key_def, 0 /* part no */, 0 /* field no */, NUM); (void) sc_space_new(&def, key_def, &alter_space_on_replace_space); + + /* _user - all existing users */ + key_def->space_id = def.id = SC_USER_ID; + snprintf(def.name, sizeof(def.name), "_user"); + (void) sc_space_new(&def, key_def, &on_replace_user); + + /* _func - all executable objects on which one can have grants */ + key_def->space_id = def.id = SC_FUNC_ID; + snprintf(def.name, sizeof(def.name), "_func"); + (void) sc_space_new(&def, key_def, &on_replace_func); + /* + * _priv - association user <-> object + * The real index is defined in the snapshot. + */ + key_def->space_id = def.id = SC_PRIV_ID; + snprintf(def.name, sizeof(def.name), "_priv"); + (void) sc_space_new(&def, key_def, &on_replace_priv); key_def_delete(key_def); /* _index - definition of indexes in all spaces */ @@ -298,4 +338,57 @@ schema_free(void) space_delete(space); } mh_i32ptr_delete(spaces); + while (mh_size(funcs) > 0) { + mh_int_t i = mh_first(funcs); + + struct func_def *func = (struct func_def *) + mh_i32ptr_node(funcs, i)->val; + func_cache_delete(func->fid); + } + mh_i32ptr_delete(funcs); +} + +void +func_cache_replace(struct func_def *func) +{ + struct func_def *old = func_by_id(func->fid); + if (old) { + *old = *func; + return; + } + if (mh_size(funcs) >= BOX_FUNCTION_MAX) + tnt_raise(ClientError, ER_FUNCTION_MAX, BOX_FUNCTION_MAX); + void *ptr = malloc(sizeof(*func)); + if (ptr == NULL) { +error: + panic_syserror("Out of memory for the data " + "dictionary cache."); + } + memcpy(ptr, func, sizeof(*func)); + func = (struct func_def *) ptr; + const struct mh_i32ptr_node_t node = { func->fid, func }; + mh_int_t k = mh_i32ptr_put(funcs, &node, NULL, NULL); + if (k == mh_end(funcs)) + goto error; +} + +void +func_cache_delete(uint32_t fid) +{ + mh_int_t k = mh_i32ptr_find(funcs, fid, NULL); + if (k == mh_end(funcs)) + return; + struct func_def *func = (struct func_def *) + mh_i32ptr_node(funcs, k)->val; + mh_i32ptr_del(funcs, k, NULL); + free(func); +} + +struct func_def * +func_by_id(uint32_t fid) +{ + mh_int_t func = mh_i32ptr_find(funcs, fid, NULL); + if (func == mh_end(funcs)) + return NULL; + return (struct func_def *) mh_i32ptr_node(funcs, func)->val; } diff --git a/src/box/schema.h b/src/box/schema.h index 76873bb9495151197e1a3405bc988447b2508ea4..097cbc7417d6a073017a3679efcbd2e93d3f2db0 100644 --- a/src/box/schema.h +++ b/src/box/schema.h @@ -39,10 +39,18 @@ enum schema_id { SC_SPACE_ID = 280, /** Space id of _index. */ SC_INDEX_ID = 288, + /** Space id of _func. */ + SC_FUNC_ID = 296, + /** Space id of _user. */ + SC_USER_ID = 304, + /** Space id of _priv. */ + SC_PRIV_ID = 312, /** End of the reserved range of system spaces. */ SC_SYSTEM_ID_MAX = 511 }; +enum { SC_ID_NIL = 4294967295 }; + extern int sc_version; struct space; @@ -65,7 +73,7 @@ extern "C" const char * space_name_by_id(uint32_t id); static inline struct space * -space_find(uint32_t id) +space_cache_find(uint32_t id) { struct space *space = space_by_id(id); if (space) @@ -111,4 +119,36 @@ space_end_recover(); struct space *schema_space(uint32_t id); +/* + * Find object id by object name. + */ +uint32_t +schema_find_id(uint32_t system_space_id, uint32_t index_id, + const char *name, uint32_t len); + +void +func_cache_replace(struct func_def *func); + +void +func_cache_delete(uint32_t fid); + +struct func_def * +func_by_id(uint32_t fid); + +static inline struct func_def * +func_cache_find(uint32_t fid) +{ + struct func_def *func = func_by_id(fid); + if (func == NULL) + tnt_raise(ClientError, ER_NO_SUCH_FUNCTION, int2str(fid)); + return func; +} + +static inline struct func_def * +func_by_name(const char *name, uint32_t name_len) +{ + uint32_t fid = schema_find_id(SC_FUNC_ID, 2, name, name_len); + return func_by_id(fid); +} + #endif /* INCLUDES_TARANTOOL_BOX_SCHEMA_H */ diff --git a/src/box/space.cc b/src/box/space.cc index c484bb2255e66733a3abe53c1bf9e9936e5d4e80..d438fac6e305b79bed4f17e67210eea0b00dc6c0 100644 --- a/src/box/space.cc +++ b/src/box/space.cc @@ -34,6 +34,15 @@ #include "scoped_guard.h" #include "trigger.h" +static struct engine* +space_engine_find(const char *name) +{ + if (strcmp(name, MEMTX) == 0) + return &engine_no_keys; + + tnt_raise(LoggedError, ER_NO_SUCH_ENGINE, name); +} + void space_fill_index_map(struct space *space) { @@ -81,7 +90,7 @@ space_new(struct space_def *def, struct rlist *key_list) space->index_map[key_def->iid] = Index::factory(key_def); } space_fill_index_map(space); - space->engine = engine_no_keys; + space->engine = *space_engine_find(def->engine_name); space->run_triggers = true; scoped_guard.is_active = false; return space; diff --git a/src/box/space.h b/src/box/space.h index 6f57c0f345087361ae91f32f89e173121516aa8d..146700e27a1cecff26524d8d53a77a3147b13a64 100644 --- a/src/box/space.h +++ b/src/box/space.h @@ -72,11 +72,15 @@ struct engine { space_replace_f replace; }; +#define MEMTX "memtx" + extern struct engine engine_no_keys; + void space_build_primary_key(struct space *space); void space_build_all_keys(struct space *space); struct space { + uint8_t access[BOX_USER_MAX]; /** * Reflects the current space state and is also a vtab * with methods. Unlike a C++ vtab, changes during space diff --git a/src/box/tuple.h b/src/box/tuple.h index b608c0b43542e25399de1b9957188f0dd58d2f50..0f94a4c0a1053cc956cf2e9e66b887dbe23a8bab 100644 --- a/src/box/tuple.h +++ b/src/box/tuple.h @@ -442,6 +442,13 @@ tuple_to_obuf(struct tuple *tuple, struct obuf *buf); void tuple_to_tbuf(struct tuple *tuple, struct tbuf *buf); +/** + * Store tuple fields in the memory buffer. Buffer must have at least + * tuple->bsize bytes. + */ +extern "C" void +tuple_to_buf(struct tuple *tuple, char *buf); + /** Initialize tuple library */ void tuple_init(float slab_alloc_arena, uint32_t slab_alloc_minimal, diff --git a/src/box/tuple_convert.cc b/src/box/tuple_convert.cc index b06179bced98581ef826fdd4a4d98add76b1235e..5e1346dd85115dcff78798035294e1278e66159c 100644 --- a/src/box/tuple_convert.cc +++ b/src/box/tuple_convert.cc @@ -41,3 +41,9 @@ tuple_to_tbuf(struct tuple *tuple, struct tbuf *buf) { tbuf_append(buf, tuple->data, tuple->bsize); } + +void +tuple_to_buf(struct tuple *tuple, char *buf) +{ + memcpy(buf, tuple->data, tuple->bsize); +} diff --git a/src/box/txn.cc b/src/box/txn.cc index f6c3539cc8d48f874691ce689681a7833e54fedf..e227be0da1c8f208073feb7bc0a6ba0bda3dd930 100644 --- a/src/box/txn.cc +++ b/src/box/txn.cc @@ -35,12 +35,6 @@ #include <fiber.h> #include "request.h" /* for request_name */ -void -txn_add_redo(struct txn *txn, struct request *request) -{ - txn->request = request; -} - void txn_replace(struct txn *txn, struct space *space, struct tuple *old_tuple, struct tuple *new_tuple, diff --git a/src/box/txn.h b/src/box/txn.h index 505aef6b5c7185412b55ce577ca95764abf94489..fb0802d3361394390d0c97edc11be13f3a0fc5d8 100644 --- a/src/box/txn.h +++ b/src/box/txn.h @@ -47,11 +47,16 @@ struct txn { struct request *request; }; +static inline void +txn_add_redo(struct txn *txn, struct request *request) +{ + txn->request = request; +} + struct txn *txn_begin(); void txn_commit(struct txn *txn); void txn_finish(struct txn *txn); void txn_rollback(struct txn *txn); -void txn_add_redo(struct txn *txn, struct request *request); void txn_replace(struct txn *txn, struct space *space, struct tuple *old_tuple, struct tuple *new_tuple, enum dup_replace_mode mode); diff --git a/src/errcode.h b/src/errcode.h index 208e754cf3a65076a2802e72427b831333e42e89..0063ca966637b40fc66427aa1c69fcbd3b9a3be7 100644 --- a/src/errcode.h +++ b/src/errcode.h @@ -91,6 +91,22 @@ enum { TNT_ERRMSG_MAX = 512 }; /* 39 */_(ER_INDEX_ARITY, 2, "Tuple field count %u is less than required by a defined index (expected %u)") \ /* 40 */_(ER_WAL_IO, 2, "Failed to write to disk") \ /* 41 */_(ER_MORE_THAN_ONE_TUPLE, 2, "More than one tuple found") \ + /* 42 */_(ER_ACCESS_DENIED, 2, "%s access denied for user '%s'") \ + /* 43 */_(ER_CREATE_USER, 2, "Failed to create user '%s': %s") \ + /* 44 */_(ER_DROP_USER, 2, "Failed to drop user '%s': %s") \ + /* 45 */_(ER_NO_SUCH_USER, 2, "User '%s' is not found") \ + /* 46 */_(ER_USER_EXISTS, 2, "User '%s' already exists") \ + /* 47 */_(ER_PASSWORD_MISMATCH, 2, "Incorrect password supplied for user '%s'") \ + /* 48 */_(ER_UNKNOWN_REQUEST_TYPE, 2, "Unknown request type %u") \ + /* 49 */_(ER_UNKNOWN_SCHEMA_OBJECT, 2, "Unknown object type '%s'") \ + /* 50 */_(ER_CREATE_FUNCTION, 2, "Failed to create function: %s") \ + /* 51 */_(ER_NO_SUCH_FUNCTION, 2, "Function '%s' does not exist") \ + /* 52 */_(ER_FUNCTION_EXISTS, 2, "Function '%s' already exists") \ + /* 53 */_(ER_FUNCTION_ACCESS_DENIED, 2, "%s access denied for user '%s' to function '%s'") \ + /* 54 */_(ER_FUNCTION_MAX, 2, "A limit on the total number of functions has been reached: %u") \ + /* 55 */_(ER_SPACE_ACCESS_DENIED, 2, "%s access denied for user '%s' to space '%s'") \ + /* 56 */_(ER_USER_MAX, 2, "A limit on the total number of users has been reached: %u") \ + /* 57 */_(ER_NO_SUCH_ENGINE, 2, "Space engine '%s' does not exist") \ /* diff --git a/src/ffisyms.cc b/src/ffisyms.cc index 8ac28fb7fbe6dd91b4e118483ff5386f908886a2..6b3dc5d202276815036cd2f604012d4e242876ae 100644 --- a/src/ffisyms.cc +++ b/src/ffisyms.cc @@ -1,11 +1,14 @@ #include <bit/bit.h> #include <lib/msgpuck/msgpuck.h> +#include "scramble.h" #include <box/tuple.h> #include <box/lua/index.h> +#include <box/lua/call.h> /* * A special hack to cc/ld to keep symbols in an optimized binary. - * Please add your symbols to this array if you plan to use it from LuaJIT FFI. + * Please add your symbols to this array if you plan to use it from + * LuaJIT FFI. */ void *ffi_symbols[] = { (void *) bswap_u32, @@ -18,5 +21,9 @@ void *ffi_symbols[] = { (void *) tuple_seek, (void *) tuple_next, (void *) tuple_ref, - (void *) boxffi_index_iterator + (void *) boxffi_index_iterator, + (void *) port_ffi_create, + (void *) port_ffi_destroy, + (void *) boxffi_select, + (void *) password_prepare }; diff --git a/src/fiber.cc b/src/fiber.cc index 7042c3477b0b0e06e930c7266c7c3d9ed2e53754..dd24d949adcb65607aa5b337417f224114648222 100644 --- a/src/fiber.cc +++ b/src/fiber.cc @@ -443,7 +443,6 @@ fiber_new(const char *name, void (*f) (va_list)) rlist_create(&fiber->state); } - fiber->f = f; /* fids from 0 to 100 are reserved */ diff --git a/src/iproto.cc b/src/iproto.cc index e0af04080c77c934568babe0777a67233cc6d999..808bbac059762a615252e100b086b2cc151d68ba 100644 --- a/src/iproto.cc +++ b/src/iproto.cc @@ -44,6 +44,8 @@ #include "memory.h" #include "msgpuck/msgpuck.h" #include "replication.h" +#include "third_party/base64.h" +#include "coio.h" class IprotoConnectionShutdown: public Exception { @@ -531,8 +533,8 @@ iproto_process_admin(struct iproto_request *ireq, subscribe_request_decode(body, end)); tnt_raise(IprotoConnectionShutdown); default: - tnt_raise(IllegalParams, "unknown request type %u", - ireq->header[IPROTO_CODE]); + tnt_raise(ClientError, ER_UNKNOWN_REQUEST_TYPE, + (uint32_t) ireq->header[IPROTO_CODE]); } if (! ev_is_active(&con->output)) ev_feed_event(con->loop, &con->output, EV_WRITE); @@ -762,6 +764,20 @@ iproto_request_new(struct iproto_connection *con, return ireq; } +const char * +iproto_greeting(int *salt) +{ + static __thread char greeting[IPROTO_GREETING_SIZE + 1]; + char base64buf[SESSION_SEED_SIZE * 4 / 3 + 5]; + + base64_encode((char *) salt, SESSION_SEED_SIZE, + base64buf, sizeof(base64buf)); + snprintf(greeting, sizeof(greeting), + "Tarantool %-20s %-32s\n%-63s\n", + tarantool_version(), custom_proc_title, base64buf); + return greeting; +} + /** * Handshake a connection: invoke the on-connect trigger * and possibly authenticate. Try to send the client an error @@ -775,6 +791,8 @@ iproto_process_connect(struct iproto_request *request) int fd = con->input.fd; try { /* connect. */ con->session = session_create(fd, con->cookie); + coio_write(&con->input, iproto_greeting(con->session->salt), + IPROTO_GREETING_SIZE); } catch (ClientError *e) { iproto_reply_error(&iobuf->out, e, request->header[IPROTO_SYNC]); try { diff --git a/src/iproto_constants.c b/src/iproto_constants.c index 6700ee3dff19c63ff87c110ffa9658de948781bd..6ff8a308be680f9f5943f9a3401a0816e332e6fa 100644 --- a/src/iproto_constants.c +++ b/src/iproto_constants.c @@ -51,6 +51,7 @@ unsigned char iproto_key_type[IPROTO_KEY_MAX] = /* 0x20 */ MP_ARRAY, /* IPROTO_KEY */ /* 0x21 */ MP_ARRAY, /* IPROTO_TUPLE */ /* 0x22 */ MP_STR, /* IPROTO_FUNCTION_NAME */ + /* 0x23 */ MP_STR, /* IPROTO_USER_NAME */ /* }}} */ }; diff --git a/src/iproto_constants.h b/src/iproto_constants.h index 1de71a8f61331b8773609899162c62a525969bbb..63ff74afe499c822529c5ce3d4f4e80045040137 100644 --- a/src/iproto_constants.h +++ b/src/iproto_constants.h @@ -33,9 +33,11 @@ enum { /** Maximal iproto package body length (2GiB) */ - IPROTO_BODY_LEN_MAX = 2147483648UL + IPROTO_BODY_LEN_MAX = 2147483648UL, + IPROTO_GREETING_SIZE = 128, }; + enum iproto_key { IPROTO_CODE = 0x00, IPROTO_SYNC = 0x01, @@ -49,6 +51,7 @@ enum iproto_key { IPROTO_KEY = 0x20, IPROTO_TUPLE = 0x21, IPROTO_FUNCTION_NAME = 0x22, + IPROTO_USER_NAME = 0x23, /* Leave a gap between request keys and response keys */ IPROTO_DATA = 0x30, IPROTO_ERROR = 0x31, @@ -60,7 +63,7 @@ enum iproto_key { #define IPROTO_HEAD_BMAP (bit(CODE) | bit(SYNC)) #define IPROTO_BODY_BMAP (bit(SPACE_ID) | bit(INDEX_ID) | bit(LIMIT) |\ bit(OFFSET) | bit(KEY) | bit(TUPLE) | \ - bit(FUNCTION_NAME)) + bit(FUNCTION_NAME) | bit(USER_NAME)) static inline bool iproto_header_has_key(const char *pos, const char *end) { @@ -87,9 +90,9 @@ enum iproto_request_type { IPROTO_UPDATE = 4, IPROTO_DELETE = 5, IPROTO_CALL = 6, - IPROTO_DML_REQUEST_MAX = 7, + IPROTO_AUTH = 7, + IPROTO_DML_REQUEST_MAX = 8, IPROTO_PING = 64, - IPROTO_AUTH = 65, IPROTO_SUBSCRIBE = 66 }; diff --git a/src/lua/init.cc b/src/lua/init.cc index 69a5dcd9be61c3a0c3c92149e7af22770b6ccd01..0e97ccbb378a1b0863ab9b80e06c1a88278c9de2 100644 --- a/src/lua/init.cc +++ b/src/lua/init.cc @@ -67,10 +67,10 @@ extern "C" { struct lua_State *tarantool_L; /* contents of src/lua/ files */ -extern char uuid_lua[], session_lua[], msgpackffi_lua[]; -static const char *lua_sources[] = { uuid_lua, session_lua, msgpackffi_lua, - NULL }; - +extern char uuid_lua[], session_lua[], msgpackffi_lua[], fun_lua[]; +static const char *lua_sources[] = { uuid_lua, session_lua, NULL }; +static const char *lua_modules[] = { "msgpackffi", msgpackffi_lua, + "fun", fun_lua, NULL }; /* * {{{ box Lua library: common functions */ @@ -317,6 +317,21 @@ tarantool_lua_init() luaopen_msgpack(L); lua_pop(L, 1); + lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED"); + for (const char **s = lua_modules; *s; s += 2) { + const char *modname = *s; + const char *modsrc = *(s + 1); + const char *modfile = lua_pushfstring(L, + "@builtin/%s.lua", modname); + if (luaL_loadbuffer(L, modsrc, strlen(modsrc), modfile)) + panic("Error loading Lua module %s...: %s", + modname, lua_tostring(L, -1)); + lua_call(L, 0, 1); + lua_setfield(L, -3, modname); /* package.loaded.modname = t */ + lua_pop(L, 1); /* chunkname */ + } + lua_pop(L, 1); /* _LOADED */ + /* Load Lua extension */ for (const char **s = lua_sources; *s; s++) { if (luaL_dostring(L, *s)) diff --git a/src/lua/msgpack.cc b/src/lua/msgpack.cc index 2370d8277a3598feb29025f988d7b82e1af7234b..f4f8519c1a105b65e2476490078b1ee2e93b3082 100644 --- a/src/lua/msgpack.cc +++ b/src/lua/msgpack.cc @@ -383,36 +383,16 @@ lua_msgpack_encode(lua_State *L) static int lua_msgpack_decode(lua_State *L) -{ - int index = lua_gettop(L); - if (index != 1 || lua_type(L, index) != LUA_TSTRING) - return luaL_error(L, "msgpack.decode: a Lua string expected"); - - size_t data_len; - const char *data = lua_tolstring(L, index, &data_len); - const char *end = data + data_len; - - const char *b = data; - if (mp_check(&b, end) || b != end) - return luaL_error(L, "msgpack.decode: invalid MsgPack"); - - b = data; - luamp_decode(L, &b); - return 1; -} - -static int -lua_msgpack_next(lua_State *L) { int index = lua_gettop(L); if (index != 2 && index != 1 && lua_type(L, 1) != LUA_TSTRING) - return luaL_error(L, "msgpack.next: a Lua string expected"); + return luaL_error(L, "msgpack.decode: a Lua string expected"); size_t data_len; uint32_t offset = index > 1 ? lua_tointeger(L, 2) - 1 : 0; const char *data = lua_tolstring(L, 1, &data_len); if (offset >= data_len) - luaL_error(L, "msgpack.next: offset is out of bounds"); + luaL_error(L, "msgpack.decode: offset is out of bounds"); const char *end = data + data_len; const char *b = data + offset; @@ -433,7 +413,6 @@ luaopen_msgpack(lua_State *L) { "dumps", lua_msgpack_encode }, { "decode", lua_msgpack_decode }, { "loads", lua_msgpack_decode }, - { "next", lua_msgpack_next}, { NULL, NULL} }; diff --git a/src/lua/msgpackffi.lua b/src/lua/msgpackffi.lua index bd45236fad4bc824533e6fd11fea6a5d38abfd28..4429bbcb4fbd9eb6111f6595c1baabffbc885b65 100644 --- a/src/lua/msgpackffi.lua +++ b/src/lua/msgpackffi.lua @@ -507,7 +507,7 @@ end -- exports -------------------------------------------------------------------------------- -package.loaded.msgpackffi = { +return { NULL = NULL; encode = encode; on_encode = on_encode; diff --git a/src/lua/session.cc b/src/lua/session.cc index 6112ac2a7d05932abbdab008b59b180fce22dab5..d428f1ef700f7d6c9a01086a9857de6db142c7de 100644 --- a/src/lua/session.cc +++ b/src/lua/session.cc @@ -29,6 +29,7 @@ #include "lua/session.h" #include "lua/utils.h" #include "lua/trigger.h" +#include "box/access.h" extern "C" { #include <lua.h> @@ -57,6 +58,57 @@ lbox_session_id(struct lua_State *L) return 1; } +/** Session user id. */ +static int +lbox_session_uid(struct lua_State *L) +{ + lua_pushnumber(L, fiber()->session ? + fiber()->session->uid : (int) GUEST); + return 1; +} + +/** Session user id. */ +static int +lbox_session_user(struct lua_State *L) +{ + struct user *user = NULL; + if (fiber()->session) + user = user_cache_find(fiber()->session->uid); + if (user) + lua_pushstring(L, user->name); + else + lua_pushnil(L); + return 1; +} + +/** Session user id. */ +static int +lbox_session_su(struct lua_State *L) +{ + if (lua_gettop(L) != 1) + luaL_error(L, "session.su(): bad arguments"); + struct session *session = fiber()->session; + if (session == NULL) + luaL_error(L, "session.su(): session does not exit"); + struct user *user; + if (lua_type(L, 1) == LUA_TSTRING) { + size_t len; + const char *name = lua_tolstring(L, 1, &len); + user = user_by_name(name, len); + if (user == NULL) + tnt_raise(ClientError, ER_NO_SUCH_USER, name); + } else { + uint32_t uid = lua_tointeger(L, 1);; + user = user_cache_find(uid); + if (user == NULL) { + tnt_raise(ClientError, ER_NO_SUCH_USER, + int2str(uid)); + } + } + session_set_user(session, user->auth_token, user->uid); + return 0; +} + /** * Check whether or not a session exists. */ @@ -159,6 +211,9 @@ tarantool_lua_session_init(struct lua_State *L) { static const struct luaL_reg sessionlib[] = { {"id", lbox_session_id}, + {"uid", lbox_session_uid}, + {"user", lbox_session_user}, + {"su", lbox_session_su}, {"fd", lbox_session_fd}, {"exists", lbox_session_exists}, {"peer", lbox_session_peer}, diff --git a/src/module/sql/sql.lua b/src/module/sql/sql.lua index d84d7b9f307303bda10cfa2e3f2322e0dc197f4e..4b014c2a32e3166246860752292e1a4f3ad58097 100644 --- a/src/module/sql/sql.lua +++ b/src/module/sql/sql.lua @@ -92,9 +92,9 @@ box.net.sql = { execute = function(self, sql, ...) -- waits until connection will be free while self.processing do - self.queue[ box.fiber.fid ] = box.ipc.channel() - self.queue[ box.fiber.fid ]:get() - self.queue[ box.fiber.fid ] = nil + self.queue[ box.fiber.id() ] = box.ipc.channel() + self.queue[ box.fiber.id() ]:get() + self.queue[ box.fiber.id() ] = nil end self.processing = true diff --git a/test/connector_c/xlog.c b/src/random.c similarity index 52% rename from test/connector_c/xlog.c rename to src/random.c index b7543509e50512c665e272e69674a0122020ef19..914e631b3a4e0414e6490dea29624661dbb040e2 100644 --- a/test/connector_c/xlog.c +++ b/src/random.c @@ -26,57 +26,26 @@ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ +#include "random.h" +#include <sys/types.h> +#include <fcntl.h> +#include <sys/stat.h> +#include <unistd.h> #include <stdlib.h> -#include <stdint.h> -#include <inttypes.h> -#include <stdbool.h> -#include <stdio.h> -#include <string.h> -#include <connector/c/include/tarantool/tnt.h> -#include <connector/c/include/tarantool/tnt_net.h> -#include <connector/c/include/tarantool/tnt_xlog.h> -#include <connector/c/include/tarantool/tnt_rpl.h> +#ifdef __linux__ +#define DEV_RANDOM "/dev/urandom" +#else +#define DEV_RANDOM "/dev/random" +#endif -static char *opname(uint32_t type) { - switch (type) { - case TNT_OP_PING: return "Ping"; - case TNT_OP_INSERT: return "Insert"; - case TNT_OP_DELETE: return "Delete"; - case TNT_OP_UPDATE: return "Update"; - case TNT_OP_SELECT: return "Select"; - case TNT_OP_CALL: return "Call"; - } - return "Unknown"; -} - -int -main(int argc, char * argv[]) +void +random_init(void) { - if (argc != 2) - return 1; - - struct tnt_stream s; - tnt_xlog(&s); - - if (tnt_xlog_open(&s, argv[1]) == -1) - return 1; - - struct tnt_iter i; - tnt_iter_request(&i, &s); - - while (tnt_next(&i)) { - struct tnt_stream_xlog *sx = TNT_SXLOG_CAST(&s); - printf("%s lsn: %"PRIu64", time: %f, len: %d\n", - opname(sx->log.current.row.op), - sx->log.current.hdr.lsn, - sx->log.current.hdr.tm, - sx->log.current.hdr.len); - } - if (i.status == TNT_ITER_FAIL) - printf("parsing failed: %s\n", tnt_xlog_strerror(&s)); - - tnt_iter_free(&i); - tnt_stream_free(&s); - return 0; + int fd = open(DEV_RANDOM, O_RDONLY); + long int seed; + read(fd, &seed, sizeof(seed)); + close(fd); + srandom(seed); + srand(seed); } diff --git a/src/random.h b/src/random.h new file mode 100644 index 0000000000000000000000000000000000000000..98cd0e5e4ec16716882f5ec495d2a0285c04c888 --- /dev/null +++ b/src/random.h @@ -0,0 +1,40 @@ +#ifndef INCLUDES_TARANTOOL_RANDOM_H +#define INCLUDES_TARANTOOL_RANDOM_H +/* + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * 1. Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * <COPYRIGHT HOLDER> OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#if defined(__cplusplus) +extern "C" { +#endif +void +random_init(void); + +#if defined(__cplusplus) +} +#endif /* extern "C" */ +#endif /* INCLUDES_TARANTOOL_RANDOM_H */ diff --git a/src/replica.cc b/src/replica.cc index f627d131d504d86fa6679558ebabe1d5ed6babc0..18ab56e1a0088de5745f5820646fd20f44da88fc 100644 --- a/src/replica.cc +++ b/src/replica.cc @@ -90,6 +90,7 @@ int replica_bootstrap(const char *replication_source) { char ip_addr[32]; + char greeting[IPROTO_GREETING_SIZE]; int port; struct sockaddr_in addr; memset(&addr, 0, sizeof(addr)); @@ -109,7 +110,8 @@ replica_bootstrap(const char *replication_source) int master = sio_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); FDGuard guard(master); sio_connect(master, &addr, sizeof(addr)); - sio_write(master, &iproto_subscribe_request, + sio_readn(master, greeting, sizeof(greeting)); + sio_writen(master, &iproto_subscribe_request, sizeof(iproto_subscribe_request)); guard.fd = -1; @@ -120,10 +122,12 @@ static void remote_connect(struct ev_io *coio, struct sockaddr_in *remote_addr, int64_t initial_lsn, const char **err) { + char greeting[IPROTO_GREETING_SIZE]; evio_socket(coio, AF_INET, SOCK_STREAM, IPPROTO_TCP); *err = "can't connect to master"; coio_connect(coio, remote_addr); + coio_readn(coio, greeting, sizeof(greeting)); struct iproto_subscribe_request request = iproto_subscribe_request; request.lsn = mp_bswap_u64(initial_lsn); diff --git a/src/scramble.c b/src/scramble.c new file mode 100644 index 0000000000000000000000000000000000000000..4773e38a10456c41310af1b94a0a0690393406d0 --- /dev/null +++ b/src/scramble.c @@ -0,0 +1,106 @@ +/* + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * 1. Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * <COPYRIGHT HOLDER> OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include "scramble.h" +#include "third_party/sha1.h" +#include "third_party/base64.h" +#include <string.h> +#include <stdio.h> + +static void +xor(unsigned char *to, unsigned const char *left, + unsigned const char *right, uint32_t len) +{ + const uint8_t *end = to + len; + while (to < end) + *to++= *left++ ^ *right++; +} + +void +scramble_prepare(void *out, const void *salt, const void *password, + int password_len) +{ + unsigned char hash1[SCRAMBLE_SIZE]; + unsigned char hash2[SCRAMBLE_SIZE]; + SHA1_CTX ctx; + + SHA1Init(&ctx); + SHA1Update(&ctx, password, password_len); + SHA1Final(hash1, &ctx); + + SHA1Init(&ctx); + SHA1Update(&ctx, hash1, SCRAMBLE_SIZE); + SHA1Final(hash2, &ctx); + + SHA1Init(&ctx); + SHA1Update(&ctx, salt, SCRAMBLE_SIZE); + SHA1Update(&ctx, hash2, SCRAMBLE_SIZE); + SHA1Final(out, &ctx); + + xor(out, hash1, out, SCRAMBLE_SIZE); +} + +int +scramble_check(const void *scramble, const void *salt, const void *hash2) +{ + SHA1_CTX ctx; + unsigned char candidate_hash2[SCRAMBLE_SIZE]; + + SHA1Init(&ctx); + SHA1Update(&ctx, salt, SCRAMBLE_SIZE); + SHA1Update(&ctx, hash2, SCRAMBLE_SIZE); + SHA1Final(candidate_hash2, &ctx); + + xor(candidate_hash2, candidate_hash2, scramble, SCRAMBLE_SIZE); + /* + * candidate_hash2 now supposedly contains hash1, turn it + * into hash2 + */ + SHA1Init(&ctx); + SHA1Update(&ctx, candidate_hash2, SCRAMBLE_SIZE); + SHA1Final(candidate_hash2, &ctx); + + return memcmp(hash2, candidate_hash2, SCRAMBLE_SIZE); +} + +void +password_prepare(const char *password, int len, char *out, int out_len) +{ + unsigned char hash2[SCRAMBLE_SIZE]; + SHA1_CTX ctx; + + SHA1Init(&ctx); + SHA1Update(&ctx, (const unsigned char *) password, len); + SHA1Final(hash2, &ctx); + + SHA1Init(&ctx); + SHA1Update(&ctx, hash2, SCRAMBLE_SIZE); + SHA1Final(hash2, &ctx); + + base64_encode((char *) hash2, SCRAMBLE_SIZE, out, out_len); +} diff --git a/src/scramble.h b/src/scramble.h new file mode 100644 index 0000000000000000000000000000000000000000..2a2a2a61eae182e89d4a11b42d4b927b8114ca1b --- /dev/null +++ b/src/scramble.h @@ -0,0 +1,93 @@ +#ifndef INCLUDES_TARANTOOL_SCRAMBLE_H +#define INCLUDES_TARANTOOL_SCRAMBLE_H +/* + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * 1. Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * <COPYRIGHT HOLDER> OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#if defined(__cplusplus) +extern "C" { +#endif +/** + * These are the core bits of the built-in Tarantool + * authentication. They implement the same algorithm as + * in MySQL 4.1 authentication: + * + * SERVER: seed = create_random_string() + * send(seed) + * + * CLIENT: recv(seed) + * hash1 = sha1("password") + * hash2 = sha1(hash1) + * reply = xor(hash1, sha1(seed, hash2)) + * + * ^^ these steps are done in scramble_prepare() + * + * send(reply) + * + * + * SERVER: recv(reply) + * + * hash1 = xor(reply, sha1(seed, hash2)) + * candidate_hash2 = sha1(hash1) + * check(candidate_hash2 == hash2) + * + * ^^ these steps are done in scramble_check() + */ + +enum { SCRAMBLE_SIZE = 20, SCRAMBLE_BASE64_SIZE = 28 }; + +/** + * Prepare a scramble (cipher) to send over the wire + * to the server for authentication. + */ +void +scramble_prepare(void *out, const void *salt, const void *password, + int password_len); + + +/** + * Verify a password. + * + * @retval 0 passwords do match + * @retval !0 passwords do not match + */ +int +scramble_check(const void *scramble, const void *salt, const void *hash2); + + +/** + * Prepare a password hash as is stored in the _user space. + * @pre out must be at least SCRAMBLE_BASE64_SIZE + * @post out contains base64_encode(sha1(sha1(password))) + */ +void +password_prepare(const char *password, int len, char *out, int out_len); + +#if defined(__cplusplus) +} /* extern "C" */ +#endif +#endif /* INCLUDES_TARANTOOL_SCRAMBLE_H */ diff --git a/src/session.cc b/src/session.cc index 624439d6fb42aafcabf11191917491d37b253d61..8a787fdd72e57ff5c166ddbb926edfdd435e1d07 100644 --- a/src/session.cc +++ b/src/session.cc @@ -35,8 +35,6 @@ #include "exception.h" #include <sys/socket.h> -uint32_t sid_max; - static struct mh_i32ptr_t *session_registry; struct mempool session_pool; @@ -44,18 +42,31 @@ struct mempool session_pool; RLIST_HEAD(session_on_connect); RLIST_HEAD(session_on_disconnect); -struct session * -session_create(int fd, uint64_t cookie) +static inline uint32_t +sid_max() { - struct session *session = (struct session *) - mempool_alloc(&session_pool); + static uint32_t sid_max = 0; /* Return the next sid rolling over the reserved value of 0. */ while (++sid_max == 0) ; + return sid_max; +} - session->id = sid_max; +struct session * +session_create(int fd, uint64_t cookie) +{ + struct session *session = (struct session *) + mempool_alloc(&session_pool); + session->id = sid_max(); session->fd = fd; session->cookie = cookie; + /* + * At first the session user is a superuser, + * to make sure triggers run correctly. + */ + session_set_user(session, ADMIN, ADMIN); + for (int i = 0; i < SESSION_SEED_SIZE/sizeof(*session->salt); i++) + session->salt[i] = rand(); struct mh_i32ptr_node_t node; node.key = session->id; node.val = session; @@ -80,6 +91,8 @@ session_create(int fd, uint64_t cookie) mempool_free(&session_pool, session); throw; } + /* Set session user to guest, until it is authenticated. */ + session_set_user(session, GUEST, GUEST); return session; } @@ -89,7 +102,8 @@ session_destroy(struct session *session) if (session == NULL) /* no-op for a dead session. */ return; fiber_set_session(fiber(), session); - + /* For triggers. */ + session_set_user(session, ADMIN, ADMIN); try { trigger_run(&session_on_disconnect, NULL); } catch (Exception *e) { diff --git a/src/session.h b/src/session.h index 1ef46bd5886c5cd0394dbae5bbefd05bdefb1b1c..7cb45b8e613fb9f47ac3a2ecedd7613891e15976 100644 --- a/src/session.h +++ b/src/session.h @@ -1,3 +1,5 @@ +#ifndef INCLUDES_TARANTOOL_SESSION_H +#define INCLUDES_TARANTOOL_SESSION_H /* * Redistribution and use in source and binary forms, with or * without modification, are permitted provided that the following @@ -30,6 +32,10 @@ #include <stdbool.h> #include "trigger.h" +enum { SESSION_SEED_SIZE = 32 }; +/** Predefined user ids. */ +enum { GUEST = 0, ADMIN = 1 }; + /** * Abstraction of a single user session: * for now, only provides accounting of established @@ -40,9 +46,17 @@ */ struct session { + /** Session id. */ uint32_t id; + /** File descriptor. */ int fd; + /** Peer cookie - description of the peer. */ uint64_t cookie; + /** Authentication salt. */ + int salt[SESSION_SEED_SIZE/sizeof(int)]; + /** A look up key to quickly find session user. */ + uint8_t auth_token; + uint32_t uid; }; /** @@ -71,7 +85,6 @@ session_create(int fd, uint64_t cookie); void session_destroy(struct session *); - /** * Return a file descriptor * associated with a session, or -1 if the @@ -89,6 +102,14 @@ session_exists(uint32_t sid) return session_fd(sid) >= 0; } +/** Set session auth token and user id. */ +static inline void +session_set_user(struct session *session, uint8_t auth_token, uint32_t uid) +{ + session->auth_token = auth_token; + session->uid = uid; +} + /* The global on-connect trigger. */ extern struct rlist session_on_connect; /* The global on-disconnect trigger. */ @@ -102,3 +123,4 @@ session_free(); void session_storage_cleanup(int sid); +#endif /* INCLUDES_TARANTOOL_SESSION_H */ diff --git a/src/sio.h b/src/sio.h index 4ccba5eed580ff642daab507a525d8f03ef635e7..49a135308be2b8e95a63af5d929e25970d9b35ca 100644 --- a/src/sio.h +++ b/src/sio.h @@ -81,7 +81,6 @@ int sio_listen_backlog(); int sio_accept(int fd, struct sockaddr_in *addr, socklen_t *addrlen); ssize_t sio_read(int fd, void *buf, size_t count); -ssize_t sio_read_total(int fd, void *buf, size_t count, size_t total); ssize_t sio_write(int fd, const void *buf, size_t count); ssize_t sio_writev(int fd, const struct iovec *iov, int iovcnt); diff --git a/src/tarantool.cc b/src/tarantool.cc index 532d2b565394636067e72a132038e69088f689b2..a0a6180cbc3729a3f355942671209365895c10e4 100644 --- a/src/tarantool.cc +++ b/src/tarantool.cc @@ -68,7 +68,7 @@ extern "C" { #include "session.h" #include "box/box.h" #include "scoped_guard.h" - +#include "random.h" static pid_t master_pid; const char *cfg_filename = NULL; @@ -608,6 +608,7 @@ main(int argc, char **argv) shebang = abspath(argv[0]); } + random_init(); say_init(argv[0]); crc32_init(); @@ -776,7 +777,6 @@ main(int argc, char **argv) strcpy(custom_proc_title, "@"); strcat(custom_proc_title, cfg.custom_proc_title); } - say_logger_init(cfg.logger, &cfg.log_level, cfg.logger_nonblock); say_crit("version %s", tarantool_version()); diff --git a/src/trivia/util.h b/src/trivia/util.h index 13dcd4e4815eebca44d289c8f4ff4520682e4079..7a1c9ece86773e42de504aea9175cecbf93ca816 100644 --- a/src/trivia/util.h +++ b/src/trivia/util.h @@ -171,6 +171,9 @@ void symbols_free(); char *abspath(const char *filename); +char * +int2str(int val); + #ifndef HAVE_MEMMEM /* Declare memmem(). */ void * diff --git a/src/tt_pthread.h b/src/tt_pthread.h index 93662323d3a43a1e7c9dfdbeae5dafd024b50644..c0a6683651ac1d429e3b491cd172a95322651459 100644 --- a/src/tt_pthread.h +++ b/src/tt_pthread.h @@ -76,7 +76,7 @@ if (e != 0 && e != EBUSY) \ say_error("%s error %d at %s:%d", __func__, e, __FILE__, __LINE__);\ assert(e == 0 || e == EBUSY); \ - e \ + e; \ }) #define tt_pthread_mutex_unlock(mutex) \ @@ -145,7 +145,7 @@ if (ETIMEDOUT != e) \ say_error("%s error %d", __func__, e);\ assert(e == 0 || e == ETIMEDOUT); \ - e \ + e; \ }) #define tt_pthread_once(control, function) \ diff --git a/src/util.cc b/src/util.cc index 5401a5bb4abac26f5e9804636c9f1327d8484aad..339e5a10b5d92293193c2416082409afccf21b38 100644 --- a/src/util.cc +++ b/src/util.cc @@ -348,6 +348,13 @@ abspath(const char *filename) return abspath; } +char * +int2str(int val) +{ + static char __thread buf[22]; + snprintf(buf, sizeof(buf), "%d", val); + return buf; +} #ifdef HAVE_BFD static struct symbol *symbols; diff --git a/test/big/hash.result b/test/big/hash.result index ba6fa5c6a75d79bdfff7e59d42586834eab6d218..bc5e1f5878706c16cc31db984656d4eaa111c15f 100644 --- a/test/big/hash.result +++ b/test/big/hash.result @@ -60,34 +60,34 @@ hash:replace{'invalid key', 'value1 v1.0', 'value2 v1.0'} -- 32-bit hash select fields test ------------------------------------------------------------------------------- -- select by valid keys -hash.index['primary']:select{0} +hash.index['primary']:get{0} --- - [0, 'value1 v1.0', 'value2 v1.0'] ... -hash.index['primary']:select{1} +hash.index['primary']:get{1} --- - [1, 'value1 v1.32', 'value2 1.72'] ... -hash.index['primary']:select{2} +hash.index['primary']:get{2} --- - [2, 'value1 v1.43', 'value2 1.92'] ... -hash.index['primary']:select{3} +hash.index['primary']:get{3} --- - [3, 'value1 v1.31', 'value2 1.12'] ... -hash.index['primary']:select{4} +hash.index['primary']:get{4} --- ... -hash.index['primary']:select{5} +hash.index['primary']:get{5} --- ... -- select by invalid keys -hash.index['primary']:select{'invalid key'} +hash.index['primary']:get{'invalid key'} --- - error: 'Supplied key type of part 0 does not match index part type: expected NUM' ... -hash.index['primary']:select{1, 2} +hash.index['primary']:get{1, 2} --- - error: Invalid key part count (expected [0..1], got 2) ... @@ -210,57 +210,57 @@ hash:replace{'invalid key', 'value1 v1.0', 'value2 v1.0'} -- 64-bit hash select fields test ------------------------------------------------------------------------------- -- select by valid keys -hash.index['primary']:select{0ULL} +hash.index['primary']:get{0ULL} --- - [0, 'value1 v1.0', 'value2 v1.0'] ... -hash.index['primary']:select{1ULL} +hash.index['primary']:get{1ULL} --- - [1, 'value1 v1.32', 'value2 1.72'] ... -hash.index['primary']:select{2ULL} +hash.index['primary']:get{2ULL} --- - [2, 'value1 v1.43', 'value2 1.92'] ... -hash.index['primary']:select{3ULL} +hash.index['primary']:get{3ULL} --- - [3, 'value1 v1.31', 'value2 1.12'] ... -hash.index['primary']:select{4ULL} +hash.index['primary']:get{4ULL} --- ... -hash.index['primary']:select{5ULL} +hash.index['primary']:get{5ULL} --- ... -- select by valid NUM keys -hash.index['primary']:select{0} +hash.index['primary']:get{0} --- - [0, 'value1 v1.0', 'value2 v1.0'] ... -hash.index['primary']:select{1} +hash.index['primary']:get{1} --- - [1, 'value1 v1.32', 'value2 1.72'] ... -hash.index['primary']:select{2} +hash.index['primary']:get{2} --- - [2, 'value1 v1.43', 'value2 1.92'] ... -hash.index['primary']:select{3} +hash.index['primary']:get{3} --- - [3, 'value1 v1.31', 'value2 1.12'] ... -hash.index['primary']:select{4} +hash.index['primary']:get{4} --- ... -hash.index['primary']:select{5} +hash.index['primary']:get{5} --- ... -- select by invalid keys -hash.index['primary']:select{'invalid key'} +hash.index['primary']:get{'invalid key'} --- - error: 'Supplied key type of part 0 does not match index part type: expected NUM' ... -hash.index['primary']:select{'00000001', '00000002'} +hash.index['primary']:get{'00000001', '00000002'} --- - error: Invalid key part count (expected [0..1], got 2) ... @@ -390,30 +390,30 @@ hash:replace{'key 2', 'value1 v1.43', 'value2 1.92'} -- String hash select fields test ------------------------------------------------------------------------------- -- select by valid keys -hash.index['primary']:select{'key 0'} +hash.index['primary']:get{'key 0'} --- - ['key 0', 'value1 v1.0', 'value2 v1.0'] ... -hash.index['primary']:select{'key 1'} +hash.index['primary']:get{'key 1'} --- - ['key 1', 'value1 v1.32', 'value2 1.72'] ... -hash.index['primary']:select{'key 2'} +hash.index['primary']:get{'key 2'} --- - ['key 2', 'value1 v1.43', 'value2 1.92'] ... -hash.index['primary']:select{'key 3'} +hash.index['primary']:get{'key 3'} --- - ['key 3', 'value1 v1.31', 'value2 1.12'] ... -hash.index['primary']:select{'key 4'} +hash.index['primary']:get{'key 4'} --- ... -hash.index['primary']:select{'key 5'} +hash.index['primary']:get{'key 5'} --- ... -- select by invalid keys -hash.index['primary']:select{'key 1', 'key 2'} +hash.index['primary']:get{'key 1', 'key 2'} --- - error: Invalid key part count (expected [0..1], got 2) ... @@ -486,31 +486,31 @@ hash:replace{1, 1, 1, 1} --- - [1, 1, 1, 1] ... -hash.index['primary']:select{10} +hash.index['primary']:get{10} --- ... -hash.index['field1']:select{10} +hash.index['field1']:get{10} --- ... -hash.index['field2']:select{10} +hash.index['field2']:get{10} --- ... -hash.index['field3']:select{10} +hash.index['field3']:get{10} --- ... -hash.index['primary']:select{1} +hash.index['primary']:get{1} --- - [1, 1, 1, 1] ... -hash.index['field1']:select{1} +hash.index['field1']:get{1} --- - [1, 1, 1, 1] ... -hash.index['field2']:select{1} +hash.index['field2']:get{1} --- - [1, 1, 1, 1] ... -hash.index['field3']:select{1} +hash.index['field3']:get{1} --- - [1, 1, 1, 1] ... @@ -523,16 +523,16 @@ hash:delete{10} --- - [10, 10, 10, 10] ... -hash.index['primary']:select{10} +hash.index['primary']:get{10} --- ... -hash.index['field1']:select{10} +hash.index['field1']:get{10} --- ... -hash.index['field2']:select{10} +hash.index['field2']:get{10} --- ... -hash.index['field3']:select{10} +hash.index['field3']:get{10} --- ... -- TupleFound (primary key) @@ -540,19 +540,19 @@ hash:insert{1, 10, 10, 10} --- - error: Duplicate key exists in unique index 0 ... -hash.index['primary']:select{10} +hash.index['primary']:get{10} --- ... -hash.index['field1']:select{10} +hash.index['field1']:get{10} --- ... -hash.index['field2']:select{10} +hash.index['field2']:get{10} --- ... -hash.index['field3']:select{10} +hash.index['field3']:get{10} --- ... -hash.index['primary']:select{1} +hash.index['primary']:get{1} --- - [1, 1, 1, 1] ... @@ -561,19 +561,19 @@ hash:replace{10, 10, 10, 10} --- - [10, 10, 10, 10] ... -hash.index['primary']:select{10} +hash.index['primary']:get{10} --- - [10, 10, 10, 10] ... -hash.index['field1']:select{10} +hash.index['field1']:get{10} --- - [10, 10, 10, 10] ... -hash.index['field2']:select{10} +hash.index['field2']:get{10} --- - [10, 10, 10, 10] ... -hash.index['field3']:select{10} +hash.index['field3']:get{10} --- - [10, 10, 10, 10] ... @@ -582,45 +582,45 @@ hash:insert{10, 0, 10, 10} --- - error: Duplicate key exists in unique index 0 ... -hash.index['primary']:select{10} +hash.index['primary']:get{10} --- - [10, 10, 10, 10] ... -hash.index['field1']:select{10} +hash.index['field1']:get{10} --- - [10, 10, 10, 10] ... -hash.index['field2']:select{10} +hash.index['field2']:get{10} --- - [10, 10, 10, 10] ... -hash.index['field3']:select{10} +hash.index['field3']:get{10} --- - [10, 10, 10, 10] ... -hash.index['field1']:select{0} +hash.index['field1']:get{0} --- - [0, 0, 0, 0] ... -- TupleFound (key --1) -- hash:replace_if_exists(2, 0, 10, 10) -hash.index['primary']:select{10} +hash.index['primary']:get{10} --- - [10, 10, 10, 10] ... -hash.index['field1']:select{10} +hash.index['field1']:get{10} --- - [10, 10, 10, 10] ... -hash.index['field2']:select{10} +hash.index['field2']:get{10} --- - [10, 10, 10, 10] ... -hash.index['field3']:select{10} +hash.index['field3']:get{10} --- - [10, 10, 10, 10] ... -hash.index['field1']:select{0} +hash.index['field1']:get{0} --- - [0, 0, 0, 0] ... @@ -629,45 +629,45 @@ hash:insert{10, 10, 10, 0} --- - error: Duplicate key exists in unique index 0 ... -hash.index['primary']:select{10} +hash.index['primary']:get{10} --- - [10, 10, 10, 10] ... -hash.index['field1']:select{10} +hash.index['field1']:get{10} --- - [10, 10, 10, 10] ... -hash.index['field2']:select{10} +hash.index['field2']:get{10} --- - [10, 10, 10, 10] ... -hash.index['field3']:select{10} +hash.index['field3']:get{10} --- - [10, 10, 10, 10] ... -hash.index['field3']:select{0} +hash.index['field3']:get{0} --- - [0, 0, 0, 0] ... -- TupleFound (key --3) -- hash:replace_if_exists(2, 10, 10, 0) -hash.index['primary']:select{10} +hash.index['primary']:get{10} --- - [10, 10, 10, 10] ... -hash.index['field1']:select{10} +hash.index['field1']:get{10} --- - [10, 10, 10, 10] ... -hash.index['field2']:select{10} +hash.index['field2']:get{10} --- - [10, 10, 10, 10] ... -hash.index['field3']:select{10} +hash.index['field3']:get{10} --- - [10, 10, 10, 10] ... -hash.index['field3']:select{0} +hash.index['field3']:get{0} --- - [0, 0, 0, 0] ... diff --git a/test/big/hash.test.lua b/test/big/hash.test.lua index 3764a71815a2db3e452e14ab67e8d9a1687869e9..bdef15f6e53cd23b0a965ce7f7f6fcbff3d3297d 100644 --- a/test/big/hash.test.lua +++ b/test/big/hash.test.lua @@ -35,16 +35,16 @@ hash:replace{'invalid key', 'value1 v1.0', 'value2 v1.0'} ------------------------------------------------------------------------------- -- select by valid keys -hash.index['primary']:select{0} -hash.index['primary']:select{1} -hash.index['primary']:select{2} -hash.index['primary']:select{3} -hash.index['primary']:select{4} -hash.index['primary']:select{5} +hash.index['primary']:get{0} +hash.index['primary']:get{1} +hash.index['primary']:get{2} +hash.index['primary']:get{3} +hash.index['primary']:get{4} +hash.index['primary']:get{5} -- select by invalid keys -hash.index['primary']:select{'invalid key'} -hash.index['primary']:select{1, 2} +hash.index['primary']:get{'invalid key'} +hash.index['primary']:get{1, 2} ------------------------------------------------------------------------------- -- 32-bit hash delete fields test @@ -104,24 +104,24 @@ hash:replace{'invalid key', 'value1 v1.0', 'value2 v1.0'} ------------------------------------------------------------------------------- -- select by valid keys -hash.index['primary']:select{0ULL} -hash.index['primary']:select{1ULL} -hash.index['primary']:select{2ULL} -hash.index['primary']:select{3ULL} -hash.index['primary']:select{4ULL} -hash.index['primary']:select{5ULL} +hash.index['primary']:get{0ULL} +hash.index['primary']:get{1ULL} +hash.index['primary']:get{2ULL} +hash.index['primary']:get{3ULL} +hash.index['primary']:get{4ULL} +hash.index['primary']:get{5ULL} -- select by valid NUM keys -hash.index['primary']:select{0} -hash.index['primary']:select{1} -hash.index['primary']:select{2} -hash.index['primary']:select{3} -hash.index['primary']:select{4} -hash.index['primary']:select{5} +hash.index['primary']:get{0} +hash.index['primary']:get{1} +hash.index['primary']:get{2} +hash.index['primary']:get{3} +hash.index['primary']:get{4} +hash.index['primary']:get{5} -- select by invalid keys -hash.index['primary']:select{'invalid key'} -hash.index['primary']:select{'00000001', '00000002'} +hash.index['primary']:get{'invalid key'} +hash.index['primary']:get{'00000001', '00000002'} ------------------------------------------------------------------------------- -- 64-bit hash delete fields test @@ -182,15 +182,15 @@ hash:replace{'key 2', 'value1 v1.43', 'value2 1.92'} ------------------------------------------------------------------------------- -- select by valid keys -hash.index['primary']:select{'key 0'} -hash.index['primary']:select{'key 1'} -hash.index['primary']:select{'key 2'} -hash.index['primary']:select{'key 3'} -hash.index['primary']:select{'key 4'} -hash.index['primary']:select{'key 5'} +hash.index['primary']:get{'key 0'} +hash.index['primary']:get{'key 1'} +hash.index['primary']:get{'key 2'} +hash.index['primary']:get{'key 3'} +hash.index['primary']:get{'key 4'} +hash.index['primary']:get{'key 5'} -- select by invalid keys -hash.index['primary']:select{'key 1', 'key 2'} +hash.index['primary']:get{'key 1', 'key 2'} ------------------------------------------------------------------------------- -- String hash delete fields test @@ -223,68 +223,68 @@ hash:insert{2, 2, 2, 2} -- OK hash:replace{1, 1, 1, 1} -hash.index['primary']:select{10} -hash.index['field1']:select{10} -hash.index['field2']:select{10} -hash.index['field3']:select{10} -hash.index['primary']:select{1} -hash.index['field1']:select{1} -hash.index['field2']:select{1} -hash.index['field3']:select{1} +hash.index['primary']:get{10} +hash.index['field1']:get{10} +hash.index['field2']:get{10} +hash.index['field3']:get{10} +hash.index['primary']:get{1} +hash.index['field1']:get{1} +hash.index['field2']:get{1} +hash.index['field3']:get{1} -- OK hash:insert{10, 10, 10, 10} hash:delete{10} -hash.index['primary']:select{10} -hash.index['field1']:select{10} -hash.index['field2']:select{10} -hash.index['field3']:select{10} +hash.index['primary']:get{10} +hash.index['field1']:get{10} +hash.index['field2']:get{10} +hash.index['field3']:get{10} -- TupleFound (primary key) hash:insert{1, 10, 10, 10} -hash.index['primary']:select{10} -hash.index['field1']:select{10} -hash.index['field2']:select{10} -hash.index['field3']:select{10} -hash.index['primary']:select{1} +hash.index['primary']:get{10} +hash.index['field1']:get{10} +hash.index['field2']:get{10} +hash.index['field3']:get{10} +hash.index['primary']:get{1} -- TupleNotFound (primary key) hash:replace{10, 10, 10, 10} -hash.index['primary']:select{10} -hash.index['field1']:select{10} -hash.index['field2']:select{10} -hash.index['field3']:select{10} +hash.index['primary']:get{10} +hash.index['field1']:get{10} +hash.index['field2']:get{10} +hash.index['field3']:get{10} -- TupleFound (key --1) hash:insert{10, 0, 10, 10} -hash.index['primary']:select{10} -hash.index['field1']:select{10} -hash.index['field2']:select{10} -hash.index['field3']:select{10} -hash.index['field1']:select{0} +hash.index['primary']:get{10} +hash.index['field1']:get{10} +hash.index['field2']:get{10} +hash.index['field3']:get{10} +hash.index['field1']:get{0} -- TupleFound (key --1) -- hash:replace_if_exists(2, 0, 10, 10) -hash.index['primary']:select{10} -hash.index['field1']:select{10} -hash.index['field2']:select{10} -hash.index['field3']:select{10} -hash.index['field1']:select{0} +hash.index['primary']:get{10} +hash.index['field1']:get{10} +hash.index['field2']:get{10} +hash.index['field3']:get{10} +hash.index['field1']:get{0} -- TupleFound (key --3) hash:insert{10, 10, 10, 0} -hash.index['primary']:select{10} -hash.index['field1']:select{10} -hash.index['field2']:select{10} -hash.index['field3']:select{10} -hash.index['field3']:select{0} +hash.index['primary']:get{10} +hash.index['field1']:get{10} +hash.index['field2']:get{10} +hash.index['field3']:get{10} +hash.index['field3']:get{0} -- TupleFound (key --3) -- hash:replace_if_exists(2, 10, 10, 0) -hash.index['primary']:select{10} -hash.index['field1']:select{10} -hash.index['field2']:select{10} -hash.index['field3']:select{10} -hash.index['field3']:select{0} +hash.index['primary']:get{10} +hash.index['field1']:get{10} +hash.index['field2']:get{10} +hash.index['field3']:get{10} +hash.index['field3']:get{0} hash:drop() diff --git a/test/big/hash_multipart.result b/test/big/hash_multipart.result index 4eedee33101b6ac93efb7f3916f7ace1302c3a3f..33d6d02dd92f7fefdee52c549c2110533069d9af 100644 --- a/test/big/hash_multipart.result +++ b/test/big/hash_multipart.result @@ -52,7 +52,8 @@ hash:insert{1, 'bar', 1, '', 5} --# setopt delimiter ';' function box.select_all() local result = {} - for v in hash:iterator() do + local tuple, v + for tuple, v in hash:pairs() do table.insert(result, v) end return result @@ -72,40 +73,40 @@ box.sort(box.select_all()) - [1, 'foo', 1, '', 2] ... -- primary index select -hash.index['primary']:select{1, 'foo', 0} +hash.index['primary']:get{1, 'foo', 0} --- - [1, 'foo', 0, '', 2] ... -hash.index['primary']:select{1, 'bar', 0} +hash.index['primary']:get{1, 'bar', 0} --- - [1, 'bar', 0, '', 4] ... -- primary index select with missing part -hash.index['primary']:select{1, 'foo'} +hash.index['primary']:get{1, 'foo'} --- - error: Invalid key part count in an exact match (expected 3, got 2) ... -- primary index select with extra part -hash.index['primary']:select{1, 'foo', 0, 0} +hash.index['primary']:get{1, 'foo', 0, 0} --- - error: Invalid key part count (expected [0..3], got 4) ... -- primary index select with wrong type -hash.index['primary']:select{1, 'foo', 'baz'} +hash.index['primary']:get{1, 'foo', 'baz'} --- - error: 'Supplied key type of part 2 does not match index part type: expected NUM' ... -- secondary index select -hash.index['unique']:select{1, 4} +hash.index['unique']:get{1, 4} --- - [1, 'bar', 1, '', 4] ... -- secondary index select with no such key -hash.index['unique']:select{1, 5} +hash.index['unique']:get{1, 5} --- ... -- secondary index select with missing part -hash.index['unique']:select{1} +hash.index['unique']:get{1} --- - error: Invalid key part count in an exact match (expected 2, got 1) ... diff --git a/test/big/hash_multipart.test.lua b/test/big/hash_multipart.test.lua index 23b32bb600fe841c160941799d132efeb04e1958..847326d7f2846608ad68066a4f74240a84153da7 100644 --- a/test/big/hash_multipart.test.lua +++ b/test/big/hash_multipart.test.lua @@ -22,7 +22,8 @@ hash:insert{1, 'bar', 1, '', 5} --# setopt delimiter ';' function box.select_all() local result = {} - for v in hash:iterator() do + local tuple, v + for tuple, v in hash:pairs() do table.insert(result, v) end return result @@ -31,21 +32,21 @@ end; box.sort(box.select_all()) -- primary index select -hash.index['primary']:select{1, 'foo', 0} -hash.index['primary']:select{1, 'bar', 0} +hash.index['primary']:get{1, 'foo', 0} +hash.index['primary']:get{1, 'bar', 0} -- primary index select with missing part -hash.index['primary']:select{1, 'foo'} +hash.index['primary']:get{1, 'foo'} -- primary index select with extra part -hash.index['primary']:select{1, 'foo', 0, 0} +hash.index['primary']:get{1, 'foo', 0, 0} -- primary index select with wrong type -hash.index['primary']:select{1, 'foo', 'baz'} +hash.index['primary']:get{1, 'foo', 'baz'} -- secondary index select -hash.index['unique']:select{1, 4} +hash.index['unique']:get{1, 4} -- secondary index select with no such key -hash.index['unique']:select{1, 5} +hash.index['unique']:get{1, 5} -- secondary index select with missing part -hash.index['unique']:select{1} +hash.index['unique']:get{1} -- secondary index select with wrong type hash.index['unique']:select{1, 'baz'} diff --git a/test/big/iterator.result b/test/big/iterator.result index 86c43987a1cb5053eb04f4392db7bb612ad3b717..d65125ffb86ed64444ed18960cec701f67231eec 100644 --- a/test/big/iterator.result +++ b/test/big/iterator.result @@ -884,15 +884,14 @@ iterate('tweedledum', 'i5', 1, 3, box.index.EQ, 'sid_005', 'tid_995', 'a') ------------------------------------------------------------------------------- -- Iterator: various ------------------------------------------------------------------------------- -space.index['primary']:iterator({}, {iterator = -666 }) +space.index['primary']:pairs({}, {iterator = -666 }) --- - error: Tree index does not support requested iterator type ... -- Test cases for #123: box.index.count does not check arguments properly -space.index['primary']:iterator(function() end, { iterator = box.index.EQ }) +space.index['primary']:pairs(function() end, { iterator = box.index.EQ }) --- -- error: '[string "-- msgpackffi.lua (internal file)..."]:261: can not encode Lua - type: ''function''' +- error: 'builtin/msgpackffi.lua:261: can not encode Lua type: ''function''' ... space:drop() --- diff --git a/test/big/iterator.test.lua b/test/big/iterator.test.lua index e0ca38eaa65d483f2507feb7252946b0b862251b..a6f6b6ecf31dfebb7e785a8037d9acbead6a35b7 100644 --- a/test/big/iterator.test.lua +++ b/test/big/iterator.test.lua @@ -158,7 +158,7 @@ iterate('tweedledum', 'i5', 1, 3, box.index.EQ, 'sid_005', 'tid_995', 'a') -- Iterator: various ------------------------------------------------------------------------------- -space.index['primary']:iterator({}, {iterator = -666 }) +space.index['primary']:pairs({}, {iterator = -666 }) -- Test cases for #123: box.index.count does not check arguments properly -space.index['primary']:iterator(function() end, { iterator = box.index.EQ }) +space.index['primary']:pairs(function() end, { iterator = box.index.EQ }) space:drop() diff --git a/test/big/lua.result b/test/big/lua.result index 0f93ba12f824e4c5bde36147293ef205cf9e55c0..c84bab07982137e1eeb78874d1692c702301ebaf 100644 --- a/test/big/lua.result +++ b/test/big/lua.result @@ -23,14 +23,14 @@ space.index['minmax']:max() --- - ['hello', 'old', 'world'] ... -space.index['minmax']:select{'new', 'world'} +space.index['minmax']:get{'new', 'world'} --- - ['brave', 'new', 'world'] ... -- A test case for Bug #904208 -- "assert failed, when key cardinality is greater than index cardinality" -- https://bugs.launchpad.net/tarantool/+bug/904208 -space.index['minmax']:select{'new', 'world', 'order'} +space.index['minmax']:get{'new', 'world', 'order'} --- - error: Invalid key part count (expected [0..2], got 3) ... @@ -45,7 +45,7 @@ space:insert{'item 1', 'alabama', 'song'} --- - ['item 1', 'alabama', 'song'] ... -space.index['minmax']:select{'alabama'} +space.index['minmax']:get{'alabama'} --- - ['item 1', 'alabama', 'song'] ... @@ -61,14 +61,20 @@ space:insert{'item 4', 'georgia', 'on my mind'} --- - ['item 4', 'georgia', 'on my mind'] ... -iter, state = space.index['minmax']:iterator('california', { iterator = box.index.GE }) +iter, param, state = space.index['minmax']:pairs('california', { iterator = box.index.GE }) --- ... -iter() +state, v = iter(param, state) +--- +... +v --- - ['item 2', 'california', 'dreaming '] ... -iter() +state, v = iter(param, state) +--- +... +v --- - ['item 3', 'california', 'uber alles'] ... @@ -129,12 +135,12 @@ space:insert{00000001ULL, 'of', 'might', 'and', 'magic'} --- - [1, 'of', 'might', 'and', 'magic'] ... -space.index['minmax']:eselect('of', { limit = 2, iterator = 'GE' }) +space.index['minmax']:select('of', { limit = 2, iterator = 'GE' }) --- - - [1, 'of', 'might', 'and', 'magic'] - [0, 'of', 'puppets'] ... -space.index['minmax']:eselect('of', { limit = 2, iterator = 'LE' }) +space.index['minmax']:select('of', { limit = 2, iterator = 'LE' }) --- - - [0, 'of', 'puppets'] - [1, 'of', 'might', 'and', 'magic'] @@ -149,7 +155,7 @@ space:insert{2^51, 'hello', 'world'} --- - [2251799813685248, 'hello', 'world'] ... -space.index['primary']:select{2^51} +space.index['primary']:get{2^51} --- - [2251799813685248, 'hello', 'world'] ... @@ -169,7 +175,7 @@ space:insert{tonumber64('18446744073709551615'), 'magic'} --- - [18446744073709551615, 'magic'] ... -tuple = space.index['primary']:select{tonumber64('18446744073709551615')} +tuple = space.index['primary']:get{tonumber64('18446744073709551615')} --- ... num = tuple[0] @@ -202,10 +208,10 @@ space:insert{125ULL, 'magic'} --- - [125, 'magic'] ... -tuple = space.index['primary']:select{125} +tuple = space.index['primary']:get{125} --- ... -tuple2 = space.index['primary']:select{125LL} +tuple2 = space.index['primary']:get{125LL} --- ... num = tuple[0] @@ -315,7 +321,7 @@ space:insert{9, 0} --- - [9, 0] ... -space.index['range']:eselect({}, { limit = 10, iterator = 'GE' }) +space.index['range']:select({}, { limit = 10, iterator = 'GE' }) --- - - [0, 0] - [1, 0] @@ -328,7 +334,7 @@ space.index['range']:eselect({}, { limit = 10, iterator = 'GE' }) - [8, 0] - [9, 0] ... -space.index['range']:eselect({}, { limit = 10, iterator = 'LE' }) +space.index['range']:select({}, { limit = 10, iterator = 'LE' }) --- - - [9, 0] - [8, 0] @@ -341,7 +347,7 @@ space.index['range']:eselect({}, { limit = 10, iterator = 'LE' }) - [1, 0] - [0, 0] ... -space.index['range']:eselect({}, { limit = 4, iterator = 'LE' }) +space.index['range']:select({}, { limit = 4, iterator = 'LE' }) --- - - [9, 0] - [8, 0] @@ -386,7 +392,7 @@ index = space.index['i1'] t = {} --- ... -for v in index:iterator('sid_1', { iterator = 'GE' }) do table.insert(t, v) end +for state, v in index:pairs('sid_1', { iterator = 'GE' }) do table.insert(t, v) end --- ... t @@ -401,7 +407,7 @@ t t = {} --- ... -for v in index:iterator('sid_2', { iterator = 'LE' }) do table.insert(t, v) end +for state, v in index:pairs('sid_2', { iterator = 'LE' }) do table.insert(t, v) end --- ... t @@ -416,7 +422,7 @@ t t = {} --- ... -for v in index:iterator('sid_1', { iterator = 'EQ' }) do table.insert(t, v) end +for state, v in index:pairs('sid_1', { iterator = 'EQ' }) do table.insert(t, v) end --- ... t @@ -428,7 +434,7 @@ t t = {} --- ... -for v in index:iterator('sid_1', { iterator = 'REQ' }) do table.insert(t, v) end +for state, v in index:pairs('sid_1', { iterator = 'REQ' }) do table.insert(t, v) end --- ... t @@ -440,7 +446,7 @@ t t = {} --- ... -for v in index:iterator('sid_2', { iterator = 'EQ' }) do table.insert(t, v) end +for state, v in index:pairs('sid_2', { iterator = 'EQ' }) do table.insert(t, v) end --- ... t @@ -452,7 +458,7 @@ t t = {} --- ... -for v in index:iterator('sid_2', { iterator = 'REQ' }) do table.insert(t, v) end +for state, v in index:pairs('sid_2', { iterator = 'REQ' }) do table.insert(t, v) end --- ... t @@ -464,9 +470,9 @@ t t = {} --- ... -index:iterator('sid_t', { iterator = 'wrong_iterator_type' }) +index:pairs('sid_t', { iterator = 'wrong_iterator_type' }) --- -- error: '[string "-- schema.lua (internal file)..."]:248: Wrong iterator type: wrong_iterator_type' +- error: '[string "-- schema.lua (internal file)..."]:324: Wrong iterator type: wrong_iterator_type' ... index = nil --- @@ -568,8 +574,7 @@ space.index['i1']:count() -- Test cases for #123: box.index.count does not check arguments properly space.index['i1']:count(function() end) --- -- error: '[string "-- msgpackffi.lua (internal file)..."]:261: can not encode Lua - type: ''function''' +- error: 'builtin/msgpackffi.lua:261: can not encode Lua type: ''function''' ... space:drop() --- @@ -868,9 +873,9 @@ space:insert{20, 30, 40, 50} ... space.index['primary']:select{} --- -- [1, 2, 3, 4] -- [10, 20, 30, 40] -- [20, 30, 40, 50] +- - [1, 2, 3, 4] + - [10, 20, 30, 40] + - [20, 30, 40, 50] ... -- Truncate must not hang space:truncate() @@ -879,6 +884,7 @@ space:truncate() -- Empty result space.index['primary']:select{} --- +- [] ... space:drop() --- diff --git a/test/big/lua.test.lua b/test/big/lua.test.lua index 541cf022b7e3b17783e38d01a65e1b9a6c2c78c7..a6d64be50fe3b25f808c714bb3f44177443eeca5 100644 --- a/test/big/lua.test.lua +++ b/test/big/lua.test.lua @@ -6,13 +6,13 @@ space:insert{'brave', 'new', 'world'} space:insert{'hello', 'old', 'world'} space.index['minmax']:min() space.index['minmax']:max() -space.index['minmax']:select{'new', 'world'} +space.index['minmax']:get{'new', 'world'} -- A test case for Bug #904208 -- "assert failed, when key cardinality is greater than index cardinality" -- https://bugs.launchpad.net/tarantool/+bug/904208 -space.index['minmax']:select{'new', 'world', 'order'} +space.index['minmax']:get{'new', 'world', 'order'} space:delete{'brave'} -- A test case for Bug #902091 @@ -20,13 +20,15 @@ space:delete{'brave'} -- https://bugs.launchpad.net/tarantool/+bug/902091 space:insert{'item 1', 'alabama', 'song'} -space.index['minmax']:select{'alabama'} +space.index['minmax']:get{'alabama'} space:insert{'item 2', 'california', 'dreaming '} space:insert{'item 3', 'california', 'uber alles'} space:insert{'item 4', 'georgia', 'on my mind'} -iter, state = space.index['minmax']:iterator('california', { iterator = box.index.GE }) -iter() -iter() +iter, param, state = space.index['minmax']:pairs('california', { iterator = box.index.GE }) +state, v = iter(param, state) +v +state, v = iter(param, state) +v space:delete{'item 1'} space:delete{'item 2'} space:delete{'item 3'} @@ -50,8 +52,8 @@ space:create_index('minmax', { type = 'tree', parts = {1, 'str', 2, 'str'}, uniq space:insert{1234567, 'new', 'world'} space:insert{0, 'of', 'puppets'} space:insert{00000001ULL, 'of', 'might', 'and', 'magic'} -space.index['minmax']:eselect('of', { limit = 2, iterator = 'GE' }) -space.index['minmax']:eselect('of', { limit = 2, iterator = 'LE' }) +space.index['minmax']:select('of', { limit = 2, iterator = 'GE' }) +space.index['minmax']:select('of', { limit = 2, iterator = 'LE' }) space:truncate() -- @@ -59,7 +61,7 @@ space:truncate() -- space:insert{2^51, 'hello', 'world'} -space.index['primary']:select{2^51} +space.index['primary']:get{2^51} space:drop() -- @@ -69,7 +71,7 @@ space = box.schema.create_space('tweedledum') space:create_index('primary', { type = 'tree', parts = {0, 'num'}, unique = true }) space:insert{tonumber64('18446744073709551615'), 'magic'} -tuple = space.index['primary']:select{tonumber64('18446744073709551615')} +tuple = space.index['primary']:get{tonumber64('18446744073709551615')} num = tuple[0] num type(num) == 'cdata' @@ -78,8 +80,8 @@ num = tuple[0] num == tonumber64('18446744073709551615') space:delete{18446744073709551615ULL} space:insert{125ULL, 'magic'} -tuple = space.index['primary']:select{125} -tuple2 = space.index['primary']:select{125LL} +tuple = space.index['primary']:get{125} +tuple2 = space.index['primary']:get{125LL} num = tuple[0] num2 = tuple2[0] num, num2 @@ -119,9 +121,9 @@ space:insert{6, 0} space:insert{7, 0} space:insert{8, 0} space:insert{9, 0} -space.index['range']:eselect({}, { limit = 10, iterator = 'GE' }) -space.index['range']:eselect({}, { limit = 10, iterator = 'LE' }) -space.index['range']:eselect({}, { limit = 4, iterator = 'LE' }) +space.index['range']:select({}, { limit = 10, iterator = 'GE' }) +space.index['range']:select({}, { limit = 10, iterator = 'LE' }) +space.index['range']:select({}, { limit = 4, iterator = 'LE' }) space:drop() -- @@ -146,27 +148,27 @@ end; index = space.index['i1'] t = {} -for v in index:iterator('sid_1', { iterator = 'GE' }) do table.insert(t, v) end +for state, v in index:pairs('sid_1', { iterator = 'GE' }) do table.insert(t, v) end t t = {} -for v in index:iterator('sid_2', { iterator = 'LE' }) do table.insert(t, v) end +for state, v in index:pairs('sid_2', { iterator = 'LE' }) do table.insert(t, v) end t t = {} -for v in index:iterator('sid_1', { iterator = 'EQ' }) do table.insert(t, v) end +for state, v in index:pairs('sid_1', { iterator = 'EQ' }) do table.insert(t, v) end t t = {} -for v in index:iterator('sid_1', { iterator = 'REQ' }) do table.insert(t, v) end +for state, v in index:pairs('sid_1', { iterator = 'REQ' }) do table.insert(t, v) end t t = {} -for v in index:iterator('sid_2', { iterator = 'EQ' }) do table.insert(t, v) end +for state, v in index:pairs('sid_2', { iterator = 'EQ' }) do table.insert(t, v) end t t = {} -for v in index:iterator('sid_2', { iterator = 'REQ' }) do table.insert(t, v) end +for state, v in index:pairs('sid_2', { iterator = 'REQ' }) do table.insert(t, v) end t t = {} -index:iterator('sid_t', { iterator = 'wrong_iterator_type' }) +index:pairs('sid_t', { iterator = 'wrong_iterator_type' }) index = nil space:drop() diff --git a/test/big/lua/push.lua b/test/big/lua/push.lua index c7770d8c57693d04eaba790d4a430f7d2a36f71c..423946433eb56c6e8600193f91ff254f9298233f 100644 --- a/test/big/lua/push.lua +++ b/test/big/lua/push.lua @@ -1,7 +1,7 @@ function push_collection(space, size, cid, ...) local append = { ... } - local tuple = space:select{cid} + local tuple = space:get{cid} if tuple == nil then return space:insert{cid, unpack(append)} end diff --git a/test/big/lua/utils.lua b/test/big/lua/utils.lua index 063bf5fa89cad8e2ae3ae88f90f56326e19d73b1..67adc0e6d9ea8239daaa23931e2b19e5c562ce1b 100644 --- a/test/big/lua/utils.lua +++ b/test/big/lua/utils.lua @@ -22,7 +22,8 @@ function iterate(space_no, index_no, f1, f2, iterator, ...) return f end end - for v in box.space[space_no].index[index_no]:iterator({...}, { iterator = iterator }) do + local state, v + for state, v in box.space[space_no].index[index_no]:pairs({...}, { iterator = iterator }) do local pk = get_field(v, 0); local tk = '$'; for f = f1, f2-1, 1 do tk = (tk..(get_field(v, f))..'$'); end; diff --git a/test/big/sql.result b/test/big/sql.result index 8e358ad5d91cc7a78d5e6ec0ff70102f6d73d66d..e9d05c6ba6d406c875d4e87546f61027f0b0fae4 100644 --- a/test/big/sql.result +++ b/test/big/sql.result @@ -1,3 +1,9 @@ +box.schema.user.create('test', { password = 'test' }) +--- +... +box.schema.user.grant('test', 'execute,read,write', 'universe') +--- +... s = box.schema.create_space('tweedledum', { id = 0 }) --- ... @@ -89,11 +95,11 @@ select * from t0 where k1='Britney' --- - ['Spears', 'Britney'] ... -s.index[0]:eselect('Spears', { limit = 100, iterator = 'GE' }) +s.index[0]:select('Spears', { limit = 100, iterator = 'GE' }) --- - - ['Spears', 'Britney'] ... -s.index[1]:eselect('Britney', { limit = 100, iterator = 'GE' }) +s.index[1]:select('Britney', { limit = 100, iterator = 'GE' }) --- - - ['Spears', 'Britney'] ... @@ -128,9 +134,9 @@ insert into t0 values ('key3', 'part1', 'part2_b') ... s.index[1]:select{} --- -- ['key1', 'part1', 'part2'] -- ['key2', 'part1', 'part2_a'] -- ['key3', 'part1', 'part2_b'] +- - ['key1', 'part1', 'part2'] + - ['key2', 'part1', 'part2_a'] + - ['key3', 'part1', 'part2_b'] ... select * from t0 where k0='key1' --- @@ -150,18 +156,18 @@ select * from t0 where k1='part1' - ['key2', 'part1', 'part2_a'] - ['key3', 'part1', 'part2_b'] ... -s.index[1]:eselect('part1', { limit = 100, iterator = 'GE' }) +s.index[1]:select('part1', { limit = 100, iterator = 'GE' }) --- - - ['key1', 'part1', 'part2'] - ['key2', 'part1', 'part2_a'] - ['key3', 'part1', 'part2_b'] ... -s.index[0]:eselect('key2', { limit = 100, iterator = 'GE' }) +s.index[0]:select('key2', { limit = 100, iterator = 'GE' }) --- - - ['key2', 'part1', 'part2_a'] - ['key3', 'part1', 'part2_b'] ... -s.index[1]:eselect({ 'part1', 'part2_a' }, { limit = 100, iterator = 'GE' }) +s.index[1]:select({ 'part1', 'part2_a' }, { limit = 100, iterator = 'GE' }) --- - - ['key2', 'part1', 'part2_a'] - ['key3', 'part1', 'part2_b'] @@ -228,7 +234,7 @@ insert into t0 values (41234567, 'part1_a', 'part2_a') l = {} --- ... -for v in s:iterator() do table.insert(l, v) end +for state, v in s:pairs() do table.insert(l, v) end --- ... return l @@ -265,10 +271,10 @@ select * from t0 where k1='part1_a' select * from t0 where k1='part_none' --- ... -box.space[0].index[1]:select{'part1', 'part2'} +box.space[0].index[1]:select({'part1', 'part2'}) --- -- [1234567, 'part1', 'part2'] -- [11234567, 'part1', 'part2'] +- - [1234567, 'part1', 'part2'] + - [11234567, 'part1', 'part2'] ... select * from t0 where k1='part1' --- @@ -301,6 +307,7 @@ delete from t0 where k0=41234567 ... s:select{} --- +- [] ... s:truncate() --- @@ -551,9 +558,9 @@ insert into t0 values(3, 'Creature ') ... s.index[1]:select{} --- -- [1, 'Aardvark '] -- [2, 'Bilimbi'] -- [3, 'Creature '] +- - [1, 'Aardvark '] + - [2, 'Bilimbi'] + - [3, 'Creature '] ... s.index[0]:min() --- @@ -583,6 +590,9 @@ delete from t0 where k0=3 --- - [3, 'Creature '] ... +box.schema.user.drop('test') +--- +... s:drop() --- ... diff --git a/test/big/sql.test.py b/test/big/sql.test.py index b3d2f65da748cfd95eb1c23e395fa24900a59e24..f59c80214c0c8bde8a0e485772a431aa14ac96bd 100644 --- a/test/big/sql.test.py +++ b/test/big/sql.test.py @@ -3,6 +3,8 @@ sql.sort = True # # Prepare spaces # +admin("box.schema.user.create('test', { password = 'test' })") +admin("box.schema.user.grant('test', 'execute,read,write', 'universe')") admin("s = box.schema.create_space('tweedledum', { id = 0 })") admin("s:create_index('primary', { type = 'tree', parts = { 0, 'str'} })") admin("s:create_index('secondary', { type = 'tree', unique = false, parts = {1, 'str'}})") @@ -12,7 +14,7 @@ print """# # "SELECT fails with a disjunct and small LIMIT" # https://bugs.launchpad.net/tarantool/+bug/729758 #""" - +sql.authenticate('test', 'test') sql("insert into t0 values ('Doe', 'Richard')") sql("insert into t0 values ('Roe', 'Richard')") sql("insert into t0 values ('Woe', 'Richard')") @@ -45,8 +47,8 @@ sql("select * from t0 where k0='Spears'") sql("select * from t0 where k1='Anything'") sql("select * from t0 where k1='Britney'") -admin("s.index[0]:eselect('Spears', { limit = 100, iterator = 'GE' })") -admin("s.index[1]:eselect('Britney', { limit = 100, iterator = 'GE' })") +admin("s.index[0]:select('Spears', { limit = 100, iterator = 'GE' })") +admin("s.index[1]:select('Britney', { limit = 100, iterator = 'GE' })") sql("delete from t0 where k0='Spears'") @@ -69,9 +71,9 @@ sql("select * from t0 where k0='key1'") sql("select * from t0 where k0='key2'") sql("select * from t0 where k0='key3'") sql("select * from t0 where k1='part1'") -admin("s.index[1]:eselect('part1', { limit = 100, iterator = 'GE' })") -admin("s.index[0]:eselect('key2', { limit = 100, iterator = 'GE' })") -admin("s.index[1]:eselect({ 'part1', 'part2_a' }, { limit = 100, iterator = 'GE' })") +admin("s.index[1]:select('part1', { limit = 100, iterator = 'GE' })") +admin("s.index[0]:select('key2', { limit = 100, iterator = 'GE' })") +admin("s.index[1]:select({ 'part1', 'part2_a' }, { limit = 100, iterator = 'GE' })") sql("select * from t0 where k0='key1'") sql("select * from t0 where k0='key2'") sql("select * from t0 where k0='key3'") @@ -90,7 +92,7 @@ sql("insert into t0 values (21234567, 'part1', 'part2_a')") sql("insert into t0 values (31234567, 'part1_a', 'part2')") sql("insert into t0 values (41234567, 'part1_a', 'part2_a')") admin("l = {}") -admin("for v in s:iterator() do table.insert(l, v) end") +admin("for state, v in s:pairs() do table.insert(l, v) end") admin("return l") sql("select * from t0 where k0=01234567") sql("select * from t0 where k0=11234567") @@ -98,7 +100,7 @@ sql("select * from t0 where k0=21234567") sql("select * from t0 where k1='part1'") sql("select * from t0 where k1='part1_a'") sql("select * from t0 where k1='part_none'") -admin("box.space[0].index[1]:select{'part1', 'part2'}") +admin("box.space[0].index[1]:select({'part1', 'part2'})") sql("select * from t0 where k1='part1'") sql("select * from t0 where k1='part2'") # cleanup @@ -203,6 +205,7 @@ admin("s.index[1]:max()") sql("delete from t0 where k0=1") sql("delete from t0 where k0=2") sql("delete from t0 where k0=3") +admin("box.schema.user.drop('test')") admin("s:drop()") sql.sort = False diff --git a/test/big/tarantool.cfg b/test/big/tarantool.cfg index 089d606f2a283d958c763339d26f8790e42759dd..0928ece87bc576df37df4d8792a909729a7d0816 100644 --- a/test/big/tarantool.cfg +++ b/test/big/tarantool.cfg @@ -4,8 +4,8 @@ pid_file = "box.pid" logger="cat - >> tarantool.log" -primary_port = 33013 -admin_port = 33015 +primary_port = 3301 +admin_port = 3313 rows_per_wal = 50 diff --git a/test/big/tree_pk.result b/test/big/tree_pk.result index 65296a7b60db9e39809a17f8284893262a924ca0..303b1e24c28693f9a31e6edefae6c9a5284376b2 100644 --- a/test/big/tree_pk.result +++ b/test/big/tree_pk.result @@ -28,15 +28,15 @@ s0:insert{3, 'tuple 3'} --- - [3, 'tuple 3'] ... -s0.index['primary']:select{1} +s0.index['primary']:get{1} --- - [1, 'tuple'] ... -s0.index['primary']:select{2} +s0.index['primary']:get{2} --- - [2, 'tuple 2'] ... -s0.index['primary']:select{3} +s0.index['primary']:get{3} --- - [3, 'tuple 3'] ... @@ -96,11 +96,11 @@ box.snapshot() --- - ok ... -s1.index['primary']:eselect('second', { limit = 100, iterator = 'GE' }) +s1.index['primary']:select('second', { limit = 100, iterator = 'GE' }) --- - - ['second', 'tuple 2'] ... -s1.index['primary']:eselect('identifier', { limit = 100, iterator = 'GE' }) +s1.index['primary']:select('identifier', { limit = 100, iterator = 'GE' }) --- - - ['identifier', 'tuple'] - ['second', 'tuple 2'] @@ -109,15 +109,15 @@ s1:insert{'third', 'tuple 3'} --- - ['third', 'tuple 3'] ... -s1.index['primary']:select{'identifier'} +s1.index['primary']:get{'identifier'} --- - ['identifier', 'tuple'] ... -s1.index['primary']:select{'second'} +s1.index['primary']:get{'second'} --- - ['second', 'tuple 2'] ... -s1.index['primary']:select{'third'} +s1.index['primary']:get{'third'} --- - ['third', 'tuple 3'] ... @@ -137,8 +137,8 @@ s1:delete{'third'} --# setopt delimiter ';' function crossjoin(space0, space1, limit) local result = {} - for v0 in space0:iterator() do - for v1 in space1:iterator() do + for state, v0 in space0:pairs() do + for state, v1 in space1:pairs() do if limit <= 0 then return result end @@ -201,14 +201,14 @@ s0:insert{200, 'select me!'} --- - [200, 'select me!'] ... -s0.index['primary']:select{200} +s0.index['primary']:get{200} --- - [200, 'select me!'] ... -s0.index['primary']:select{199} +s0.index['primary']:get{199} --- ... -s0.index['primary']:select{201} +s0.index['primary']:get{201} --- ... -- Test partially specified keys in TREE indexes @@ -248,7 +248,7 @@ s1:insert{'abcdc_'} --- - ['abcdc_'] ... -box.sort(s1.index['primary']:eselect('abcdb', { limit = 3, iterator = 'GE' })) +box.sort(s1.index['primary']:select('abcdb', { limit = 3, iterator = 'GE' })) --- - - ['abcdb'] - ['abcdb_'] @@ -306,33 +306,36 @@ s0:replace{1, 1, 1, 1} --- - [1, 1, 1, 1] ... -s0.index['primary']:select{10} +s0.index['primary']:get{10} --- ... s0.index['i1']:select{10} --- +- [] ... s0.index['i2']:select{10} --- +- [] ... s0.index['i3']:select{10} --- +- [] ... -s0.index['primary']:select{1} +s0.index['primary']:get{1} --- - [1, 1, 1, 1] ... s0.index['i1']:select{1} --- -- [1, 1, 1, 1] +- - [1, 1, 1, 1] ... s0.index['i2']:select{1} --- -- [1, 1, 1, 1] +- - [1, 1, 1, 1] ... s0.index['i3']:select{1} --- -- [1, 1, 1, 1] +- - [1, 1, 1, 1] ... -- OK s0:insert{10, 10, 10, 10} @@ -343,36 +346,42 @@ s0:delete{10} --- - [10, 10, 10, 10] ... -s0.index['primary']:select{10} +s0.index['primary']:get{10} --- ... s0.index['i1']:select{10} --- +- [] ... s0.index['i2']:select{10} --- +- [] ... s0.index['i3']:select{10} --- +- [] ... -- TupleFound (primary key) s0:insert{1, 10, 10, 10} --- - error: Duplicate key exists in unique index 0 ... -s0.index['primary']:select{10} +s0.index['primary']:get{10} --- ... s0.index['i1']:select{10} --- +- [] ... s0.index['i2']:select{10} --- +- [] ... s0.index['i3']:select{10} --- +- [] ... -s0.index['primary']:select{1} +s0.index['primary']:get{1} --- - [1, 1, 1, 1] ... @@ -381,121 +390,121 @@ s0:replace{10, 10, 10, 10} --- - [10, 10, 10, 10] ... -s0.index['primary']:select{10} +s0.index['primary']:get{10} --- - [10, 10, 10, 10] ... s0.index['i1']:select{10} --- -- [10, 10, 10, 10] +- - [10, 10, 10, 10] ... s0.index['i2']:select{10} --- -- [10, 10, 10, 10] +- - [10, 10, 10, 10] ... s0.index['i3']:select{10} --- -- [10, 10, 10, 10] +- - [10, 10, 10, 10] ... -- TupleFound (key #1) s0:insert{10, 0, 10, 10} --- - error: Duplicate key exists in unique index 0 ... -s0.index['primary']:select{10} +s0.index['primary']:get{10} --- - [10, 10, 10, 10] ... s0.index['i1']:select{10} --- -- [10, 10, 10, 10] +- - [10, 10, 10, 10] ... s0.index['i2']:select{10} --- -- [10, 10, 10, 10] +- - [10, 10, 10, 10] ... s0.index['i3']:select{10} --- -- [10, 10, 10, 10] +- - [10, 10, 10, 10] ... s0.index['i1']:select{0} --- -- [0, 0, 0, 0] +- - [0, 0, 0, 0] ... -- TupleFound (key #1) s0:replace{2, 0, 10, 10} --- - error: Duplicate key exists in unique index 1 ... -s0.index['primary']:select{10} +s0.index['primary']:get{10} --- - [10, 10, 10, 10] ... s0.index['i1']:select{10} --- -- [10, 10, 10, 10] +- - [10, 10, 10, 10] ... s0.index['i2']:select{10} --- -- [10, 10, 10, 10] +- - [10, 10, 10, 10] ... s0.index['i3']:select{10} --- -- [10, 10, 10, 10] +- - [10, 10, 10, 10] ... s0.index['i1']:select{0} --- -- [0, 0, 0, 0] +- - [0, 0, 0, 0] ... -- TupleFound (key #3) s0:insert{10, 10, 10, 0} --- - error: Duplicate key exists in unique index 0 ... -s0.index['primary']:select{10} +s0.index['primary']:get{10} --- - [10, 10, 10, 10] ... s0.index['i1']:select{10} --- -- [10, 10, 10, 10] +- - [10, 10, 10, 10] ... s0.index['i2']:select{10} --- -- [10, 10, 10, 10] +- - [10, 10, 10, 10] ... s0.index['i3']:select{10} --- -- [10, 10, 10, 10] +- - [10, 10, 10, 10] ... s0.index['i3']:select{0} --- -- [0, 0, 0, 0] +- - [0, 0, 0, 0] ... -- TupleFound (key #3) s0:replace{2, 10, 10, 0} --- - error: Duplicate key exists in unique index 1 ... -s0.index['primary']:select{10} +s0.index['primary']:get{10} --- - [10, 10, 10, 10] ... s0.index['i1']:select{10} --- -- [10, 10, 10, 10] +- - [10, 10, 10, 10] ... s0.index['i2']:select{10} --- -- [10, 10, 10, 10] +- - [10, 10, 10, 10] ... s0.index['i3']:select{10} --- -- [10, 10, 10, 10] +- - [10, 10, 10, 10] ... s0.index['i3']:select{0} --- -- [0, 0, 0, 0] +- - [0, 0, 0, 0] ... -- Non-Uniq test (key #2) s0:insert{4, 4, 0, 4} @@ -514,7 +523,7 @@ s0:replace{5, 5, 0, 5} --- - [5, 5, 0, 5] ... -box.sort({s0.index['i2']:select{0}}) +box.sort(s0.index['i2']:select(0)) --- - - [0, 0, 0, 0] - [4, 4, 0, 4] @@ -525,7 +534,7 @@ s0:delete{5} --- - [5, 5, 0, 5] ... -box.sort({s0.index['i2']:select{0}}) +box.sort(s0.index['i2']:select(0)) --- - - [0, 0, 0, 0] - [4, 4, 0, 4] @@ -581,7 +590,7 @@ s:insert{8} - [8] ... -- it seems that all elements will be deleted: -for t in ind:iterator() do s:delete{t[0]} end +for state, t in ind:pairs() do s:delete{t[0]} end --- ... -- but (oops) some elements are left in space: @@ -626,25 +635,37 @@ s:insert{1} --- - [1] ... -itr = ind:iterator() +gen, param, state = ind:pairs() +--- +... +state, val = gen(param, state) --- ... -itr() -- 1 +val -- 1 --- - [1] ... -itr() -- 2 +state, val = gen(param, state) +--- +... +val -- 2 --- - [2] ... for i = 5,100 do s:insert{i} end --- ... -itr() -- 3 +state, val = gen(param, state) +--- +... +val -- 3 --- - [3] ... -itr() -- now you don't +state, val = gen(param, state) +--- +... +val -- now you don't --- - null ... @@ -678,10 +699,13 @@ s:insert{3} --- - [3] ... -itr = ind:iterator() +gen, param, state = ind:pairs() --- ... -itr() -- 1 +state, val = gen(param, state) +--- +... +val -- 1 --- - [1] ... @@ -693,11 +717,17 @@ s:insert{0} --- - [0] ... -itr() -- 1 again +state, val = gen(param, state) +--- +... +val -- 1 again --- - [1] ... -itr() -- null +state, val = gen(param, state) +--- +... +val -- null --- - null ... diff --git a/test/big/tree_pk.test.lua b/test/big/tree_pk.test.lua index 9c600a6ef645c9b97b61c665b027b644f46dc937..04ffddee1ab79c0071c08834eb35adb8590e69a4 100644 --- a/test/big/tree_pk.test.lua +++ b/test/big/tree_pk.test.lua @@ -10,9 +10,9 @@ s0:insert{2, 'tuple 2'} box.snapshot() s0:insert{3, 'tuple 3'} -s0.index['primary']:select{1} -s0.index['primary']:select{2} -s0.index['primary']:select{3} +s0.index['primary']:get{1} +s0.index['primary']:get{2} +s0.index['primary']:get{3} -- Cleanup s0:delete{1} @@ -36,13 +36,13 @@ s1:insert{'identifier', 'tuple'} box.snapshot() s1:insert{'second', 'tuple 2'} box.snapshot() -s1.index['primary']:eselect('second', { limit = 100, iterator = 'GE' }) -s1.index['primary']:eselect('identifier', { limit = 100, iterator = 'GE' }) +s1.index['primary']:select('second', { limit = 100, iterator = 'GE' }) +s1.index['primary']:select('identifier', { limit = 100, iterator = 'GE' }) s1:insert{'third', 'tuple 3'} -s1.index['primary']:select{'identifier'} -s1.index['primary']:select{'second'} -s1.index['primary']:select{'third'} +s1.index['primary']:get{'identifier'} +s1.index['primary']:get{'second'} +s1.index['primary']:get{'third'} -- Cleanup s1:delete{'identifier'} @@ -52,8 +52,8 @@ s1:delete{'third'} --# setopt delimiter ';' function crossjoin(space0, space1, limit) local result = {} - for v0 in space0:iterator() do - for v1 in space1:iterator() do + for state, v0 in space0:pairs() do + for state, v1 in space1:pairs() do if limit <= 0 then return result end @@ -82,9 +82,9 @@ s2:truncate() -- Bug #922520 - select missing keys s0:insert{200, 'select me!'} -s0.index['primary']:select{200} -s0.index['primary']:select{199} -s0.index['primary']:select{201} +s0.index['primary']:get{200} +s0.index['primary']:get{199} +s0.index['primary']:get{201} -- Test partially specified keys in TREE indexes s1:insert{'abcd'} @@ -96,7 +96,7 @@ s1:insert{'abcdb__'} s1:insert{'abcdb___'} s1:insert{'abcdc'} s1:insert{'abcdc_'} -box.sort(s1.index['primary']:eselect('abcdb', { limit = 3, iterator = 'GE' })) +box.sort(s1.index['primary']:select('abcdb', { limit = 3, iterator = 'GE' })) s1:drop() s1 = nil s2:drop() @@ -119,11 +119,11 @@ s0:insert{2, 2, 2, 2} s0:replace{1, 1, 1, 1} s0:replace{1, 10, 10, 10} s0:replace{1, 1, 1, 1} -s0.index['primary']:select{10} +s0.index['primary']:get{10} s0.index['i1']:select{10} s0.index['i2']:select{10} s0.index['i3']:select{10} -s0.index['primary']:select{1} +s0.index['primary']:get{1} s0.index['i1']:select{1} s0.index['i2']:select{1} s0.index['i3']:select{1} @@ -131,7 +131,7 @@ s0.index['i3']:select{1} -- OK s0:insert{10, 10, 10, 10} s0:delete{10} -s0.index['primary']:select{10} +s0.index['primary']:get{10} s0.index['i1']:select{10} s0.index['i2']:select{10} s0.index['i3']:select{10} @@ -139,22 +139,22 @@ s0.index['i3']:select{10} -- TupleFound (primary key) s0:insert{1, 10, 10, 10} -s0.index['primary']:select{10} +s0.index['primary']:get{10} s0.index['i1']:select{10} s0.index['i2']:select{10} s0.index['i3']:select{10} -s0.index['primary']:select{1} +s0.index['primary']:get{1} -- TupleNotFound (primary key) s0:replace{10, 10, 10, 10} -s0.index['primary']:select{10} +s0.index['primary']:get{10} s0.index['i1']:select{10} s0.index['i2']:select{10} s0.index['i3']:select{10} -- TupleFound (key #1) s0:insert{10, 0, 10, 10} -s0.index['primary']:select{10} +s0.index['primary']:get{10} s0.index['i1']:select{10} s0.index['i2']:select{10} s0.index['i3']:select{10} @@ -162,7 +162,7 @@ s0.index['i1']:select{0} -- TupleFound (key #1) s0:replace{2, 0, 10, 10} -s0.index['primary']:select{10} +s0.index['primary']:get{10} s0.index['i1']:select{10} s0.index['i2']:select{10} s0.index['i3']:select{10} @@ -170,7 +170,7 @@ s0.index['i1']:select{0} -- TupleFound (key #3) s0:insert{10, 10, 10, 0} -s0.index['primary']:select{10} +s0.index['primary']:get{10} s0.index['i1']:select{10} s0.index['i2']:select{10} s0.index['i3']:select{10} @@ -178,7 +178,7 @@ s0.index['i3']:select{0} -- TupleFound (key #3) s0:replace{2, 10, 10, 0} -s0.index['primary']:select{10} +s0.index['primary']:get{10} s0.index['i1']:select{10} s0.index['i2']:select{10} s0.index['i3']:select{10} @@ -189,9 +189,9 @@ s0:insert{4, 4, 0, 4} s0:insert{5, 5, 0, 5} s0:insert{6, 6, 0, 6} s0:replace{5, 5, 0, 5} -box.sort({s0.index['i2']:select{0}}) +box.sort(s0.index['i2']:select(0)) s0:delete{5} -box.sort({s0.index['i2']:select{0}}) +box.sort(s0.index['i2']:select(0)) s0:drop() s0 = nil @@ -212,7 +212,7 @@ s:insert{7} s:insert{8} -- it seems that all elements will be deleted: -for t in ind:iterator() do s:delete{t[0]} end +for state, t in ind:pairs() do s:delete{t[0]} end -- but (oops) some elements are left in space: iterate('test', 'primary', 0, 1) @@ -232,12 +232,16 @@ s:insert{2} s:insert{4} -- now you see me s:insert{1} -itr = ind:iterator() -itr() -- 1 -itr() -- 2 +gen, param, state = ind:pairs() +state, val = gen(param, state) +val -- 1 +state, val = gen(param, state) +val -- 2 for i = 5,100 do s:insert{i} end -itr() -- 3 -itr() -- now you don't +state, val = gen(param, state) +val -- 3 +state, val = gen(param, state) +val -- now you don't -- cleanup s:drop() @@ -254,12 +258,15 @@ s:insert{2} s:insert{1} s:insert{3} -itr = ind:iterator() -itr() -- 1 +gen, param, state = ind:pairs() +state, val = gen(param, state) +val -- 1 s:delete{2} s:insert{0} -itr() -- 1 again -itr() -- null +state, val = gen(param, state) +val -- 1 again +state, val = gen(param, state) +val -- null -- cleanup s:drop() diff --git a/test/big/tree_pk_multipart.result b/test/big/tree_pk_multipart.result index edc9eb44c4b0fae80a123b4dfd61bb26800e98f8..b54c2cffc5f645d405903f3e8ca1ea07797d3c5f 100644 --- a/test/big/tree_pk_multipart.result +++ b/test/big/tree_pk_multipart.result @@ -100,155 +100,155 @@ space:insert{'Vincent', 'The Wolf!', 2, 'If I`m curt with you it`s because time -- Select test -- -- Select by one entry -space.index['primary']:select{'Vincent', 'Jules', 0} +space.index['primary']:get{'Vincent', 'Jules', 0} --- - ['Vincent', 'Jules', 0, 'Do you know what they call a - a - a Quarter Pounder with cheese in Paris?'] ... -space.index['primary']:select{'Jules', 'Vincent', 0} +space.index['primary']:get{'Jules', 'Vincent', 0} --- - ['Jules', 'Vincent', 0, 'They don`t call it a Quarter Pounder with cheese?'] ... -space.index['primary']:select{'Vincent', 'Jules', 1} +space.index['primary']:get{'Vincent', 'Jules', 1} --- - ['Vincent', 'Jules', 1, 'No man, they got the metric system. They wouldn`t know what the f--k a Quarter Pounder is.'] ... -space.index['primary']:select{'Jules', 'Vincent', 1} +space.index['primary']:get{'Jules', 'Vincent', 1} --- - ['Jules', 'Vincent', 1, 'Then what do they call it?'] ... -space.index['primary']:select{'Vincent', 'Jules', 2} +space.index['primary']:get{'Vincent', 'Jules', 2} --- - ['Vincent', 'Jules', 2, 'They call it a `Royale` with cheese.'] ... -space.index['primary']:select{'Jules', 'Vincent', 2} +space.index['primary']:get{'Jules', 'Vincent', 2} --- - ['Jules', 'Vincent', 2, 'A `Royale` with cheese!'] ... -space.index['primary']:select{'Vincent', 'Jules', 3} +space.index['primary']:get{'Vincent', 'Jules', 3} --- - ['Vincent', 'Jules', 3, 'That`s right.'] ... -space.index['primary']:select{'Jules', 'Vincent', 3} +space.index['primary']:get{'Jules', 'Vincent', 3} --- - ['Jules', 'Vincent', 3, 'What do they call a Big Mac?'] ... -space.index['primary']:select{'Vincent', 'Jules', 4} +space.index['primary']:get{'Vincent', 'Jules', 4} --- - ['Vincent', 'Jules', 4, 'A Big Mac`s a Big Mac, but they call it `Le Big Mac.`'] ... -space.index['primary']:select{'Jules', 'Vincent', 4} +space.index['primary']:get{'Jules', 'Vincent', 4} --- - ['Jules', 'Vincent', 4, '`Le Big Mac!`'] ... -space.index['primary']:select{'Vincent', 'Jules', 5} +space.index['primary']:get{'Vincent', 'Jules', 5} --- - ['Vincent', 'Jules', 5, 'Ha, ha, ha.'] ... -space.index['primary']:select{'Jules', 'Vincent', 5} +space.index['primary']:get{'Jules', 'Vincent', 5} --- - ['Jules', 'Vincent', 5, 'What do they call a `Whopper`?'] ... -space.index['primary']:select{'Vincent', 'Jules', 6} +space.index['primary']:get{'Vincent', 'Jules', 6} --- - ['Vincent', 'Jules', 6, 'I dunno, I didn`t go into Burger King.'] ... -space.index['primary']:select{'The Wolf!', 'Vincent', 0} +space.index['primary']:get{'The Wolf!', 'Vincent', 0} --- - ['The Wolf!', 'Vincent', 0, 'Jimmie, lead the way. Boys, get to work.'] ... -space.index['primary']:select{'Vincent', 'The Wolf!', 0} +space.index['primary']:get{'Vincent', 'The Wolf!', 0} --- - ['Vincent', 'The Wolf!', 0, 'A please would be nice.'] ... -space.index['primary']:select{'The Wolf!', 'Vincent', 1} +space.index['primary']:get{'The Wolf!', 'Vincent', 1} --- - ['The Wolf!', 'Vincent', 1, 'Come again?'] ... -space.index['primary']:select{'Vincent', 'The Wolf!', 1} +space.index['primary']:get{'Vincent', 'The Wolf!', 1} --- - ['Vincent', 'The Wolf!', 1, 'I said a please would be nice.'] ... -space.index['primary']:select{'The Wolf!', 'Vincent', 2} +space.index['primary']:get{'The Wolf!', 'Vincent', 2} --- - ['The Wolf!', 'Vincent', 2, 'Get it straight buster - I`m not here to say please, I`m here to tell you what to do and if self-preservation is an instinct you possess you`d better fucking do it and do it quick. I`m here to help - if my help`s not appreciated then lotsa luck, gentlemen.'] ... -space.index['primary']:select{'The Wolf!', 'Vincent', 3} +space.index['primary']:get{'The Wolf!', 'Vincent', 3} --- - ['The Wolf!', 'Vincent', 3, 'I don`t mean any disrespect, I just don`t like people barking orders at me.'] ... -space.index['primary']:select{'Vincent', 'The Wolf!', 2} +space.index['primary']:get{'Vincent', 'The Wolf!', 2} --- - ['Vincent', 'The Wolf!', 2, 'If I`m curt with you it`s because time is a factor. I think fast, I talk fast and I need you guys to act fast if you wanna get out of this. So, pretty please... with sugar on top. Clean the fucking car.'] ... -- Select all messages from Vincent to Jules -space.index['primary']:select{'Vincent', 'Jules'} ---- -- ['Vincent', 'Jules', 0, 'Do you know what they call a - a - a Quarter Pounder with - cheese in Paris?'] -- ['Vincent', 'Jules', 1, 'No man, they got the metric system. They wouldn`t know - what the f--k a Quarter Pounder is.'] -- ['Vincent', 'Jules', 2, 'They call it a `Royale` with cheese.'] -- ['Vincent', 'Jules', 3, 'That`s right.'] -- ['Vincent', 'Jules', 4, 'A Big Mac`s a Big Mac, but they call it `Le Big Mac.`'] -- ['Vincent', 'Jules', 5, 'Ha, ha, ha.'] -- ['Vincent', 'Jules', 6, 'I dunno, I didn`t go into Burger King.'] +space.index['primary']:select({'Vincent', 'Jules'}) +--- +- - ['Vincent', 'Jules', 0, 'Do you know what they call a - a - a Quarter Pounder + with cheese in Paris?'] + - ['Vincent', 'Jules', 1, 'No man, they got the metric system. They wouldn`t know + what the f--k a Quarter Pounder is.'] + - ['Vincent', 'Jules', 2, 'They call it a `Royale` with cheese.'] + - ['Vincent', 'Jules', 3, 'That`s right.'] + - ['Vincent', 'Jules', 4, 'A Big Mac`s a Big Mac, but they call it `Le Big Mac.`'] + - ['Vincent', 'Jules', 5, 'Ha, ha, ha.'] + - ['Vincent', 'Jules', 6, 'I dunno, I didn`t go into Burger King.'] ... -- Select all messages from Jules to Vincent -space.index['primary']:select{'Jules', 'Vincent'} +space.index['primary']:select({'Jules', 'Vincent'}) --- -- ['Jules', 'Vincent', 0, 'They don`t call it a Quarter Pounder with cheese?'] -- ['Jules', 'Vincent', 1, 'Then what do they call it?'] -- ['Jules', 'Vincent', 2, 'A `Royale` with cheese!'] -- ['Jules', 'Vincent', 3, 'What do they call a Big Mac?'] -- ['Jules', 'Vincent', 4, '`Le Big Mac!`'] -- ['Jules', 'Vincent', 5, 'What do they call a `Whopper`?'] +- - ['Jules', 'Vincent', 0, 'They don`t call it a Quarter Pounder with cheese?'] + - ['Jules', 'Vincent', 1, 'Then what do they call it?'] + - ['Jules', 'Vincent', 2, 'A `Royale` with cheese!'] + - ['Jules', 'Vincent', 3, 'What do they call a Big Mac?'] + - ['Jules', 'Vincent', 4, '`Le Big Mac!`'] + - ['Jules', 'Vincent', 5, 'What do they call a `Whopper`?'] ... -- Select all messages from Vincent to The Wolf -space.index['primary']:select{'Vincent', 'The Wolf!'} +space.index['primary']:select({'Vincent', 'The Wolf!'}) --- -- ['Vincent', 'The Wolf!', 0, 'A please would be nice.'] -- ['Vincent', 'The Wolf!', 1, 'I said a please would be nice.'] -- ['Vincent', 'The Wolf!', 2, 'If I`m curt with you it`s because time is a factor. - I think fast, I talk fast and I need you guys to act fast if you wanna get out - of this. So, pretty please... with sugar on top. Clean the fucking car.'] +- - ['Vincent', 'The Wolf!', 0, 'A please would be nice.'] + - ['Vincent', 'The Wolf!', 1, 'I said a please would be nice.'] + - ['Vincent', 'The Wolf!', 2, 'If I`m curt with you it`s because time is a factor. + I think fast, I talk fast and I need you guys to act fast if you wanna get out + of this. So, pretty please... with sugar on top. Clean the fucking car.'] ... -- Select all messages from The Wolf to Vincent -space.index['primary']:select{'The Wolf!', 'Vincent'} +space.index['primary']:select({'The Wolf!', 'Vincent'}) --- -- ['The Wolf!', 'Vincent', 0, 'Jimmie, lead the way. Boys, get to work.'] -- ['The Wolf!', 'Vincent', 1, 'Come again?'] -- ['The Wolf!', 'Vincent', 2, 'Get it straight buster - I`m not here to say please, - I`m here to tell you what to do and if self-preservation is an instinct you possess - you`d better fucking do it and do it quick. I`m here to help - if my help`s not - appreciated then lotsa luck, gentlemen.'] -- ['The Wolf!', 'Vincent', 3, 'I don`t mean any disrespect, I just don`t like people - barking orders at me.'] +- - ['The Wolf!', 'Vincent', 0, 'Jimmie, lead the way. Boys, get to work.'] + - ['The Wolf!', 'Vincent', 1, 'Come again?'] + - ['The Wolf!', 'Vincent', 2, 'Get it straight buster - I`m not here to say please, + I`m here to tell you what to do and if self-preservation is an instinct you + possess you`d better fucking do it and do it quick. I`m here to help - if my + help`s not appreciated then lotsa luck, gentlemen.'] + - ['The Wolf!', 'Vincent', 3, 'I don`t mean any disrespect, I just don`t like people + barking orders at me.'] ... -- Select all Vincent messages -space.index['primary']:select{'Vincent'} ---- -- ['Vincent', 'Jules', 0, 'Do you know what they call a - a - a Quarter Pounder with - cheese in Paris?'] -- ['Vincent', 'Jules', 1, 'No man, they got the metric system. They wouldn`t know - what the f--k a Quarter Pounder is.'] -- ['Vincent', 'Jules', 2, 'They call it a `Royale` with cheese.'] -- ['Vincent', 'Jules', 3, 'That`s right.'] -- ['Vincent', 'Jules', 4, 'A Big Mac`s a Big Mac, but they call it `Le Big Mac.`'] -- ['Vincent', 'Jules', 5, 'Ha, ha, ha.'] -- ['Vincent', 'Jules', 6, 'I dunno, I didn`t go into Burger King.'] -- ['Vincent', 'The Wolf!', 0, 'A please would be nice.'] -- ['Vincent', 'The Wolf!', 1, 'I said a please would be nice.'] -- ['Vincent', 'The Wolf!', 2, 'If I`m curt with you it`s because time is a factor. - I think fast, I talk fast and I need you guys to act fast if you wanna get out - of this. So, pretty please... with sugar on top. Clean the fucking car.'] +space.index['primary']:select({'Vincent'}) +--- +- - ['Vincent', 'Jules', 0, 'Do you know what they call a - a - a Quarter Pounder + with cheese in Paris?'] + - ['Vincent', 'Jules', 1, 'No man, they got the metric system. They wouldn`t know + what the f--k a Quarter Pounder is.'] + - ['Vincent', 'Jules', 2, 'They call it a `Royale` with cheese.'] + - ['Vincent', 'Jules', 3, 'That`s right.'] + - ['Vincent', 'Jules', 4, 'A Big Mac`s a Big Mac, but they call it `Le Big Mac.`'] + - ['Vincent', 'Jules', 5, 'Ha, ha, ha.'] + - ['Vincent', 'Jules', 6, 'I dunno, I didn`t go into Burger King.'] + - ['Vincent', 'The Wolf!', 0, 'A please would be nice.'] + - ['Vincent', 'The Wolf!', 1, 'I said a please would be nice.'] + - ['Vincent', 'The Wolf!', 2, 'If I`m curt with you it`s because time is a factor. + I think fast, I talk fast and I need you guys to act fast if you wanna get out + of this. So, pretty please... with sugar on top. Clean the fucking car.'] ... -- -- Delete test @@ -276,21 +276,21 @@ space:update({'Updated', 'The Wolf!', 1}, {{ '=', 0, 'Vincent'}, { '#', 4, 1 }}) - ['Vincent', 'The Wolf!', 1, 'I said a please would be nice.'] ... -- Checking Vincent's last messages -space.index['primary']:select{'Vincent', 'The Wolf!'} +space.index['primary']:select({'Vincent', 'The Wolf!'}) --- -- ['Vincent', 'The Wolf!', 1, 'I said a please would be nice.'] -- ['Vincent', 'The Wolf!', 2, 'If I`m curt with you it`s because time is a factor. - I think fast, I talk fast and I need you guys to act fast if you wanna get out - of this. So, pretty please... with sugar on top. Clean the fucking car.'] +- - ['Vincent', 'The Wolf!', 1, 'I said a please would be nice.'] + - ['Vincent', 'The Wolf!', 2, 'If I`m curt with you it`s because time is a factor. + I think fast, I talk fast and I need you guys to act fast if you wanna get out + of this. So, pretty please... with sugar on top. Clean the fucking car.'] ... -- Checking The Wolf's last messages -space.index['primary']:select{'The Wolf!', 'Vincent'} +space.index['primary']:select({'The Wolf!', 'Vincent'}) --- -- ['The Wolf!', 'Vincent', 1, 'Come again?'] -- ['The Wolf!', 'Vincent', 2, 'Get it straight buster - I`m not here to say please, - I`m here to tell you what to do and if self-preservation is an instinct you possess - you`d better fucking do it and do it quick. I`m here to help - if my help`s not - appreciated then lotsa luck, gentlemen.'] +- - ['The Wolf!', 'Vincent', 1, 'Come again?'] + - ['The Wolf!', 'Vincent', 2, 'Get it straight buster - I`m not here to say please, + I`m here to tell you what to do and if self-preservation is an instinct you + possess you`d better fucking do it and do it quick. I`m here to help - if my + help`s not appreciated then lotsa luck, gentlemen.'] ... -- try to delete nonexistent message space:delete{'Vincent', 'The Wolf!', 3} @@ -318,21 +318,21 @@ space:update({'Vincent', 'The Wolf!', 1}, {{'=', 3, '<ooops>'}}) - ['Vincent', 'The Wolf!', 1, '<ooops>'] ... -- Checking Vincent's last messages -space.index['primary']:select{'Vincent', 'The Wolf!'} +space.index['primary']:select({'Vincent', 'The Wolf!'}) --- -- ['Vincent', 'The Wolf!', 1, '<ooops>'] -- ['Vincent', 'The Wolf!', 2, 'If I`m curt with you it`s because time is a factor. - I think fast, I talk fast and I need you guys to act fast if you wanna get out - of this. So, pretty please... with sugar on top. Clean the fucking car.'] +- - ['Vincent', 'The Wolf!', 1, '<ooops>'] + - ['Vincent', 'The Wolf!', 2, 'If I`m curt with you it`s because time is a factor. + I think fast, I talk fast and I need you guys to act fast if you wanna get out + of this. So, pretty please... with sugar on top. Clean the fucking car.'] ... -- Checking The Wolf's last messages -space.index['primary']:select{'The Wolf!', 'Vincent'} +space.index['primary']:select({'The Wolf!', 'Vincent'}) --- -- ['The Wolf!', 'Vincent', 1, '<ooops>'] -- ['The Wolf!', 'Vincent', 2, 'Get it straight buster - I`m not here to say please, - I`m here to tell you what to do and if self-preservation is an instinct you possess - you`d better fucking do it and do it quick. I`m here to help - if my help`s not - appreciated then lotsa luck, gentlemen.'] +- - ['The Wolf!', 'Vincent', 1, '<ooops>'] + - ['The Wolf!', 'Vincent', 2, 'Get it straight buster - I`m not here to say please, + I`m here to tell you what to do and if self-preservation is an instinct you + possess you`d better fucking do it and do it quick. I`m here to help - if my + help`s not appreciated then lotsa luck, gentlemen.'] ... -- try to update a nonexistent message space:update({'Vincent', 'The Wolf!', 3}, {{'=', 3, '<ooops>'}}) @@ -394,12 +394,12 @@ space:insert{'c', 'c', 'c'} t = {} --- ... -iterator = space.index['second']:iterator(nil, { iterator = box.index.GE }) +gen, param, state = space.index['second']:pairs(nil, { iterator = box.index.GE }) --- ... --# setopt delimiter ';' for i = 1, 2 do - v = iterator() + state, v = gen(param, state) table.insert(t, v) end; --- @@ -425,7 +425,7 @@ v --- - ['b', 'b', 'b'] ... -v = iterator() +param, v = gen(param, state) --- ... v @@ -445,7 +445,7 @@ t = {} ... --# setopt delimiter ';' for i = 1, 3 do - v = iterator() + param, v = gen(param, state) table.insert(t, v) end; --- diff --git a/test/big/tree_pk_multipart.test.lua b/test/big/tree_pk_multipart.test.lua index ce1f270f1287324f23f8980b6781b6c68c523f0c..c84891411125555fa1bb3a9cf7841016961a15ca 100644 --- a/test/big/tree_pk_multipart.test.lua +++ b/test/big/tree_pk_multipart.test.lua @@ -32,42 +32,42 @@ space:insert{'Vincent', 'The Wolf!', 2, 'If I`m curt with you it`s because time -- -- Select by one entry -space.index['primary']:select{'Vincent', 'Jules', 0} -space.index['primary']:select{'Jules', 'Vincent', 0} -space.index['primary']:select{'Vincent', 'Jules', 1} -space.index['primary']:select{'Jules', 'Vincent', 1} -space.index['primary']:select{'Vincent', 'Jules', 2} -space.index['primary']:select{'Jules', 'Vincent', 2} -space.index['primary']:select{'Vincent', 'Jules', 3} -space.index['primary']:select{'Jules', 'Vincent', 3} -space.index['primary']:select{'Vincent', 'Jules', 4} -space.index['primary']:select{'Jules', 'Vincent', 4} -space.index['primary']:select{'Vincent', 'Jules', 5} -space.index['primary']:select{'Jules', 'Vincent', 5} -space.index['primary']:select{'Vincent', 'Jules', 6} - -space.index['primary']:select{'The Wolf!', 'Vincent', 0} -space.index['primary']:select{'Vincent', 'The Wolf!', 0} -space.index['primary']:select{'The Wolf!', 'Vincent', 1} -space.index['primary']:select{'Vincent', 'The Wolf!', 1} -space.index['primary']:select{'The Wolf!', 'Vincent', 2} -space.index['primary']:select{'The Wolf!', 'Vincent', 3} -space.index['primary']:select{'Vincent', 'The Wolf!', 2} +space.index['primary']:get{'Vincent', 'Jules', 0} +space.index['primary']:get{'Jules', 'Vincent', 0} +space.index['primary']:get{'Vincent', 'Jules', 1} +space.index['primary']:get{'Jules', 'Vincent', 1} +space.index['primary']:get{'Vincent', 'Jules', 2} +space.index['primary']:get{'Jules', 'Vincent', 2} +space.index['primary']:get{'Vincent', 'Jules', 3} +space.index['primary']:get{'Jules', 'Vincent', 3} +space.index['primary']:get{'Vincent', 'Jules', 4} +space.index['primary']:get{'Jules', 'Vincent', 4} +space.index['primary']:get{'Vincent', 'Jules', 5} +space.index['primary']:get{'Jules', 'Vincent', 5} +space.index['primary']:get{'Vincent', 'Jules', 6} + +space.index['primary']:get{'The Wolf!', 'Vincent', 0} +space.index['primary']:get{'Vincent', 'The Wolf!', 0} +space.index['primary']:get{'The Wolf!', 'Vincent', 1} +space.index['primary']:get{'Vincent', 'The Wolf!', 1} +space.index['primary']:get{'The Wolf!', 'Vincent', 2} +space.index['primary']:get{'The Wolf!', 'Vincent', 3} +space.index['primary']:get{'Vincent', 'The Wolf!', 2} -- Select all messages from Vincent to Jules -space.index['primary']:select{'Vincent', 'Jules'} +space.index['primary']:select({'Vincent', 'Jules'}) -- Select all messages from Jules to Vincent -space.index['primary']:select{'Jules', 'Vincent'} +space.index['primary']:select({'Jules', 'Vincent'}) -- Select all messages from Vincent to The Wolf -space.index['primary']:select{'Vincent', 'The Wolf!'} +space.index['primary']:select({'Vincent', 'The Wolf!'}) -- Select all messages from The Wolf to Vincent -space.index['primary']:select{'The Wolf!', 'Vincent'} +space.index['primary']:select({'The Wolf!', 'Vincent'}) -- Select all Vincent messages -space.index['primary']:select{'Vincent'} +space.index['primary']:select({'Vincent'}) -- -- Delete test @@ -81,9 +81,9 @@ 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 }}) -- Checking Vincent's last messages -space.index['primary']:select{'Vincent', 'The Wolf!'} +space.index['primary']:select({'Vincent', 'The Wolf!'}) -- Checking The Wolf's last messages -space.index['primary']:select{'The Wolf!', 'Vincent'} +space.index['primary']:select({'The Wolf!', 'Vincent'}) -- try to delete nonexistent message space:delete{'Vincent', 'The Wolf!', 3} @@ -99,9 +99,9 @@ space:update({'The Wolf!', 'Vincent', 1}, {{'=', 3, '<ooops>'}}) space:update({'Vincent', 'The Wolf!', 1}, {{'=', 3, '<ooops>'}}) -- Checking Vincent's last messages -space.index['primary']:select{'Vincent', 'The Wolf!'} +space.index['primary']:select({'Vincent', 'The Wolf!'}) -- Checking The Wolf's last messages -space.index['primary']:select{'The Wolf!', 'Vincent'} +space.index['primary']:select({'The Wolf!', 'Vincent'}) -- try to update a nonexistent message space:update({'Vincent', 'The Wolf!', 3}, {{'=', 3, '<ooops>'}}) @@ -127,10 +127,10 @@ space:insert{'b', 'b', 'b'} space:insert{'c', 'c', 'c'} t = {} -iterator = space.index['second']:iterator(nil, { iterator = box.index.GE }) +gen, param, state = space.index['second']:pairs(nil, { iterator = box.index.GE }) --# setopt delimiter ';' for i = 1, 2 do - v = iterator() + state, v = gen(param, state) table.insert(t, v) end; --# setopt delimiter '' @@ -141,7 +141,7 @@ v collectgarbage('collect') v -v = iterator() +param, v = gen(param, state) v collectgarbage('collect') v @@ -149,7 +149,7 @@ v t = {} --# setopt delimiter ';' for i = 1, 3 do - v = iterator() + param, v = gen(param, state) table.insert(t, v) end; --# setopt delimiter '' diff --git a/test/big/tree_variants.result b/test/big/tree_variants.result index 4f638d6f3f585eeb01280060c6b6925368beb977..95bfdf7e226eabf6f6beb0543ed1cfc1c10b0a28 100644 --- a/test/big/tree_variants.result +++ b/test/big/tree_variants.result @@ -62,43 +62,43 @@ space:insert{9, 9, 400, 'John', 'Smoker', 'Rolls', 'A Blunt', 'foo', 2009} --- - [9, 9, 400, 'John', 'Smoker', 'Rolls', 'A Blunt', 'foo', 2009] ... -space.index['primary']:select{1} +space.index['primary']:get{1} --- - [1, 1, 200, 'Joe', 'Sixpack', 'Drinks', 'Heineken', 'bar', 2001] ... space.index['i1']:select{2} --- -- [2, 2, 200, 'Joe', 'Sixpack', 'Drinks', 'Carlsberg', 'bar', 2002] +- - [2, 2, 200, 'Joe', 'Sixpack', 'Drinks', 'Carlsberg', 'bar', 2002] ... -{space.index[2]:select{300}} +space.index[2]:select({300}) --- - - [3, 3, 300, 'Joe', 'Sixpack', 'Drinks', 'Corona Extra', 'bar', 2003] - [4, 4, 300, 'Joe', 'Sixpack', 'Drinks', 'Stella Artois', 'bar', 2004] - [5, 5, 300, 'Joe', 'Sixpack', 'Drinks', 'Miller Genuine Draft', 'bar', 2005] ... -#{space.index['i3']:select{'Joe', 'Sixpack'}} +#space.index['i3']:select({'Joe', 'Sixpack'}) --- - 6 ... -#{space.index['i3']:select{'John'}} +#space.index['i3']:select('John') --- - 4 ... -#{space.index['i4']:select{'A Pipe'}} +#space.index['i4']:select('A Pipe') --- - 1 ... {space.index['i4']:select{'Miller Genuine Draft', 'Drinks'}} --- -- - [5, 5, 300, 'Joe', 'Sixpack', 'Drinks', 'Miller Genuine Draft', 'bar', 2005] +- - - [5, 5, 300, 'Joe', 'Sixpack', 'Drinks', 'Miller Genuine Draft', 'bar', 2005] ... space.index['i5']:select{2007} --- -- [7, 7, 400, 'John', 'Smoker', 'Hits', 'A Bong', 'foo', 2007] +- - [7, 7, 400, 'John', 'Smoker', 'Hits', 'A Bong', 'foo', 2007] ... space.index[6]:select{'Miller Genuine Draft', 'Drinks'} --- -- [5, 5, 300, 'Joe', 'Sixpack', 'Drinks', 'Miller Genuine Draft', 'bar', 2005] +- - [5, 5, 300, 'Joe', 'Sixpack', 'Drinks', 'Miller Genuine Draft', 'bar', 2005] ... space:delete{6} --- @@ -134,27 +134,27 @@ space:insert{9, 9ULL, 400ULL, 'John', 'Smoker', 'Rolls', 'A Blunt', 'foo', 2009} ... space.index['i1']:select{6ULL} --- -- [6, 6, 400, 'John', 'Smoker', 'Hits', 'A Pipe', 'foo', 2006] +- - [6, 6, 400, 'John', 'Smoker', 'Hits', 'A Pipe', 'foo', 2006] ... space.index['i1']:select{6} --- -- [6, 6, 400, 'John', 'Smoker', 'Hits', 'A Pipe', 'foo', 2006] +- - [6, 6, 400, 'John', 'Smoker', 'Hits', 'A Pipe', 'foo', 2006] ... -{space.index['i2']:select{400ULL}} +space.index['i2']:select(400ULL) --- - - [6, 6, 400, 'John', 'Smoker', 'Hits', 'A Pipe', 'foo', 2006] - [7, 7, 400, 'John', 'Smoker', 'Hits', 'A Bong', 'foo', 2007] - [8, 8, 400, 'John', 'Smoker', 'Rolls', 'A Joint', 'foo', 2008] - [9, 9, 400, 'John', 'Smoker', 'Rolls', 'A Blunt', 'foo', 2009] ... -{space.index['i2']:select{400}} +space.index['i2']:select(400) --- - - [6, 6, 400, 'John', 'Smoker', 'Hits', 'A Pipe', 'foo', 2006] - [7, 7, 400, 'John', 'Smoker', 'Hits', 'A Bong', 'foo', 2007] - [8, 8, 400, 'John', 'Smoker', 'Rolls', 'A Joint', 'foo', 2008] - [9, 9, 400, 'John', 'Smoker', 'Rolls', 'A Blunt', 'foo', 2009] ... -{space:select{}} +space:select{} --- - - [0, 0, 100, 'Joe', 'Sixpack', 'Drinks', 'Amstel', 'bar', 2000] - [1, 1, 200, 'Joe', 'Sixpack', 'Drinks', 'Heineken', 'bar', 2001] diff --git a/test/big/tree_variants.test.lua b/test/big/tree_variants.test.lua index 89e4ce730f107376e38691ab3367d42d341ed6e4..046480ed5527cc135b343b99e92778bb5b17577a 100644 --- a/test/big/tree_variants.test.lua +++ b/test/big/tree_variants.test.lua @@ -18,12 +18,12 @@ space:insert{7, 7, 400, 'John', 'Smoker', 'Hits', 'A Bong', 'foo', 2007} space:insert{8, 8, 400, 'John', 'Smoker', 'Rolls', 'A Joint', 'foo', 2008} space:insert{9, 9, 400, 'John', 'Smoker', 'Rolls', 'A Blunt', 'foo', 2009} -space.index['primary']:select{1} +space.index['primary']:get{1} space.index['i1']:select{2} -{space.index[2]:select{300}} -#{space.index['i3']:select{'Joe', 'Sixpack'}} -#{space.index['i3']:select{'John'}} -#{space.index['i4']:select{'A Pipe'}} +space.index[2]:select({300}) +#space.index['i3']:select({'Joe', 'Sixpack'}) +#space.index['i3']:select('John') +#space.index['i4']:select('A Pipe') {space.index['i4']:select{'Miller Genuine Draft', 'Drinks'}} space.index['i5']:select{2007} space.index[6]:select{'Miller Genuine Draft', 'Drinks'} @@ -40,10 +40,10 @@ space:insert{9, 9ULL, 400ULL, 'John', 'Smoker', 'Rolls', 'A Blunt', 'foo', 2009} space.index['i1']:select{6ULL} space.index['i1']:select{6} -{space.index['i2']:select{400ULL}} -{space.index['i2']:select{400}} +space.index['i2']:select(400ULL) +space.index['i2']:select(400) -{space:select{}} +space:select{} -- Test incorrect keys - supplied key field type does not match index type -- https://bugs.launchpad.net/tarantool/+bug/1072624 diff --git a/test/box/access.result b/test/box/access.result new file mode 100644 index 0000000000000000000000000000000000000000..d81d8b8ece1e7450c0e9acf7423158d68f6eed46 --- /dev/null +++ b/test/box/access.result @@ -0,0 +1,123 @@ +-- user id for a Lua session is admin - 1 +box.session.uid() +--- +- 1 +... +-- extra arguments are ignored +box.session.uid(nil) +--- +- 1 +... +-- admin +box.session.user() +--- +- admin +... +-- extra argumentes are ignored +box.session.user(nil) +--- +- admin +... +-- password() is a function which returns base64(sha1(sha1(password)) +-- a string to store in _user table +box.schema.user.password('test') +--- +- lL3OvhkIPOKh+Vn9Avlkx69M/Ck= +... +box.schema.user.password('test1') +--- +- BsC/W2Ts4vZItfBIpxkDkGugjlw= +... +-- admin can create any user +box.schema.user.create('test', { password = 'test' }) +--- +... +-- su() let's you change the user of the session +-- the user will be unabe to change back unless he/she +-- is granted access to 'su' +box.session.su('test') +--- +... +-- you can't create spaces unless you have a write access on +-- system space _space +-- in future we may introduce a separate privilege +box.schema.create_space('test') +--- +- error: Read access denied for user 'test' to space '_space' +... +-- su() goes through because called from admin +-- console, and it has no access checks +-- for functions +box.session.su('admin') +--- +... +box.schema.user.grant('test', 'write', 'space', '_space') +--- +... +--# setopt delimiter ';' +function usermax() + local i = 1 + while true do + box.schema.user.create('user'..i) + i = i + 1 + end +end; +--- +... +usermax(); +--- +- error: 'A limit on the total number of users has been reached: 32' +... +function usermax() + local i = 1 + while true do + box.schema.user.drop('user'..i) + i = i + 1 + end +end; +--- +... +usermax(); +--- +- error: User 'user30' does not exist +... +--# setopt delimiter '' +box.schema.user.create('rich') +--- +... +box.schema.user.grant('rich', 'read,write', 'universe') +--- +... +box.session.su('rich') +--- +... +uid = box.session.uid() +--- +... +box.schema.func.create('dummy') +--- +... +box.session.su('admin') +--- +... +box.space['_user']:delete{uid} +--- +- error: 'Failed to drop user ''rich'': the user has objects' +... +box.schema.func.drop('dummy') +--- +... +box.space['_user']:delete{uid} +--- +- error: 'Failed to drop user ''rich'': the user has objects' +... +box.schema.user.revoke('rich', 'read,write', 'universe') +--- +... +box.space['_user']:delete{uid} +--- +- [3, '', 'rich', []] +... +box.schema.user.drop('test') +--- +... diff --git a/test/box/access.test.lua b/test/box/access.test.lua new file mode 100644 index 0000000000000000000000000000000000000000..48b5ef987f3a6e378c0ab22df378c1ec0569d277 --- /dev/null +++ b/test/box/access.test.lua @@ -0,0 +1,58 @@ +-- user id for a Lua session is admin - 1 +box.session.uid() +-- extra arguments are ignored +box.session.uid(nil) +-- admin +box.session.user() +-- extra argumentes are ignored +box.session.user(nil) +-- password() is a function which returns base64(sha1(sha1(password)) +-- a string to store in _user table +box.schema.user.password('test') +box.schema.user.password('test1') +-- admin can create any user +box.schema.user.create('test', { password = 'test' }) +-- su() let's you change the user of the session +-- the user will be unabe to change back unless he/she +-- is granted access to 'su' +box.session.su('test') +-- you can't create spaces unless you have a write access on +-- system space _space +-- in future we may introduce a separate privilege +box.schema.create_space('test') +-- su() goes through because called from admin +-- console, and it has no access checks +-- for functions +box.session.su('admin') +box.schema.user.grant('test', 'write', 'space', '_space') + +--# setopt delimiter ';' +function usermax() + local i = 1 + while true do + box.schema.user.create('user'..i) + i = i + 1 + end +end; +usermax(); +function usermax() + local i = 1 + while true do + box.schema.user.drop('user'..i) + i = i + 1 + end +end; +usermax(); +--# setopt delimiter '' +box.schema.user.create('rich') +box.schema.user.grant('rich', 'read,write', 'universe') +box.session.su('rich') +uid = box.session.uid() +box.schema.func.create('dummy') +box.session.su('admin') +box.space['_user']:delete{uid} +box.schema.func.drop('dummy') +box.space['_user']:delete{uid} +box.schema.user.revoke('rich', 'read,write', 'universe') +box.space['_user']:delete{uid} +box.schema.user.drop('test') diff --git a/test/box/admin.result b/test/box/admin.result index 6a8cf5c744b7d2f02b1f9f5f2b13ea0e236d19e0..29757534ecb0eecf5913c9331e3792b5bb30b3df 100644 --- a/test/box/admin.result +++ b/test/box/admin.result @@ -14,7 +14,7 @@ box.stat() total: 0 rps: 0 SELECT: - total: 0 + total: 1 rps: 0 REPLACE: total: 0 @@ -76,7 +76,7 @@ box.stat() total: 0 rps: 0 SELECT: - total: 0 + total: 1 rps: 0 REPLACE: total: 0 diff --git a/test/box/alter.result b/test/box/alter.result index 4d702f4f4fabe41bcb54afabb1e62a4a6178fd34..59bfceb3c28b222ebedfd0d72f709a4fa974b9b6 100644 --- a/test/box/alter.result +++ b/test/box/alter.result @@ -4,11 +4,14 @@ _space = box.space[box.schema.SPACE_ID] _index = box.space[box.schema.INDEX_ID] --- ... +ADMIN = 1 +--- +... -- -- Test insertion into a system space - verify that -- mandatory fields are required. -- -_space:insert{_space.n, 5, 'test'} +_space:insert{_space.n, ADMIN, 'test', 5 } --- - error: Duplicate key exists in unique index 0 ... @@ -22,35 +25,35 @@ _space:insert{'hello', 'world', 'test'} -- -- Can't create a space which has wrong arity - arity must be NUM -- -_space:insert{_space.n, 'world', 'test'} +_space:insert{_space.n, ADMIN, 'test', 'world'} --- - error: Duplicate key exists in unique index 0 ... -- -- There is already a tuple for the system space -- -_space:insert{_space.n, 0, '_space'} +_space:insert{_space.n, ADMIN, '_space', 'memtx', 0} --- - error: Duplicate key exists in unique index 0 ... -_space:replace{_space.n, 0, '_space'} +_space:replace{_space.n, ADMIN, '_space', 'memtx', 0} --- -- [280, 0, '_space'] +- [280, 1, '_space', 'memtx', 0] ... -_space:insert{_index.n, 0, '_index'} +_space:insert{_index.n, ADMIN, '_index', 'memtx', 0} --- - error: Duplicate key exists in unique index 0 ... -_space:replace{_index.n, 0, '_index'} +_space:replace{_index.n, ADMIN, '_index', 'memtx', 0} --- -- [288, 0, '_index'] +- [288, 1, '_index', 'memtx', 0] ... -- -- Can't change properties of a space -- -_space:replace{_space.n, 0, '_space'} +_space:replace{_space.n, ADMIN, '_space', 'memtx', 0} --- -- [280, 0, '_space'] +- [280, 1, '_space', 'memtx', 0] ... -- -- Can't drop a system space @@ -77,7 +80,7 @@ _space:update({_space.n}, {{'+', 0, 2}}) -- -- Create a space -- -t = _space:auto_increment{0, 'hello'} +t = _space:auto_increment{ADMIN, 'hello', 'memtx', 0} --- ... -- Check that a space exists @@ -86,7 +89,7 @@ space = box.space[t[0]] ... space.n --- -- 289 +- 313 ... space.arity --- @@ -101,23 +104,23 @@ space.index[0] -- space:select{0} --- -- error: 'No index #0 is defined in space 289' +- error: 'No index #0 is defined in space 313' ... space:insert{0, 0} --- -- error: 'No index #0 is defined in space 289' +- error: 'No index #0 is defined in space 313' ... space:replace{0, 0} --- -- error: 'No index #0 is defined in space 289' +- error: 'No index #0 is defined in space 313' ... space:update({0}, {{'+', 0, 1}}) --- -- error: 'No index #0 is defined in space 289' +- error: 'No index #0 is defined in space 313' ... space:delete{0} --- -- error: 'No index #0 is defined in space 289' +- error: 'No index #0 is defined in space 313' ... t = _space:delete{space.n} --- @@ -131,7 +134,7 @@ space_deleted ... space:replace{0} --- -- error: Space 289 does not exist +- error: Space 313 does not exist ... _index:insert{_space.n, 0, 'primary', 'tree', 1, 1, 0, 'num'} --- @@ -151,20 +154,28 @@ _index:replace{_index.n, 0, 'primary', 'tree', 1, 2, 0, 'num', 1, 'num'} ... _index:select{} --- -- [272, 0, 'primary', 'tree', 1, 1, 0, 'str'] -- [280, 0, 'primary', 'tree', 1, 1, 0, 'num'] -- [280, 1, 'name', 'tree', 1, 1, 2, 'str'] -- [288, 0, 'primary', 'tree', 1, 2, 0, 'num', 1, 'num'] -- [288, 1, 'name', 'tree', 1, 2, 0, 'num', 2, 'str'] +- - [272, 0, 'primary', 'tree', 1, 1, 0, 'str'] + - [280, 0, 'primary', 'tree', 1, 1, 0, 'num'] + - [280, 1, 'owner', 'tree', 0, 1, 1, 'num'] + - [280, 2, 'name', 'tree', 1, 1, 2, 'str'] + - [288, 0, 'primary', 'tree', 1, 2, 0, 'num', 1, 'num'] + - [288, 2, 'name', 'tree', 1, 2, 0, 'num', 2, 'str'] + - [296, 0, 'primary', 'tree', 1, 1, 0, 'num'] + - [296, 1, 'owner', 'tree', 0, 1, 1, 'num'] + - [296, 2, 'name', 'tree', 1, 1, 2, 'str'] + - [304, 0, 'primary', 'tree', 1, 1, 0, 'num'] + - [304, 2, 'name', 'tree', 1, 1, 2, 'str'] + - [312, 0, 'primary', 'tree', 1, 3, 1, 'num', 2, 'str', 3, 'num'] + - [312, 1, 'owner', 'tree', 0, 1, 1, 'num'] ... -- modify indexes of a system space _index:delete{_index.n, 0} --- - error: Can't drop the primary key in a system space, space id 288 ... -_space:insert{1000, 0, 'hello'} +_space:insert{1000, ADMIN, 'hello', 'memtx', 0} --- -- [1000, 0, 'hello'] +- [1000, 1, 'hello', 'memtx', 0] ... _index:insert{1000, 0, 'primary', 'tree', 1, 1, 0, 'num'} --- @@ -195,9 +206,12 @@ box.snapshot() ... --# stop server default --# start server default -box.space['_space']:insert{1000, 0, 'test'} +ADMIN = 1 +--- +... +box.space['_space']:insert{1000, ADMIN, 'test', 'memtx', 0} --- -- [1000, 0, 'test'] +- [1000, 1, 'test', 'memtx', 0] ... box.space[1000].n --- @@ -205,7 +219,7 @@ box.space[1000].n ... box.space['_space']:delete{1000} --- -- [1000, 0, 'test'] +- [1000, 1, 'test', 'memtx', 0] ... box.space[1000] --- diff --git a/test/box/alter.test.lua b/test/box/alter.test.lua index e8058fb99d187384bfe99e782af56f135e46c5ac..940e42bec1143a67c5c07bab72f77d25d178860b 100644 --- a/test/box/alter.test.lua +++ b/test/box/alter.test.lua @@ -1,10 +1,11 @@ _space = box.space[box.schema.SPACE_ID] _index = box.space[box.schema.INDEX_ID] +ADMIN = 1 -- -- Test insertion into a system space - verify that -- mandatory fields are required. -- -_space:insert{_space.n, 5, 'test'} +_space:insert{_space.n, ADMIN, 'test', 5 } -- -- Bad space id -- @@ -12,18 +13,18 @@ _space:insert{'hello', 'world', 'test'} -- -- Can't create a space which has wrong arity - arity must be NUM -- -_space:insert{_space.n, 'world', 'test'} +_space:insert{_space.n, ADMIN, 'test', 'world'} -- -- There is already a tuple for the system space -- -_space:insert{_space.n, 0, '_space'} -_space:replace{_space.n, 0, '_space'} -_space:insert{_index.n, 0, '_index'} -_space:replace{_index.n, 0, '_index'} +_space:insert{_space.n, ADMIN, '_space', 'memtx', 0} +_space:replace{_space.n, ADMIN, '_space', 'memtx', 0} +_space:insert{_index.n, ADMIN, '_index', 'memtx', 0} +_space:replace{_index.n, ADMIN, '_index', 'memtx', 0} -- -- Can't change properties of a space -- -_space:replace{_space.n, 0, '_space'} +_space:replace{_space.n, ADMIN, '_space', 'memtx', 0} -- -- Can't drop a system space -- @@ -37,7 +38,7 @@ _space:update({_space.n}, {{'+', 0, 2}}) -- -- Create a space -- -t = _space:auto_increment{0, 'hello'} +t = _space:auto_increment{ADMIN, 'hello', 'memtx', 0} -- Check that a space exists space = box.space[t[0]] space.n @@ -62,7 +63,7 @@ _index:replace{_index.n, 0, 'primary', 'tree', 1, 2, 0, 'num', 1, 'num'} _index:select{} -- modify indexes of a system space _index:delete{_index.n, 0} -_space:insert{1000, 0, 'hello'} +_space:insert{1000, ADMIN, 'hello', 'memtx', 0} _index:insert{1000, 0, 'primary', 'tree', 1, 1, 0, 'num'} box.space[1000]:insert{0, 'hello, world'} box.space[1000]:drop() @@ -74,7 +75,8 @@ _space:run_triggers(false) box.snapshot() --# stop server default --# start server default -box.space['_space']:insert{1000, 0, 'test'} +ADMIN = 1 +box.space['_space']:insert{1000, ADMIN, 'test', 'memtx', 0} box.space[1000].n box.space['_space']:delete{1000} box.space[1000] diff --git a/test/box/alter_limits.result b/test/box/alter_limits.result index 85f5d1d0aa7fbce22aff8acb87a1af2d6b1cc095..4f9eeaa9709a3e6eb7c5475725cc13df513b2e56 100644 --- a/test/box/alter_limits.result +++ b/test/box/alter_limits.result @@ -68,6 +68,11 @@ s:drop() --- - error: Space 512 does not exist ... +-- no such engine +box.schema.create_space('tweedleedee', { engine = 'unknown' }) +--- +- error: Space engine 'unknown' does not exist +... -- explicit space id s = box.schema.create_space('tweedledum', { id = 3000 }) --- @@ -94,6 +99,11 @@ box.schema.create_space(string.rep('tweedledee', 100)) --- - error: 'Failed to create space 512: space name is too long' ... +-- too long space engine name +box.schema.create_space('tweedleedee', { engine = string.rep('too-long', 100) }) +--- +- error: 'Failed to create space 512: space engine name is too long' +... -- space name limit box.schema.create_space(string.rep('t', box.schema.NAME_MAX)..'_') --- @@ -242,33 +252,36 @@ s:insert{1, 2, 3} ... s:select{} --- -- [1, 2] +- - [1, 2] +... +ARITY = 4 +--- ... -- increase arity -- error -box.space['_space']:update(s.n, {{"=", 1, 3}}) +box.space['_space']:update(s.n, {{"=", ARITY, 3}}) --- - error: 'Can''t modify space 512: can not change arity on a non-empty space' ... s:select{} --- -- [1, 2] +- - [1, 2] ... -- decrease arity - error -box.space['_space']:update(s.n, {{"=", 1, 1}}) +box.space['_space']:update(s.n, {{"=", ARITY, 1}}) --- - error: 'Can''t modify space 512: can not change arity on a non-empty space' ... -- remove arity - ok -box.space['_space']:update(s.n, {{"=", 1, 0}}) +box.space['_space']:update(s.n, {{"=", ARITY, 0}}) --- -- [512, 0, 'test', ''] +- [512, 1, 'test', 'memtx', 0, ''] ... s:select{} --- -- [1, 2] +- - [1, 2] ... -- increase arity - error -box.space['_space']:update(s.n, {{"=", 1, 3}}) +box.space['_space']:update(s.n, {{"=", ARITY, 3}}) --- - error: 'Can''t modify space 512: can not change arity on a non-empty space' ... @@ -277,14 +290,16 @@ s:truncate() ... s:select{} --- +- [] ... -- set arity of an empty space -box.space['_space']:update(s.n, {{"=", 1, 3}}) +box.space['_space']:update(s.n, {{"=", ARITY, 3}}) --- -- [512, 3, 'test', ''] +- [512, 1, 'test', 'memtx', 3, ''] ... s:select{} --- +- [] ... -- arity actually works s:insert{3, 4} @@ -305,8 +320,8 @@ s:insert{7, 8, 9} ... s:select{} --- -- [3, 4, 5] -- [7, 8, 9] +- - [3, 4, 5] + - [7, 8, 9] ... -- check transition of space from enabled to disabled on -- deletion of the primary key @@ -657,7 +672,7 @@ s:create_index('third', { type = 'hash', parts = { 2, 'num' } }) ... s.index.third:rename('second') --- -- error: Duplicate key exists in unique index 1 +- error: Duplicate key exists in unique index 2 ... s.index.third.id --- @@ -727,13 +742,13 @@ s:create_index('year', { type = '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] +- - ['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', { type = 'tree', unique=true, parts = { 1, 'num'} }) @@ -747,13 +762,13 @@ s.index.year:alter({unique=true}) ... 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] +- - ['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}, {{"=", 7, 'num'}}) --- diff --git a/test/box/alter_limits.test.lua b/test/box/alter_limits.test.lua index 82063fc12998c868d03bfc4421afb6bbd1a967be..7b6fcc41695f234404839f561ccce5927bc33572 100644 --- a/test/box/alter_limits.test.lua +++ b/test/box/alter_limits.test.lua @@ -25,6 +25,8 @@ s = box.schema.create_space('tweedledum', { if_not_exists = true }) s:drop() -- no such space s:drop() +-- no such engine +box.schema.create_space('tweedleedee', { engine = 'unknown' }) -- explicit space id s = box.schema.create_space('tweedledum', { id = 3000 }) s.n @@ -35,6 +37,8 @@ box.schema.create_space('tweedledee', { id = 'tweedledee' }) s:drop() -- too long space name box.schema.create_space(string.rep('tweedledee', 100)) +-- too long space engine name +box.schema.create_space('tweedleedee', { engine = string.rep('too-long', 100) }) -- space name limit box.schema.create_space(string.rep('t', box.schema.NAME_MAX)..'_') s = box.schema.create_space(string.rep('t', box.schema.NAME_MAX - 1)..'_') @@ -84,20 +88,22 @@ s:insert{1} s:insert{1, 2} s:insert{1, 2, 3} s:select{} +ARITY = 4 -- increase arity -- error -box.space['_space']:update(s.n, {{"=", 1, 3}}) + +box.space['_space']:update(s.n, {{"=", ARITY, 3}}) s:select{} -- decrease arity - error -box.space['_space']:update(s.n, {{"=", 1, 1}}) +box.space['_space']:update(s.n, {{"=", ARITY, 1}}) -- remove arity - ok -box.space['_space']:update(s.n, {{"=", 1, 0}}) +box.space['_space']:update(s.n, {{"=", ARITY, 0}}) s:select{} -- increase arity - error -box.space['_space']:update(s.n, {{"=", 1, 3}}) +box.space['_space']:update(s.n, {{"=", ARITY, 3}}) s:truncate() s:select{} -- set arity of an empty space -box.space['_space']:update(s.n, {{"=", 1, 3}}) +box.space['_space']:update(s.n, {{"=", ARITY, 3}}) s:select{} -- arity actually works s:insert{3, 4} diff --git a/test/box/bad_trigger.result b/test/box/bad_trigger.result index a28855fbba5f38416b62fb7af4ffff5cae0a5b98..b40377d1712a5493a6b256b87c9530d8bb9d93cf 100644 --- a/test/box/bad_trigger.result +++ b/test/box/bad_trigger.result @@ -10,12 +10,7 @@ box.session.on_connect(f1) --- ... select * from t0 where k0=0 ---- -- error: - errcode: ER_PROC_LUA - errmsg: [string "function f1() nosuchfunction() end"]:1: attempt to call global 'nosuchfunction' (a nil value) -... -Connection is dead. +Connection is dead: Connection reset by peer. box.session.on_connect(nil, f1) --- diff --git a/test/box/bad_trigger.test.py b/test/box/bad_trigger.test.py index 083c7c6235afb1f6b4bac38a265e1e42d8b79c74..2083ac3f8cdfa8046c7a44aba60e9c18f3b90c93 100644 --- a/test/box/bad_trigger.test.py +++ b/test/box/bad_trigger.test.py @@ -1,4 +1,5 @@ from lib.box_connection import BoxConnection +from tarantool import NetworkError print """ # # if on_connect() trigger raises an exception, the connection is dropped @@ -7,11 +8,11 @@ print """ admin("function f1() nosuchfunction() end") admin("box.session.on_connect(f1)") -con1 = BoxConnection('localhost', sql.port) -con1("select * from t0 where k0=0") -if not con1.check_connection(): - print "Connection is dead.\n" -else: +try: + con1 = BoxConnection('localhost', sql.port) + con1("select * from t0 where k0=0") print "Connection is alive.\n" +except NetworkError as e: + print "Connection is dead: {0}.\n".format(e.message) # Clean-up admin("box.session.on_connect(nil, f1)") diff --git a/test/box/bug726778.cfg b/test/box/bug726778.cfg index f1e679f2c57109342a0566f20ab9ce8d6e92216d..5a37830c80b50e62b1f106d2953c3eb2b5c23a3b 100644 --- a/test/box/bug726778.cfg +++ b/test/box/bug726778.cfg @@ -11,7 +11,7 @@ wal_dir = "xlogs" logger="cat - >> tarantool.log" -primary_port = 33013 -admin_port = 33015 +primary_port = 3301 +admin_port = 3313 rows_per_wal = 50 diff --git a/test/box/call.result b/test/box/call.result index 8af0870f9ac984d71c49be151dc3aae9db943b66..06625a45290faf2c7104c66c4a8243e14f87aa3d 100644 --- a/test/box/call.result +++ b/test/box/call.result @@ -1,3 +1,9 @@ +box.schema.user.create('test', { password = 'test' }) +--- +... +box.schema.user.grant('test', 'execute,read,write', 'universe') +--- +... function f1() return 'testing', 1, false, -1, 1.123, 1e123, nil end --- ... @@ -229,7 +235,7 @@ insert into t0 values (2, 'test box delete') --- - [2, 'test box delete'] ... -call space:select(2) +call space:get(2) --- - [2, 'test box delete'] ... @@ -237,23 +243,35 @@ space:delete{2} --- - [2, 'test box delete'] ... -call space:select(2) +call space:get(2) --- ... insert into t0 values (2, 'test box.select()') --- - [2, 'test box.select()'] ... +call space:get(2) +--- +- [2, 'test box.select()'] +... call space:select(2) --- - [2, 'test box.select()'] ... -space:select{2} +space:get{2} --- - [2, 'test box.select()'] ... +space:select{2} +--- +- - [2, 'test box.select()'] +... +space:get{1} +--- +... space:select{1} --- +- [] ... call myreplace(2, 'hello', 'world') --- @@ -263,18 +281,30 @@ call myreplace(2, 'goodbye', 'universe') --- - [2, 'goodbye', 'universe'] ... +call space:get(2) +--- +- [2, 'goodbye', 'universe'] +... call space:select(2) --- - [2, 'goodbye', 'universe'] ... -space:select{2} +space:get{2} --- - [2, 'goodbye', 'universe'] ... +space:select{2} +--- +- - [2, 'goodbye', 'universe'] +... call myreplace(2) --- - [2] ... +call space:get(2) +--- +- [2] +... call space:select(2) --- - [2] @@ -300,6 +330,10 @@ space:update({3}, {{'=', 0, 4}, {'=', 1, 'new'}}) --- - [4, 'new', 2] ... +call space:get(4) +--- +- [4, 'new', 2] +... call space:select(4) --- - [4, 'new', 2] @@ -312,11 +346,15 @@ space:update({4}, {{'-', 2, 1}}) --- - [4, 'new', 2] ... +call space:get(4) +--- +- [4, 'new', 2] +... call space:select(4) --- - [4, 'new', 2] ... -function field_x(key, field_index) return space:select{key}[field_index] end +function field_x(key, field_index) return space:get(key)[field_index] end --- ... call field_x(4, 0) @@ -334,3 +372,6 @@ call space:delete(4) space:drop() --- ... +box.schema.user.drop('test') +--- +... diff --git a/test/box/call.test.py b/test/box/call.test.py index 1ca1cf40cc770c9d00bef709f781a99d3596e7af..a126b578fdd386a62173c8df3ca04ce0c019ed35 100644 --- a/test/box/call.test.py +++ b/test/box/call.test.py @@ -1,6 +1,9 @@ import os import sys +admin("box.schema.user.create('test', { password = 'test' })") +admin("box.schema.user.grant('test', 'execute,read,write', 'universe')") +sql.authenticate('test', 'test') admin("function f1() return 'testing', 1, false, -1, 1.123, 1e123, nil end") admin("f1()") sql("call f1()") @@ -81,18 +84,24 @@ sql("call space:delete(2)") sql("call space:delete(2)") admin("space:delete{2}") sql("insert into t0 values (2, 'test box delete')") -sql("call space:select(2)") +sql("call space:get(2)") admin("space:delete{2}") -sql("call space:select(2)") +sql("call space:get(2)") sql("insert into t0 values (2, 'test box.select()')") +sql("call space:get(2)") sql("call space:select(2)") +admin("space:get{2}") admin("space:select{2}") +admin("space:get{1}") admin("space:select{1}") sql("call myreplace(2, 'hello', 'world')") sql("call myreplace(2, 'goodbye', 'universe')") +sql("call space:get(2)") sql("call space:select(2)") +admin("space:get{2}") admin("space:select{2}") sql("call myreplace(2)") +sql("call space:get(2)") sql("call space:select(2)") sql("call space:delete(2)") sql("call space:delete(2)") @@ -100,13 +109,16 @@ 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'}})") +sql("call space:get(4)") sql("call space:select(4)") admin("space:update({4}, {{'+', 2, 1}})") admin("space:update({4}, {{'-', 2, 1}})") +sql("call space:get(4)") sql("call space:select(4)") -admin("function field_x(key, field_index) return space:select{key}[field_index] end") +admin("function field_x(key, field_index) return space:get(key)[field_index] end") sql("call field_x(4, 0)") sql("call field_x(4, 1)") sql("call space:delete(4)") admin("space:drop()") +admin("box.schema.user.drop('test')") diff --git a/test/box/configuration.result b/test/box/configuration.result index 8c91826cea92bd063cd2fbdf18f6e6a36efd27ef..21ff122ca35955cc33b86d895b98f238f8cbf88c 100644 --- a/test/box/configuration.result +++ b/test/box/configuration.result @@ -44,15 +44,15 @@ box.space.tweedledum:insert{4, 8, 16} # Test insert from init.lua -box.space.tweedledum:select{1} +box.space.tweedledum:get(1) --- - [1, 2, 4, 8] ... -box.space.tweedledum:select(2) +box.space.tweedledum:get(2) --- - [2, 4, 8, 16] ... -box.space.tweedledum:select(4) +box.space.tweedledum:get(4) --- - [4, 8, 16] ... diff --git a/test/box/configuration.test.py b/test/box/configuration.test.py index 424dad1eae7a7e6893ec28cea9b5be7812114d20..5cfbdea9ed36068a72d7544efd6d00150bfaeba3 100644 --- a/test/box/configuration.test.py +++ b/test/box/configuration.test.py @@ -40,9 +40,9 @@ admin("box.space.tweedledum:insert{4, 8, 16}") print """ # Test insert from init.lua """ -admin("box.space.tweedledum:select{1}") -admin("box.space.tweedledum:select(2)") -admin("box.space.tweedledum:select(4)") +admin("box.space.tweedledum:get(1)") +admin("box.space.tweedledum:get(2)") +admin("box.space.tweedledum:get(4)") print """ # Test bug #1002272 diff --git a/test/box/crossjoin.result b/test/box/crossjoin.result index b3c9739ae917ae5e74413c38c36a02bb28d89ba8..ef64f6e841fac440068f04846a6c61c2e8a82b03 100644 --- a/test/box/crossjoin.result +++ b/test/box/crossjoin.result @@ -7,8 +7,8 @@ space:create_index('primary', { type = 'tree' }) --# setopt delimiter ';' function crossjoin(space0, space1, limit) local result = {} - for v0 in space0:iterator() do - for v1 in space1:iterator() do + for _,v0 in space0:pairs() do + for _,v1 in space1:pairs() do if limit <= 0 then return result end diff --git a/test/box/crossjoin.test.lua b/test/box/crossjoin.test.lua index b7839c1f4e56b6be551f4fd20f825f2a3341f01b..5919ae40b5cd6f10a6f4fa0006af4cebc643e388 100644 --- a/test/box/crossjoin.test.lua +++ b/test/box/crossjoin.test.lua @@ -3,8 +3,8 @@ space:create_index('primary', { type = 'tree' }) --# setopt delimiter ';' function crossjoin(space0, space1, limit) local result = {} - for v0 in space0:iterator() do - for v1 in space1:iterator() do + for _,v0 in space0:pairs() do + for _,v1 in space1:pairs() do if limit <= 0 then return result end diff --git a/test/box/dup_key1.xlog b/test/box/dup_key1.xlog index a168b8473c850b6915b89dae08b8fce7816dc0e2..08563a9fb2cb9836509d28764624e13ae2c2d2dd 100644 Binary files a/test/box/dup_key1.xlog and b/test/box/dup_key1.xlog differ diff --git a/test/box/dup_key2.xlog b/test/box/dup_key2.xlog index 5d6978b801b0a483023b3efd218fadcd97645d5c..fb10436343275d0d4f7b12af4a3746fa56f0c55b 100644 Binary files a/test/box/dup_key2.xlog and b/test/box/dup_key2.xlog differ diff --git a/test/box/errinj.result b/test/box/errinj.result index c95dc2929dc851e5aed44578ac8a69af4324d5b1..4a6af65688d39034fddd1c68af7375b2364ab3d3 100644 --- a/test/box/errinj.result +++ b/test/box/errinj.result @@ -25,14 +25,14 @@ box.errinj.set("some-injection") -- check error --- - 'error: can''t find error injection ''some-injection''' ... -space:select{222444} +space:get{222444} --- ... box.errinj.set("ERRINJ_TESTING", true) --- - ok ... -space:select{222444} +space:get{222444} --- - error: Error injection 'ERRINJ_TESTING' ... @@ -49,7 +49,7 @@ space:insert{1} --- - error: Failed to write to disk ... -space:select{1} +space:get{1} --- ... box.errinj.set("ERRINJ_WAL_IO", false) @@ -68,11 +68,11 @@ space:update(1, {{'=', 0, 2}}) --- - error: Failed to write to disk ... -space:select{1} +space:get{1} --- - [1] ... -space:select{2} +space:get{2} --- ... box.errinj.set("ERRINJ_WAL_IO", false) @@ -91,7 +91,7 @@ space:insert{1} --- - error: Failed to write to disk ... -space:select{1} +space:get{1} --- ... box.errinj.set("ERRINJ_WAL_ROTATE", false) @@ -110,11 +110,11 @@ space:update(1, {{'=', 0, 2}}) --- - error: Failed to write to disk ... -space:select{1} +space:get{1} --- - [1] ... -space:select{2} +space:get{2} --- ... box.errinj.set("ERRINJ_WAL_ROTATE", false) @@ -125,10 +125,10 @@ space:update(1, {{'=', 0, 2}}) --- - [2] ... -space:select{1} +space:get{1} --- ... -space:select{2} +space:get{2} --- - [2] ... diff --git a/test/box/errinj.test.lua b/test/box/errinj.test.lua index 69f7fcb259e209e1004df0c90011612dfe0885ae..d3ba84ff8b9d185fb0c1515a23f66ffa6c3051e3 100644 --- a/test/box/errinj.test.lua +++ b/test/box/errinj.test.lua @@ -4,38 +4,38 @@ space:create_index('primary', { type = 'hash' }) box.errinj.info() box.errinj.set("some-injection", true) box.errinj.set("some-injection") -- check error -space:select{222444} +space:get{222444} box.errinj.set("ERRINJ_TESTING", true) -space:select{222444} +space:get{222444} box.errinj.set("ERRINJ_TESTING", false) -- Check how well we handle a failed log write box.errinj.set("ERRINJ_WAL_IO", true) space:insert{1} -space:select{1} +space:get{1} box.errinj.set("ERRINJ_WAL_IO", false) space:insert{1} box.errinj.set("ERRINJ_WAL_IO", true) space:update(1, {{'=', 0, 2}}) -space:select{1} -space:select{2} +space:get{1} +space:get{2} box.errinj.set("ERRINJ_WAL_IO", false) space:truncate() -- Check a failed log rotation box.errinj.set("ERRINJ_WAL_ROTATE", true) space:insert{1} -space:select{1} +space:get{1} box.errinj.set("ERRINJ_WAL_ROTATE", false) space:insert{1} box.errinj.set("ERRINJ_WAL_ROTATE", true) space:update(1, {{'=', 0, 2}}) -space:select{1} -space:select{2} +space:get{1} +space:get{2} box.errinj.set("ERRINJ_WAL_ROTATE", false) space:update(1, {{'=', 0, 2}}) -space:select{1} -space:select{2} +space:get{1} +space:get{2} box.errinj.set("ERRINJ_WAL_ROTATE", true) space:truncate() box.errinj.set("ERRINJ_WAL_ROTATE", false) diff --git a/test/box/errinj_index.result b/test/box/errinj_index.result index 3c936cfacc929c2e0d1cebd0e0652580c6222d30..feb59b77a8af5e0abc5053141aab1e0b40363a65 100644 --- a/test/box/errinj_index.result +++ b/test/box/errinj_index.result @@ -11,7 +11,7 @@ for i = 1,10 do s:insert{i, i, 'test' .. i} end res = {} --- ... -for i = 1,10 do table.insert(res, s:select{i}) end +for i = 1,10 do table.insert(res, s:get{i}) end --- ... res @@ -30,7 +30,7 @@ res res = {} --- ... -for t in s.index[0]:iterator() do table.insert(res, t) end +for _, t in s.index[0]:pairs() do table.insert(res, t) end --- ... res @@ -53,7 +53,7 @@ box.errinj.set("ERRINJ_TREE_ALLOC", true) res = {} --- ... -for i = 1,10 do table.insert(res, s:select{i}) end +for i = 1,10 do table.insert(res, s:get{i}) end --- ... res @@ -80,7 +80,7 @@ s:delete{1} res = {} --- ... -for t in s.index[0]:iterator() do table.insert(res, t) end +for _, t in s.index[0]:pairs() do table.insert(res, t) end --- - error: Failed to allocate 196 bytes in TreeIndex for init iterator ... @@ -93,7 +93,7 @@ box.errinj.set("ERRINJ_TREE_ALLOC", false) --- - ok ... -s:select{1} +s:get{1} --- ... box.errinj.set("ERRINJ_TREE_ALLOC", true) @@ -103,7 +103,7 @@ box.errinj.set("ERRINJ_TREE_ALLOC", true) res = {} --- ... -for i = 1,10 do table.insert(res, (s:select{i})) end +for i = 1,10 do table.insert(res, (s:get{i})) end --- ... res @@ -126,7 +126,7 @@ s:delete{2} --- - [2, 2, 'test2'] ... -s.index[0]:iterator() +s.index[0]:pairs() --- - error: Failed to allocate 200 bytes in TreeIndex for init iterator ... @@ -136,7 +136,7 @@ box.errinj.set("ERRINJ_TREE_ALLOC", false) --- - ok ... -s:select{1} +s:get{1} --- ... box.errinj.set("ERRINJ_TREE_ALLOC", true) @@ -146,7 +146,7 @@ box.errinj.set("ERRINJ_TREE_ALLOC", true) res = {} --- ... -for i = 1,10 do table.insert(res, (s:select{i})) end +for i = 1,10 do table.insert(res, (s:get{i})) end --- ... res @@ -168,7 +168,7 @@ s:delete{3} --- - [3, 3, 'test3'] ... -s.index[0]:iterator() +s.index[0]:pairs() --- - error: Failed to allocate 200 bytes in TreeIndex for init iterator ... @@ -182,7 +182,7 @@ for i = 2001,2500 do s:insert{i, i} end res = {} --- ... -for i = 1,10 do table.insert(res, (s:select{i})) end +for i = 1,10 do table.insert(res, (s:get{i})) end --- ... res @@ -202,7 +202,7 @@ s:delete{8} res = {} --- ... -for i = 1,10 do table.insert(res, (s:select{i})) end +for i = 1,10 do table.insert(res, (s:get{i})) end --- ... res @@ -217,7 +217,7 @@ res res = {} --- ... -for i = 2001,2010 do table.insert(res, (s:select{i})) end +for i = 2001,2010 do table.insert(res, (s:get{i})) end --- ... res diff --git a/test/box/errinj_index.test.lua b/test/box/errinj_index.test.lua index 1341c396f2cd4645b8c3b54c30e24001e4842e8c..05e65e060af7eb5630fff5f381bbfea05def1f2b 100644 --- a/test/box/errinj_index.test.lua +++ b/test/box/errinj_index.test.lua @@ -5,61 +5,61 @@ s:create_index('primary') for i = 1,10 do s:insert{i, i, 'test' .. i} end res = {} -for i = 1,10 do table.insert(res, s:select{i}) end +for i = 1,10 do table.insert(res, s:get{i}) end res res = {} -for t in s.index[0]:iterator() do table.insert(res, t) end +for _, t in s.index[0]:pairs() do table.insert(res, t) end res box.errinj.set("ERRINJ_TREE_ALLOC", true) res = {} -for i = 1,10 do table.insert(res, s:select{i}) end +for i = 1,10 do table.insert(res, s:get{i}) end res for i = 501,1000 do s:insert{i, i} end s:delete{1} res = {} -for t in s.index[0]:iterator() do table.insert(res, t) end +for _, t in s.index[0]:pairs() do table.insert(res, t) end res -- reserve memory for iterator in index. last insert may increase tree depth box.errinj.set("ERRINJ_TREE_ALLOC", false) -s:select{1} +s:get{1} box.errinj.set("ERRINJ_TREE_ALLOC", true) res = {} -for i = 1,10 do table.insert(res, (s:select{i})) end +for i = 1,10 do table.insert(res, (s:get{i})) end res for i = 1001,1500 do s:insert{i, i} end s:delete{2} -s.index[0]:iterator() +s.index[0]:pairs() -- reserve memory for iterator in index. last insert may increase tree depth -- (if rebalance was not initiated) box.errinj.set("ERRINJ_TREE_ALLOC", false) -s:select{1} +s:get{1} box.errinj.set("ERRINJ_TREE_ALLOC", true) res = {} -for i = 1,10 do table.insert(res, (s:select{i})) end +for i = 1,10 do table.insert(res, (s:get{i})) end res for i = 1501,2000 do s:insert{i, i} end s:delete{3} -s.index[0]:iterator() +s.index[0]:pairs() box.errinj.set("ERRINJ_TREE_ALLOC", false) for i = 2001,2500 do s:insert{i, i} end res = {} -for i = 1,10 do table.insert(res, (s:select{i})) end +for i = 1,10 do table.insert(res, (s:get{i})) end res s:delete{8} res = {} -for i = 1,10 do table.insert(res, (s:select{i})) end +for i = 1,10 do table.insert(res, (s:get{i})) end res res = {} -for i = 2001,2010 do table.insert(res, (s:select{i})) end +for i = 2001,2010 do table.insert(res, (s:get{i})) end res s:drop() diff --git a/test/box/fiber.result b/test/box/fiber.result index 12b60d4c5b5cee585a952de734f622a3968412ba..caffa03bf09e890e1ad13f44354e416419f4140a 100644 --- a/test/box/fiber.result +++ b/test/box/fiber.result @@ -579,9 +579,15 @@ box.fiber.resume(f) --- - error: 'fiber.resume(): the fiber is dead' ... -function r() box.fiber.yield(box.space.tweedledum:insert{0, 0, 1}) box.fiber.yield(box.space.tweedledum:select{0}) box.fiber.yield(box.space.tweedledum:truncate()) end +--# setopt delimiter ';' +function r() + box.fiber.yield(box.space.tweedledum:insert{0, 0, 1}) + box.fiber.yield(box.space.tweedledum:get{0}) + box.fiber.yield(box.space.tweedledum:truncate()) +end; --- ... +--# setopt delimiter '' f = box.fiber.create(r) --- ... diff --git a/test/box/fiber.test.lua b/test/box/fiber.test.lua index 094fbb434c769de7e145351291b58c7ca6fd2c88..ab9cb4ebcf7a8602c405bdbb47b9a3e5941523d2 100644 --- a/test/box/fiber.test.lua +++ b/test/box/fiber.test.lua @@ -208,7 +208,13 @@ function r() return box.fiber.sleep(0.01) end f = box.fiber.create(r) box.fiber.resume(f) box.fiber.resume(f) -function r() box.fiber.yield(box.space.tweedledum:insert{0, 0, 1}) box.fiber.yield(box.space.tweedledum:select{0}) box.fiber.yield(box.space.tweedledum:truncate()) end +--# setopt delimiter ';' +function r() + box.fiber.yield(box.space.tweedledum:insert{0, 0, 1}) + box.fiber.yield(box.space.tweedledum:get{0}) + box.fiber.yield(box.space.tweedledum:truncate()) +end; +--# setopt delimiter '' f = box.fiber.create(r) box.fiber.resume(f) box.fiber.resume(f) diff --git a/test/box/lua/fifo.lua b/test/box/lua/fifo.lua index bc2ba2b8c94a50fa50821a5783792f2d671fa834..08067f36a4536cd50202fbc19296a19f18c79b80 100644 --- a/test/box/lua/fifo.lua +++ b/test/box/lua/fifo.lua @@ -1,6 +1,6 @@ fifomax = 5 function find_or_create_fifo(space, name) - fifo = space:select{name} + fifo = space:get{name} if fifo == nil then fifo = {} for i = 1, fifomax do fifo[i] = 0 end diff --git a/test/box/luafun.result b/test/box/luafun.result new file mode 100644 index 0000000000000000000000000000000000000000..70f98792cf0d5b7b0cbae348535f4fc076a789bb --- /dev/null +++ b/test/box/luafun.result @@ -0,0 +1,180 @@ +-------------------------------------------------------------------------------- +-- # luafun integration +-------------------------------------------------------------------------------- +space = box.schema.create_space('tweedledum') +--- +... +space:create_index('primary', { type = 'hash' }) +--- +... +for i = 1,5,1 do space:replace({i, i}) end +--- +... +fun = require('fun') +--- +... +-- print all methods from metatable +methods = fun.iter(getmetatable(fun.range(5)).__index):totable() +--- +... +table.sort(methods) +--- +... +methods +--- +- - all + - any + - car + - cdr + - chain + - cycle + - drop + - drop_n + - drop_while + - each + - elem_index + - elem_indexes + - elem_indices + - enumerate + - every + - filter + - foldl + - for_each + - foreach + - grep + - head + - index + - index_of + - indexes + - indices + - intersperse + - is_null + - is_prefix_of + - length + - map + - max + - max_by + - maximum + - min + - min_by + - minimum + - minimum_by + - nth + - op + - operator + - partition + - product + - reduce + - remove_if + - some + - span + - split + - split_at + - sum + - tail + - take + - take_n + - take_while + - tomap + - totable + - unwrap + - zip +... +-- iter on arrays +fun.iter({1, 2, 3}):totable() +--- +- - 1 + - 2 + - 3 +... +fun.iter({2, 4, 6, 8}):all(function(x) return x % 2 == 1 end) +--- +- false +... +-- iter on hashes +fun.iter({a = 1, b = 2, c = 3}):tomap() +--- +- b: 2 + a: 1 + c: 3 +... +-- iter on tuple +fun.iter(box.tuple.new({1, 2, 3}):pairs()):totable() +--- +- - 1 + - 2 + - 3 +... +-- iter on space (using __ipairs) +function pred(t) return t[1] % 2 == 0 end +--- +... +fun.iter(space):totable() +--- +- - [1, 1] + - [2, 2] + - [3, 3] + - [4, 4] + - [5, 5] +... +fun.iter(space:pairs()):totable() +--- +- - [1, 1] + - [2, 2] + - [3, 3] + - [4, 4] + - [5, 5] +... +space:pairs():filter(pred):drop(2):take(3):totable() +--- +- [] +... +-- iter on index (using __ipairs) +fun.iter(space.index[0]):totable() +--- +- - [1, 1] + - [2, 2] + - [3, 3] + - [4, 4] + - [5, 5] +... +fun.iter(space.index[0]:pairs()):totable() +--- +- - [1, 1] + - [2, 2] + - [3, 3] + - [4, 4] + - [5, 5] +... +space.index[0]:pairs():drop(2):take(3):totable() +--- +- - [3, 3] + - [4, 4] + - [5, 5] +... +-- test global functions +--# setopt delimiter ';' +fun.reduce(function(acc, val) return acc + val end, 0, + fun.filter(function(x) return x % 11 == 0 end, + fun.map(function(x) return 2 * x end, fun.range(1000)))); +--- +- 90090 +... +--# setopt delimiter '' +t = {} +--- +... +fun.foreach(function(x) table.insert(t, x) end, "abcde") +--- +... +t +--- +- - a + - b + - c + - d + - e +... +space:drop() +--- +... diff --git a/test/box/luafun.test.lua b/test/box/luafun.test.lua new file mode 100644 index 0000000000000000000000000000000000000000..d66aa5874bac1b80c73b64a5a71c84eb2ef4616b --- /dev/null +++ b/test/box/luafun.test.lua @@ -0,0 +1,49 @@ +-------------------------------------------------------------------------------- +-- # luafun integration +-------------------------------------------------------------------------------- + +space = box.schema.create_space('tweedledum') +space:create_index('primary', { type = 'hash' }) +for i = 1,5,1 do space:replace({i, i}) end + +fun = require('fun') + +-- print all methods from metatable +methods = fun.iter(getmetatable(fun.range(5)).__index):totable() +table.sort(methods) +methods + +-- iter on arrays +fun.iter({1, 2, 3}):totable() +fun.iter({2, 4, 6, 8}):all(function(x) return x % 2 == 1 end) + +-- iter on hashes +fun.iter({a = 1, b = 2, c = 3}):tomap() + +-- iter on tuple +fun.iter(box.tuple.new({1, 2, 3}):pairs()):totable() + +-- iter on space (using __ipairs) +function pred(t) return t[1] % 2 == 0 end +fun.iter(space):totable() +fun.iter(space:pairs()):totable() +space:pairs():filter(pred):drop(2):take(3):totable() + +-- iter on index (using __ipairs) +fun.iter(space.index[0]):totable() +fun.iter(space.index[0]:pairs()):totable() +space.index[0]:pairs():drop(2):take(3):totable() + +-- test global functions +--# setopt delimiter ';' +fun.reduce(function(acc, val) return acc + val end, 0, + fun.filter(function(x) return x % 11 == 0 end, + fun.map(function(x) return 2 * x end, fun.range(1000)))); + +--# setopt delimiter '' + +t = {} +fun.foreach(function(x) table.insert(t, x) end, "abcde") +t + +space:drop() diff --git a/test/box/misc.result b/test/box/misc.result index d6884ceccc4dea7150d10f1d559a606eb0700d1d..93806232d54deabc0e39c1f2424249373cef2d02 100644 --- a/test/box/misc.result +++ b/test/box/misc.result @@ -19,7 +19,6 @@ t - - _delete - _insert - _replace - - _select - _update - call_loadproc - cfg @@ -194,34 +193,50 @@ end; ... t; --- -- - 'box.error.ER_NO_SUCH_INDEX : 35' +- - 'box.error.ER_CREATE_FUNCTION : 50' + - 'box.error.ER_NO_SUCH_INDEX : 35' - 'box.error.ER_TUPLE_FOUND : 3' - 'box.error.ER_CREATE_SPACE : 9' - 'box.error.ER_TUPLE_FORMAT_LIMIT : 16' - 'box.error.ER_FIELD_TYPE : 23' - 'box.error.ER_OK : 0' + - 'box.error.ER_NO_SUCH_ENGINE : 57' - 'box.error.ER_TUPLE_NOT_FOUND : 4' - 'box.error.ER_INDEX_ARITY : 39' - 'box.error.ER_WAL_IO : 40' + - 'box.error.ER_USER_MAX : 56' + - 'box.error.ER_NO_SUCH_FUNCTION : 51' - 'box.error.ER_INJECTION : 8' - 'box.error.ER_DROP_PRIMARY_KEY : 17' - 'box.error.ER_INDEX_TYPE : 13' - 'box.error.ER_ARG_TYPE : 26' + - 'box.error.ER_FUNCTION_MAX : 54' + - 'box.error.ER_FUNCTION_ACCESS_DENIED : 53' + - 'box.error.ER_SPACE_ARITY : 38' - 'box.error.ER_INVALID_MSGPACK : 20' + - 'box.error.ER_SPACE_ACCESS_DENIED : 55' - 'box.error.ER_KEY_PART_COUNT : 31' + - 'box.error.ER_UNKNOWN_SCHEMA_OBJECT : 49' + - 'box.error.ER_USER_EXISTS : 46' - 'box.error.ER_MEMORY_ISSUE : 2' - 'box.error.ER_ILLEGAL_PARAMS : 1' - 'box.error.ER_KEY_FIELD_TYPE : 18' - 'box.error.ER_NONMASTER : 6' + - 'box.error.ER_UNKNOWN_REQUEST_TYPE : 48' - 'box.error.ER_FIELD_TYPE_MISMATCH : 24' - 'box.error.ER_MODIFY_INDEX : 14' + - 'box.error.ER_PASSWORD_MISMATCH : 47' - 'box.error.ER_EXACT_MATCH : 19' + - 'box.error.ER_NO_SUCH_USER : 45' - 'box.error.ER_SECONDARY : 7' + - 'box.error.ER_FUNCTION_EXISTS : 52' + - 'box.error.ER_CREATE_USER : 43' + - 'box.error.ER_ACCESS_DENIED : 42' - 'box.error.ER_LAST_DROP : 15' - 'box.error.ER_UPDATE_FIELD : 29' - 'box.error.ER_FIBER_STACK : 30' - 'box.error.ER_UNKNOWN_UPDATE_OP : 28' - - 'box.error.ER_SPACE_ARITY : 38' + - 'box.error.ER_DROP_USER : 44' - 'box.error.ER_UNSUPPORTED : 5' - 'box.error.ER_NO_SUCH_FIELD : 37' - 'box.error.ER_TUPLE_NOT_ARRAY : 22' @@ -401,7 +416,7 @@ box.counter.inc(space.n, {1}) --- - 1 ... -space:select{1} +space:get{1} --- - [1, 1] ... @@ -413,7 +428,7 @@ box.counter.inc(space.n, {1}) --- - 3 ... -space:select{1} +space:get{1} --- - [1, 3] ... @@ -429,7 +444,7 @@ box.counter.dec(space.n, {1}) --- - 0 ... -space:select{1} +space:get{1} --- ... space:truncate() diff --git a/test/box/misc.test.lua b/test/box/misc.test.lua index 6e2f96d8594a6cd8b7fc87706ed11e8ba0784b91..7c9ef513656eb8ff15833a630ab53070ab0283ac 100644 --- a/test/box/misc.test.lua +++ b/test/box/misc.test.lua @@ -131,14 +131,14 @@ bit.bor(1, 2) -- A test case for box.counter space = box.space.tweedledum box.counter.inc(space.n, {1}) -space:select{1} +space:get{1} box.counter.inc(space.n, {1}) box.counter.inc(space.n, {1}) -space:select{1} +space:get{1} box.counter.dec(space.n, {1}) box.counter.dec(space.n, {1}) box.counter.dec(space.n, {1}) -space:select{1} +space:get{1} space:truncate() dofile('fifo.lua') diff --git a/test/box/msgpack.result b/test/box/msgpack.result index 1f59c421df21fc371448cfebe3a929881f0f918f..9669f9f892c59cd912219233dbe16ad46e69158f 100644 --- a/test/box/msgpack.result +++ b/test/box/msgpack.result @@ -21,7 +21,7 @@ msgpack.encode('a', 'b') ... msgpack.decode('a', 'b') --- -- error: 'msgpack.decode: a Lua string expected' +- error: 'msgpack.decode: offset is out of bounds' ... --# setopt delimiter ';' function deepcompare(a, b) @@ -53,7 +53,7 @@ end; function test(x) local buf1 = msgpack.encode(x) local buf2 = msgpackffi.encode(x) - local x1, offset1 = msgpack.next(buf1) + local x1, offset1 = msgpack.decode(buf1) local x2, offset2 = msgpackffi.decode_unchecked(buf2) local xstr if type(x) == "table" then @@ -337,6 +337,7 @@ msgpack.decode(msgpack.encode({[0] = 1, 2, 3, 4, 5})) 3: 4 1: 2 4: 5 +- 12 ... -- test sparse / dense arrays msgpack.decode(msgpack.encode({1, 2, 3, 4, 5, [10] = 10})) @@ -347,6 +348,7 @@ msgpack.decode(msgpack.encode({1, 2, 3, 4, 5, [10] = 10})) 1: 1 10: 10 4: 4 +- 14 ... msgpack.decode(msgpack.encode({1, 2, 3, 4, 5, [100] = 100})) --- @@ -356,6 +358,7 @@ msgpack.decode(msgpack.encode({1, 2, 3, 4, 5, [100] = 100})) 1: 1 100: 100 4: 4 +- 14 ... msgpackffi.decode_unchecked(msgpackffi.encode({1, 2, 3, 4, 5, [100] = 100})) --- @@ -462,6 +465,7 @@ msgpack.decode(msgpack.encode(a)); - b - c - null +- 90 ... msgpackffi.decode_unchecked(msgpackffi.encode(a)); --- @@ -521,19 +525,19 @@ msgpackffi.decode_unchecked(msgpackffi.encode(a)); a = { 1, 2, 3 } --- ... -msgpack.decode(msgpack.dumps(a)) +(msgpack.decode(msgpack.dumps(a))) --- - - 1 - 2 - 3 ... -msgpack.loads(msgpack.encode(a)) +(msgpack.loads(msgpack.encode(a))) --- - - 1 - 2 - 3 ... --- Test msgpack.next +-- Test msgpack.decode with offsets dump = msgpack.dumps({1, 2, 3})..msgpack.dumps({4, 5, 6}) --- ... @@ -541,7 +545,7 @@ dump:len() --- - 8 ... -a, offset = msgpack.next(dump) +a, offset = msgpack.decode(dump) --- ... a @@ -554,7 +558,7 @@ offset --- - 5 ... -a, offset = msgpack.next(dump, offset) +a, offset = msgpack.decode(dump, offset) --- ... a @@ -567,10 +571,10 @@ offset --- - 9 ... -a, offset = msgpack.next(dump, offset) +a, offset = msgpack.decode(dump, offset) --- -- error: '[string "a, offset = msgpack.next(dump, offset) "]:1: msgpack.next: offset - is out of bounds' +- error: '[string "a, offset = msgpack.decode(dump, offset) "]:1: msgpack.decode: + offset is out of bounds' ... -- Test decode with offset dump = msgpackffi.encode({1, 2, 3})..msgpackffi.encode({4, 5, 6}) @@ -608,6 +612,5 @@ offset ... a, offset = msgpackffi.decode_unchecked(dump, offset) --- -- error: '[string "-- msgpackffi.lua (internal file)..."]:460: offset = 9 is out of - bounds [1..8]' +- error: 'builtin/msgpackffi.lua:460: offset = 9 is out of bounds [1..8]' ... diff --git a/test/box/msgpack.test.lua b/test/box/msgpack.test.lua index f29d05124eb0145cee7cd7e6fd2241d42a41ba57..d573101a70f8cd3ab3c5c8665e4824fcbf631f27 100644 --- a/test/box/msgpack.test.lua +++ b/test/box/msgpack.test.lua @@ -41,7 +41,7 @@ end; function test(x) local buf1 = msgpack.encode(x) local buf2 = msgpackffi.encode(x) - local x1, offset1 = msgpack.next(buf1) + local x1, offset1 = msgpack.decode(buf1) local x2, offset2 = msgpackffi.decode_unchecked(buf2) local xstr if type(x) == "table" then @@ -220,18 +220,18 @@ msgpackffi.decode_unchecked(msgpackffi.encode(a)); --# setopt delimiter '' -- Test aliases, loads and dumps a = { 1, 2, 3 } -msgpack.decode(msgpack.dumps(a)) -msgpack.loads(msgpack.encode(a)) --- Test msgpack.next +(msgpack.decode(msgpack.dumps(a))) +(msgpack.loads(msgpack.encode(a))) +-- Test msgpack.decode with offsets dump = msgpack.dumps({1, 2, 3})..msgpack.dumps({4, 5, 6}) dump:len() -a, offset = msgpack.next(dump) +a, offset = msgpack.decode(dump) a offset -a, offset = msgpack.next(dump, offset) +a, offset = msgpack.decode(dump, offset) a offset -a, offset = msgpack.next(dump, offset) +a, offset = msgpack.decode(dump, offset) -- Test decode with offset dump = msgpackffi.encode({1, 2, 3})..msgpackffi.encode({4, 5, 6}) diff --git a/test/box/net.box.result b/test/box/net.box.result index 9a89eee9ab720d5ee6a4fb2f8b38e1a9d08379ca..bc82f3272e3481a23d6ff7fddb9fa3f39d0c956d 100644 --- a/test/box/net.box.result +++ b/test/box/net.box.result @@ -4,6 +4,9 @@ space = box.schema.create_space('tweedledum') space:create_index('primary', { type = 'tree'}) --- ... +box.schema.user.grant('guest', 'read,write,execute', 'universe') +--- +... remote = box.net.box.new('localhost', box.cfg.primary_port, '0.5') --- ... @@ -29,10 +32,19 @@ space:insert{123, 'test1', 'test2'} ... space:select{123} --- +- - [123, 'test1', 'test2'] +... +space:get{123} +--- - [123, 'test1', 'test2'] ... -tuple = remote:select(space.n, 123) +remote:select(space.n, 123) --- +- - [123, 'test1', 'test2'] +... +remote:get(space.n, 123) +--- +- [123, 'test1', 'test2'] ... function test(...) return box.tuple.new({ 123, 456 }) end --- @@ -152,14 +164,30 @@ remote:call('test.a:b', 123) --- - - [1, 123] ... -box.space.tweedledum:select(123) +box.space.tweedledum:get(123) --- - [123, 'test1', 'test2'] ... -box.space.tweedledum:select({123}) +box.space.tweedledum:get({123}) --- - [123, 'test1', 'test2'] ... +remote:call('box.space.tweedledum:get', 123) +--- +- - [123, 'test1', 'test2'] +... +remote:call('box.space.tweedledum:get', {123}) +--- +- - [123, 'test1', 'test2'] +... +box.space.tweedledum:select(123) +--- +- - [123, 'test1', 'test2'] +... +box.space.tweedledum:select({123}) +--- +- - [123, 'test1', 'test2'] +... remote:call('box.space.tweedledum:select', 123) --- - - [123, 'test1', 'test2'] @@ -179,18 +207,6 @@ type(foo) --- - table ... -tuple ---- -- [123, 'test1', 'test2'] -... -type(tuple) ---- -- cdata -... -#tuple ---- -- 3 -... space:update(123, {{'=', 1, 'test1-updated'}}) --- - [123, 'test1-updated', 'test2'] @@ -211,52 +227,88 @@ remote:insert(space.n, {345, 'test1', 'test2'}) --- - [345, 'test1', 'test2'] ... -remote:select(space.n, {345}) +remote:get(space.n, {345}) --- - [345, 'test1', 'test2'] ... +remote:select(space.n, {345}) +--- +- - [345, 'test1', 'test2'] +... remote:call('box.space.tweedledum:select', 345) --- - - [345, 'test1', 'test2'] ... -space:select{345} +space:get{345} --- - [345, 'test1', 'test2'] ... +space:select{345} +--- +- - [345, 'test1', 'test2'] +... +remote:put(space.n, {345, 'test1-replaced', 'test3-replaced'}) +--- +- [345, 'test1-replaced', 'test3-replaced'] +... +space:get{345} +--- +- [345, 'test1-replaced', 'test3-replaced'] +... +space:select{345} +--- +- - [345, 'test1-replaced', 'test3-replaced'] +... remote:replace(space.n, {345, 'test1-replaced', 'test2-replaced'}) --- - [345, 'test1-replaced', 'test2-replaced'] ... -space:select{345} +space:get{345} --- - [345, 'test1-replaced', 'test2-replaced'] ... -space:eselect({}, { iterator = 'GE', limit = 1000 }) +space:select{345} +--- +- - [345, 'test1-replaced', 'test2-replaced'] +... +space:select({}, { iterator = 'GE', limit = 1000 }) --- - - [123, 'test1-updated', 'test2-updated'] - [345, 'test1-replaced', 'test2-replaced'] ... -box.net.self:eselect(space.n, 0, {}, { iterator = 'GE', limit = 1000 }) +box.net.self:select(space.n, {}, { iterator = 'GE', limit = 1000 }) --- - - [123, 'test1-updated', 'test2-updated'] - [345, 'test1-replaced', 'test2-replaced'] ... -remote:eselect(space.n, 0, {}, { limit = 1000, iterator = 'GE' }) +remote:select(space.n, {}, { limit = 1000, iterator = 'GE' }) --- - - [123, 'test1-updated', 'test2-updated'] - [345, 'test1-replaced', 'test2-replaced'] ... +space:get{345} +--- +- [345, 'test1-replaced', 'test2-replaced'] +... space:select{345} --- +- - [345, 'test1-replaced', 'test2-replaced'] +... +remote:get(space.n, {345}) +--- - [345, 'test1-replaced', 'test2-replaced'] ... remote:select(space.n, {345}) --- +- - [345, 'test1-replaced', 'test2-replaced'] +... +remote:timeout(0.5):get(space.n, {345}) +--- - [345, 'test1-replaced', 'test2-replaced'] ... remote:timeout(0.5):select(space.n, {345}) --- -- [345, 'test1-replaced', 'test2-replaced'] +- - [345, 'test1-replaced', 'test2-replaced'] ... box.net.self:insert(space.n, {12345, 'test1', 'test2'}) --- @@ -356,11 +408,15 @@ box.time() - pstart < 0.5 --- - true ... -box.net.self.rpc.box.space.tweedledum.index.primary:select(12345) +box.net.self.rpc.box.space.tweedledum.index.primary:get(12345) --- - - [12345, 'test11', 'test2'] ... -remote.rpc.box.space.tweedledum.index.primary:eselect(12345) +box.net.self.rpc.box.space.tweedledum.index.primary:select(12345) +--- +- - - [12345, 'test11', 'test2'] +... +remote.rpc.box.space.tweedledum.index.primary:get(12345) --- - - [12345, 'test11', 'test2'] ... @@ -374,13 +430,16 @@ remote:close() ... remote:close() --- -- error: '[string "-- box_net.lua (internal file)..."]:506: box.net.box: already closed' +- error: '[string "-- box_net.lua (internal file)..."]:530: box.net.box: already closed' ... remote:ping() --- -- error: '[string "-- box_net.lua (internal file)..."]:511: box.net.box: connection +- error: '[string "-- box_net.lua (internal file)..."]:535: box.net.box: connection was closed' ... space:drop() --- ... +box.schema.user.revoke('guest', 'read,write,execute', 'universe') +--- +... diff --git a/test/box/net.box.test.lua b/test/box/net.box.test.lua index 67f30e898a1afa34c880576babb89d39febf2ff6..09e43a4d263dee17ee01c6fd3e0546df29e0bda3 100644 --- a/test/box/net.box.test.lua +++ b/test/box/net.box.test.lua @@ -1,5 +1,6 @@ space = box.schema.create_space('tweedledum') space:create_index('primary', { type = 'tree'}) +box.schema.user.grant('guest', 'read,write,execute', 'universe') remote = box.net.box.new('localhost', box.cfg.primary_port, '0.5') type(remote) remote:ping() @@ -7,7 +8,9 @@ remote:ping() box.net.box.ping(remote) space:insert{123, 'test1', 'test2'} space:select{123} -tuple = remote:select(space.n, 123) +space:get{123} +remote:select(space.n, 123) +remote:get(space.n, 123) function test(...) return box.tuple.new({ 123, 456 }) end f, a = box.call_loadproc('test') @@ -47,7 +50,10 @@ type(a) remote:call('test.a:b', 123) - +box.space.tweedledum:get(123) +box.space.tweedledum:get({123}) +remote:call('box.space.tweedledum:get', 123) +remote:call('box.space.tweedledum:get', {123}) box.space.tweedledum:select(123) box.space.tweedledum:select({123}) @@ -58,10 +64,6 @@ slf, foo = box.call_loadproc('box.net.self:select') type(slf) type(foo) -tuple -type(tuple) -#tuple - space:update(123, {{'=', 1, 'test1-updated'}}) remote:update(space.n, 123, {{'=', 2, 'test2-updated'}}) @@ -69,18 +71,28 @@ space:insert{123, 'test1', 'test2'} remote:insert(space.n, {123, 'test1', 'test2'}) remote:insert(space.n, {345, 'test1', 'test2'}) +remote:get(space.n, {345}) remote:select(space.n, {345}) remote:call('box.space.tweedledum:select', 345) +space:get{345} +space:select{345} + +remote:put(space.n, {345, 'test1-replaced', 'test3-replaced'}) +space:get{345} space:select{345} remote:replace(space.n, {345, 'test1-replaced', 'test2-replaced'}) +space:get{345} space:select{345} -space:eselect({}, { iterator = 'GE', limit = 1000 }) -box.net.self:eselect(space.n, 0, {}, { iterator = 'GE', limit = 1000 }) -remote:eselect(space.n, 0, {}, { limit = 1000, iterator = 'GE' }) +space:select({}, { iterator = 'GE', limit = 1000 }) +box.net.self:select(space.n, {}, { iterator = 'GE', limit = 1000 }) +remote:select(space.n, {}, { limit = 1000, iterator = 'GE' }) +space:get{345} space:select{345} +remote:get(space.n, {345}) remote:select(space.n, {345}) +remote:timeout(0.5):get(space.n, {345}) remote:timeout(0.5):select(space.n, {345}) @@ -128,8 +140,9 @@ box.time() - pstart < 0.5 +box.net.self.rpc.box.space.tweedledum.index.primary:get(12345) box.net.self.rpc.box.space.tweedledum.index.primary:select(12345) -remote.rpc.box.space.tweedledum.index.primary:eselect(12345) +remote.rpc.box.space.tweedledum.index.primary:get(12345) remote.rpc.box.space.tweedledum.index.primary:select(12345) remote:close() @@ -137,3 +150,4 @@ remote:close() remote:ping() space:drop() +box.schema.user.revoke('guest', 'read,write,execute', 'universe') diff --git a/test/box/on_replace.result b/test/box/on_replace.result index a3bf532ce2d639ef5b9fdb37f8a25ca561447482..3de8a9e9edc2f0e325116e016d017b02f12d165b 100644 --- a/test/box/on_replace.result +++ b/test/box/on_replace.result @@ -30,7 +30,7 @@ ts:insert{1, 'b', 'c'} --- - error: '[string "function fail(old_tuple, new_tuple) error(''te..."]:1: test' ... -ts:select{1} +ts:get{1} --- ... ts:on_replace(nil, fail) @@ -40,7 +40,7 @@ ts:insert{1, 'b', 'c'} --- - [1, 'b', 'c'] ... -ts:select{1} +ts:get{1} --- - [1, 'b', 'c'] ... @@ -54,7 +54,7 @@ ts:insert{2, 'b', 'c'} --- - error: '[string "function fail(old_tuple, new_tuple) error(''ab..."]:1: abc' ... -ts:select{2} +ts:get{2} --- ... function save_out(told, tnew) o = told n = tnew end diff --git a/test/box/on_replace.test.lua b/test/box/on_replace.test.lua index 329f7f112cc5bbdaf76bd8f9e0a34c1bb2366c12..6a79ba6337b24e237ffa776c9ed19ebaa0c5ef76 100644 --- a/test/box/on_replace.test.lua +++ b/test/box/on_replace.test.lua @@ -10,18 +10,18 @@ function fail(old_tuple, new_tuple) error('test') end ts:on_replace(fail) ts:insert{1, 'b', 'c'} -ts:select{1} +ts:get{1} ts:on_replace(nil, fail) ts:insert{1, 'b', 'c'} -ts:select{1} +ts:get{1} function fail(old_tuple, new_tuple) error('abc') end ts:on_replace(fail) ts:insert{2, 'b', 'c'} -ts:select{2} +ts:get{2} function save_out(told, tnew) o = told n = tnew end ts:on_replace(save_out, fail) diff --git a/test/box/panic_on_wal_error.cfg b/test/box/panic_on_wal_error.cfg index 282e51278bedd13073b58638163134bc11b3552d..ee68c9196e64946370b275f00e8dbd246fca48c4 100644 --- a/test/box/panic_on_wal_error.cfg +++ b/test/box/panic_on_wal_error.cfg @@ -22,11 +22,11 @@ logger="cat - >> tarantool.log" # # Read only and read-write port. -primary_port = 33013 +primary_port = 3301 # # The port for administrative commands. # -admin_port = 33015 +admin_port = 3313 # # Each write ahead log contains this many rows. # When the limit is reached, Tarantool closes diff --git a/test/box/schema.result b/test/box/schema.result index bdb2015badd93cc310c92ce75f90616944c8451a..ce6c600aa3c5dd794e7a796844e381bae56b54af 100644 --- a/test/box/schema.result +++ b/test/box/schema.result @@ -11,6 +11,7 @@ t --- - - 'temporary: false' - 'n: 0' + - 'engine: memtx' - 'enabled: true' - 'name: tweedledum' - 'arity: 0' diff --git a/test/box/select.result b/test/box/select.result index 9fa2ee70bf885bce9290d7cc81f149134b67d540..85a57e6171db7b36ed4401f9c25b9b98665d1f1a 100644 --- a/test/box/select.result +++ b/test/box/select.result @@ -1,16 +1,72 @@ -print('eselect') +s = box.schema.create_space('select', { temporary = true }) --- ... -s = box.schema.create_space('eselect', { temporary = true }) +index = s:create_index('primary', { type = 'tree' }) --- ... -index = s:create_index('primary', { type = 'tree' }) +s:create_index('second', { type = 'tree', unique = true, parts = {1, 'num', 0, 'num'}}) --- ... for i = 1, 20 do s:insert({ i, 1, 2, 3 }) end --- ... -s.index[0]:eselect(nil, { iterator = 'ALL', offset = 0, limit = 4294967295 }) +-------------------------------------------------------------------------------- +-- get tests +-------------------------------------------------------------------------------- +s.index[0]:get() +--- +- error: More than one tuple found by get() +... +s.index[0]:get({}) +--- +- error: More than one tuple found by get() +... +s.index[0]:get(nil) +--- +- error: More than one tuple found by get() +... +s.index[0]:get(1) +--- +- [1, 1, 2, 3] +... +s.index[0]:get({1}) +--- +- [1, 1, 2, 3] +... +s.index[0]:get({1, 2}) +--- +- error: Invalid key part count (expected [0..1], got 2) +... +s.index[0]:get(0) +--- +... +s.index[0]:get({0}) +--- +... +s.index[0]:get("0") +--- +- error: 'Supplied key type of part 0 does not match index part type: expected NUM' +... +s.index[0]:get({"0"}) +--- +- error: 'Supplied key type of part 0 does not match index part type: expected NUM' +... +s.index[1]:get(1) +--- +- error: More than one tuple found by get() +... +s.index[1]:get({1}) +--- +- error: More than one tuple found by get() +... +s.index[1]:get({1, 2}) +--- +- [2, 1, 2, 3] +... +-------------------------------------------------------------------------------- +-- select tests +-------------------------------------------------------------------------------- +s.index[0]:select() --- - - [1, 1, 2, 3] - [2, 1, 2, 3] @@ -33,7 +89,7 @@ s.index[0]:eselect(nil, { iterator = 'ALL', offset = 0, limit = 4294967295 }) - [19, 1, 2, 3] - [20, 1, 2, 3] ... -s.index[0]:eselect({}, { iterator = 'ALL', offset = 0, limit = 4294967295 }) +s.index[0]:select({}) --- - - [1, 1, 2, 3] - [2, 1, 2, 3] @@ -56,54 +112,428 @@ s.index[0]:eselect({}, { iterator = 'ALL', offset = 0, limit = 4294967295 }) - [19, 1, 2, 3] - [20, 1, 2, 3] ... -s.index[0]:eselect(1) +s.index[0]:select(nil) --- -- [1, 1, 2, 3] +- - [1, 1, 2, 3] + - [2, 1, 2, 3] + - [3, 1, 2, 3] + - [4, 1, 2, 3] + - [5, 1, 2, 3] + - [6, 1, 2, 3] + - [7, 1, 2, 3] + - [8, 1, 2, 3] + - [9, 1, 2, 3] + - [10, 1, 2, 3] + - [11, 1, 2, 3] + - [12, 1, 2, 3] + - [13, 1, 2, 3] + - [14, 1, 2, 3] + - [15, 1, 2, 3] + - [16, 1, 2, 3] + - [17, 1, 2, 3] + - [18, 1, 2, 3] + - [19, 1, 2, 3] + - [20, 1, 2, 3] ... -s.index[0]:eselect(1, { iterator = box.index.EQ }) +s.index[0]:select({}, {iterator = 'ALL'}) --- -- [1, 1, 2, 3] +- - [1, 1, 2, 3] + - [2, 1, 2, 3] + - [3, 1, 2, 3] + - [4, 1, 2, 3] + - [5, 1, 2, 3] + - [6, 1, 2, 3] + - [7, 1, 2, 3] + - [8, 1, 2, 3] + - [9, 1, 2, 3] + - [10, 1, 2, 3] + - [11, 1, 2, 3] + - [12, 1, 2, 3] + - [13, 1, 2, 3] + - [14, 1, 2, 3] + - [15, 1, 2, 3] + - [16, 1, 2, 3] + - [17, 1, 2, 3] + - [18, 1, 2, 3] + - [19, 1, 2, 3] + - [20, 1, 2, 3] ... -s.index[0]:eselect(1, { iterator = 'EQ' }) +s.index[0]:select(nil, {iterator = box.index.ALL }) --- -- [1, 1, 2, 3] +- - [1, 1, 2, 3] + - [2, 1, 2, 3] + - [3, 1, 2, 3] + - [4, 1, 2, 3] + - [5, 1, 2, 3] + - [6, 1, 2, 3] + - [7, 1, 2, 3] + - [8, 1, 2, 3] + - [9, 1, 2, 3] + - [10, 1, 2, 3] + - [11, 1, 2, 3] + - [12, 1, 2, 3] + - [13, 1, 2, 3] + - [14, 1, 2, 3] + - [15, 1, 2, 3] + - [16, 1, 2, 3] + - [17, 1, 2, 3] + - [18, 1, 2, 3] + - [19, 1, 2, 3] + - [20, 1, 2, 3] ... -s.index[0]:eselect(1, { iterator = 'GE' }) +s.index[0]:select({}, {iterator = box.index.ALL, limit = 10}) --- -- error: More than one tuple found without 'limit' +- - [1, 1, 2, 3] + - [2, 1, 2, 3] + - [3, 1, 2, 3] + - [4, 1, 2, 3] + - [5, 1, 2, 3] + - [6, 1, 2, 3] + - [7, 1, 2, 3] + - [8, 1, 2, 3] + - [9, 1, 2, 3] + - [10, 1, 2, 3] +... +s.index[0]:select(nil, {iterator = box.index.ALL, limit = 0}) +--- +- [] ... -s.index[0]:eselect(1, { iterator = 'GE', limit = 2 }) +s.index[0]:select({}, {iterator = 'ALL', limit = 1, offset = 15}) +--- +- - [16, 1, 2, 3] +... +s.index[0]:select(nil, {iterator = 'ALL', limit = 20, offset = 15}) +--- +- - [16, 1, 2, 3] + - [17, 1, 2, 3] + - [18, 1, 2, 3] + - [19, 1, 2, 3] + - [20, 1, 2, 3] +... +s.index[0]:select(nil, {iterator = box.index.EQ}) --- - - [1, 1, 2, 3] - [2, 1, 2, 3] + - [3, 1, 2, 3] + - [4, 1, 2, 3] + - [5, 1, 2, 3] + - [6, 1, 2, 3] + - [7, 1, 2, 3] + - [8, 1, 2, 3] + - [9, 1, 2, 3] + - [10, 1, 2, 3] + - [11, 1, 2, 3] + - [12, 1, 2, 3] + - [13, 1, 2, 3] + - [14, 1, 2, 3] + - [15, 1, 2, 3] + - [16, 1, 2, 3] + - [17, 1, 2, 3] + - [18, 1, 2, 3] + - [19, 1, 2, 3] + - [20, 1, 2, 3] ... -s.index[0]:eselect(1, { iterator = 'LE', limit = 2 }) +s.index[0]:select({}, {iterator = 'EQ'}) --- - - [1, 1, 2, 3] + - [2, 1, 2, 3] + - [3, 1, 2, 3] + - [4, 1, 2, 3] + - [5, 1, 2, 3] + - [6, 1, 2, 3] + - [7, 1, 2, 3] + - [8, 1, 2, 3] + - [9, 1, 2, 3] + - [10, 1, 2, 3] + - [11, 1, 2, 3] + - [12, 1, 2, 3] + - [13, 1, 2, 3] + - [14, 1, 2, 3] + - [15, 1, 2, 3] + - [16, 1, 2, 3] + - [17, 1, 2, 3] + - [18, 1, 2, 3] + - [19, 1, 2, 3] + - [20, 1, 2, 3] ... -s.index[0]:eselect(1, { iterator = 'GE', offset = 10, limit = 2 }) +s.index[0]:select(nil, {iterator = 'REQ'}) --- -- - [11, 1, 2, 3] +- - [20, 1, 2, 3] + - [19, 1, 2, 3] + - [18, 1, 2, 3] + - [17, 1, 2, 3] + - [16, 1, 2, 3] + - [15, 1, 2, 3] + - [14, 1, 2, 3] + - [13, 1, 2, 3] - [12, 1, 2, 3] + - [11, 1, 2, 3] + - [10, 1, 2, 3] + - [9, 1, 2, 3] + - [8, 1, 2, 3] + - [7, 1, 2, 3] + - [6, 1, 2, 3] + - [5, 1, 2, 3] + - [4, 1, 2, 3] + - [3, 1, 2, 3] + - [2, 1, 2, 3] + - [1, 1, 2, 3] +... +s.index[0]:select({}, {iterator = box.index.REQ}) +--- +- - [20, 1, 2, 3] + - [19, 1, 2, 3] + - [18, 1, 2, 3] + - [17, 1, 2, 3] + - [16, 1, 2, 3] + - [15, 1, 2, 3] + - [14, 1, 2, 3] + - [13, 1, 2, 3] + - [12, 1, 2, 3] + - [11, 1, 2, 3] + - [10, 1, 2, 3] + - [9, 1, 2, 3] + - [8, 1, 2, 3] + - [7, 1, 2, 3] + - [6, 1, 2, 3] + - [5, 1, 2, 3] + - [4, 1, 2, 3] + - [3, 1, 2, 3] + - [2, 1, 2, 3] + - [1, 1, 2, 3] ... -s.index[0]:eselect(1, { iterator = 'GE', grep = function(t) if math.fmod(t[0], 2) == 0 then return true end end, limit = 2 }) +s.index[0]:select(nil, {iterator = 'EQ', limit = 2, offset = 1}) --- - - [2, 1, 2, 3] + - [3, 1, 2, 3] +... +s.index[0]:select({}, {iterator = box.index.REQ, limit = 2, offset = 1}) +--- +- - [19, 1, 2, 3] + - [18, 1, 2, 3] +... +s.index[0]:select(1) +--- +- - [1, 1, 2, 3] +... +s.index[0]:select({1}) +--- +- - [1, 1, 2, 3] +... +s.index[0]:select({1, 2}) +--- +- error: Invalid key part count (expected [0..1], got 2) +... +s.index[0]:select(0) +--- +- [] +... +s.index[0]:select({0}) +--- +- [] +... +s.index[0]:select("0") +--- +- error: 'Supplied key type of part 0 does not match index part type: expected NUM' +... +s.index[0]:select({"0"}) +--- +- error: 'Supplied key type of part 0 does not match index part type: expected NUM' +... +s.index[1]:select(1) +--- +- - [1, 1, 2, 3] + - [2, 1, 2, 3] + - [3, 1, 2, 3] + - [4, 1, 2, 3] + - [5, 1, 2, 3] + - [6, 1, 2, 3] + - [7, 1, 2, 3] + - [8, 1, 2, 3] + - [9, 1, 2, 3] + - [10, 1, 2, 3] + - [11, 1, 2, 3] + - [12, 1, 2, 3] + - [13, 1, 2, 3] + - [14, 1, 2, 3] + - [15, 1, 2, 3] + - [16, 1, 2, 3] + - [17, 1, 2, 3] + - [18, 1, 2, 3] + - [19, 1, 2, 3] + - [20, 1, 2, 3] +... +s.index[1]:select({1}) +--- +- - [1, 1, 2, 3] + - [2, 1, 2, 3] + - [3, 1, 2, 3] - [4, 1, 2, 3] + - [5, 1, 2, 3] + - [6, 1, 2, 3] + - [7, 1, 2, 3] + - [8, 1, 2, 3] + - [9, 1, 2, 3] + - [10, 1, 2, 3] + - [11, 1, 2, 3] + - [12, 1, 2, 3] + - [13, 1, 2, 3] + - [14, 1, 2, 3] + - [15, 1, 2, 3] + - [16, 1, 2, 3] + - [17, 1, 2, 3] + - [18, 1, 2, 3] + - [19, 1, 2, 3] + - [20, 1, 2, 3] +... +s.index[1]:select({1}, {limit = 2}) +--- +- - [1, 1, 2, 3] + - [2, 1, 2, 3] ... -s.index[0]:eselect(1, { iterator = 'GE', grep = function(t) if math.fmod(t[0], 2) == 0 then return true end end, limit = 2, offset = 1 }) +s.index[1]:select(1, {iterator = 'EQ'}) +--- +- - [1, 1, 2, 3] + - [2, 1, 2, 3] + - [3, 1, 2, 3] + - [4, 1, 2, 3] + - [5, 1, 2, 3] + - [6, 1, 2, 3] + - [7, 1, 2, 3] + - [8, 1, 2, 3] + - [9, 1, 2, 3] + - [10, 1, 2, 3] + - [11, 1, 2, 3] + - [12, 1, 2, 3] + - [13, 1, 2, 3] + - [14, 1, 2, 3] + - [15, 1, 2, 3] + - [16, 1, 2, 3] + - [17, 1, 2, 3] + - [18, 1, 2, 3] + - [19, 1, 2, 3] + - [20, 1, 2, 3] +... +s.index[1]:select({1}, {iterator = box.index.EQ, offset = 16, limit = 2}) +--- +- - [17, 1, 2, 3] + - [18, 1, 2, 3] +... +s.index[1]:select({1}, {iterator = box.index.REQ, offset = 16, limit = 2 }) --- - - [4, 1, 2, 3] + - [3, 1, 2, 3] +... +s.index[1]:select({1, 2}, {iterator = 'EQ'}) +--- +- - [2, 1, 2, 3] +... +s.index[1]:select({1, 2}, {iterator = box.index.REQ}) +--- +- - [2, 1, 2, 3] +... +s.index[1]:select({1, 2}) +--- +- - [2, 1, 2, 3] +... +s.index[0]:select(nil, { iterator = 'ALL', offset = 0, limit = 4294967295 }) +--- +- - [1, 1, 2, 3] + - [2, 1, 2, 3] + - [3, 1, 2, 3] + - [4, 1, 2, 3] + - [5, 1, 2, 3] + - [6, 1, 2, 3] + - [7, 1, 2, 3] + - [8, 1, 2, 3] + - [9, 1, 2, 3] + - [10, 1, 2, 3] + - [11, 1, 2, 3] + - [12, 1, 2, 3] + - [13, 1, 2, 3] + - [14, 1, 2, 3] + - [15, 1, 2, 3] + - [16, 1, 2, 3] + - [17, 1, 2, 3] + - [18, 1, 2, 3] + - [19, 1, 2, 3] + - [20, 1, 2, 3] +... +s.index[0]:select({}, { iterator = 'ALL', offset = 0, limit = 4294967295 }) +--- +- - [1, 1, 2, 3] + - [2, 1, 2, 3] + - [3, 1, 2, 3] + - [4, 1, 2, 3] + - [5, 1, 2, 3] + - [6, 1, 2, 3] + - [7, 1, 2, 3] + - [8, 1, 2, 3] + - [9, 1, 2, 3] + - [10, 1, 2, 3] + - [11, 1, 2, 3] + - [12, 1, 2, 3] + - [13, 1, 2, 3] + - [14, 1, 2, 3] + - [15, 1, 2, 3] + - [16, 1, 2, 3] + - [17, 1, 2, 3] + - [18, 1, 2, 3] + - [19, 1, 2, 3] + - [20, 1, 2, 3] +... +s.index[0]:select(1) +--- +- - [1, 1, 2, 3] +... +s.index[0]:select(1, { iterator = box.index.EQ }) +--- +- - [1, 1, 2, 3] +... +s.index[0]:select(1, { iterator = 'EQ' }) +--- +- - [1, 1, 2, 3] +... +s.index[0]:select(1, { iterator = 'GE' }) +--- +- - [1, 1, 2, 3] + - [2, 1, 2, 3] + - [3, 1, 2, 3] + - [4, 1, 2, 3] + - [5, 1, 2, 3] - [6, 1, 2, 3] + - [7, 1, 2, 3] + - [8, 1, 2, 3] + - [9, 1, 2, 3] + - [10, 1, 2, 3] + - [11, 1, 2, 3] + - [12, 1, 2, 3] + - [13, 1, 2, 3] + - [14, 1, 2, 3] + - [15, 1, 2, 3] + - [16, 1, 2, 3] + - [17, 1, 2, 3] + - [18, 1, 2, 3] + - [19, 1, 2, 3] + - [20, 1, 2, 3] ... -s.index[0]:eselect(1, { iterator = 'GE', grep = function(t) if math.fmod(t[0], 2) == 0 then return true end end, limit = 2, offset = 1, map = function(t) return { t[0] } end }) +s.index[0]:select(1, { iterator = 'GE', limit = 2 }) --- -- - - 4 - - - 6 +- - [1, 1, 2, 3] + - [2, 1, 2, 3] ... -s:eselect(2) +s.index[0]:select(1, { iterator = 'LE', limit = 2 }) --- -- [2, 1, 2, 3] +- - [1, 1, 2, 3] +... +s.index[0]:select(1, { iterator = 'GE', offset = 10, limit = 2 }) +--- +- - [11, 1, 2, 3] + - [12, 1, 2, 3] +... +s:select(2) +--- +- - [2, 1, 2, 3] ... s:drop() --- diff --git a/test/box/select.test.lua b/test/box/select.test.lua index c94e25d74e5bd06f1a4d65d950b997f3b15f8833..b98a061d66d306cf477bf9929704f70d1075586c 100644 --- a/test/box/select.test.lua +++ b/test/box/select.test.lua @@ -1,27 +1,78 @@ -print('eselect') - -s = box.schema.create_space('eselect', { temporary = true }) +s = box.schema.create_space('select', { temporary = true }) index = s:create_index('primary', { type = 'tree' }) - +s:create_index('second', { type = 'tree', unique = true, parts = {1, 'num', 0, 'num'}}) for i = 1, 20 do s:insert({ i, 1, 2, 3 }) end +-------------------------------------------------------------------------------- +-- get tests +-------------------------------------------------------------------------------- + +s.index[0]:get() +s.index[0]:get({}) +s.index[0]:get(nil) +s.index[0]:get(1) +s.index[0]:get({1}) +s.index[0]:get({1, 2}) +s.index[0]:get(0) +s.index[0]:get({0}) +s.index[0]:get("0") +s.index[0]:get({"0"}) + +s.index[1]:get(1) +s.index[1]:get({1}) +s.index[1]:get({1, 2}) + +-------------------------------------------------------------------------------- +-- select tests +-------------------------------------------------------------------------------- + +s.index[0]:select() +s.index[0]:select({}) +s.index[0]:select(nil) +s.index[0]:select({}, {iterator = 'ALL'}) +s.index[0]:select(nil, {iterator = box.index.ALL }) +s.index[0]:select({}, {iterator = box.index.ALL, limit = 10}) +s.index[0]:select(nil, {iterator = box.index.ALL, limit = 0}) +s.index[0]:select({}, {iterator = 'ALL', limit = 1, offset = 15}) +s.index[0]:select(nil, {iterator = 'ALL', limit = 20, offset = 15}) + +s.index[0]:select(nil, {iterator = box.index.EQ}) +s.index[0]:select({}, {iterator = 'EQ'}) +s.index[0]:select(nil, {iterator = 'REQ'}) +s.index[0]:select({}, {iterator = box.index.REQ}) + +s.index[0]:select(nil, {iterator = 'EQ', limit = 2, offset = 1}) +s.index[0]:select({}, {iterator = box.index.REQ, limit = 2, offset = 1}) -s.index[0]:eselect(nil, { iterator = 'ALL', offset = 0, limit = 4294967295 }) -s.index[0]:eselect({}, { iterator = 'ALL', offset = 0, limit = 4294967295 }) +s.index[0]:select(1) +s.index[0]:select({1}) +s.index[0]:select({1, 2}) +s.index[0]:select(0) +s.index[0]:select({0}) +s.index[0]:select("0") +s.index[0]:select({"0"}) -s.index[0]:eselect(1) -s.index[0]:eselect(1, { iterator = box.index.EQ }) -s.index[0]:eselect(1, { iterator = 'EQ' }) -s.index[0]:eselect(1, { iterator = 'GE' }) -s.index[0]:eselect(1, { iterator = 'GE', limit = 2 }) -s.index[0]:eselect(1, { iterator = 'LE', limit = 2 }) -s.index[0]:eselect(1, { iterator = 'GE', offset = 10, limit = 2 }) +s.index[1]:select(1) +s.index[1]:select({1}) +s.index[1]:select({1}, {limit = 2}) +s.index[1]:select(1, {iterator = 'EQ'}) +s.index[1]:select({1}, {iterator = box.index.EQ, offset = 16, limit = 2}) +s.index[1]:select({1}, {iterator = box.index.REQ, offset = 16, limit = 2 }) +s.index[1]:select({1, 2}, {iterator = 'EQ'}) +s.index[1]:select({1, 2}, {iterator = box.index.REQ}) +s.index[1]:select({1, 2}) -s.index[0]:eselect(1, { iterator = 'GE', grep = function(t) if math.fmod(t[0], 2) == 0 then return true end end, limit = 2 }) -s.index[0]:eselect(1, { iterator = 'GE', grep = function(t) if math.fmod(t[0], 2) == 0 then return true end end, limit = 2, offset = 1 }) -s.index[0]:eselect(1, { iterator = 'GE', grep = function(t) if math.fmod(t[0], 2) == 0 then return true end end, limit = 2, offset = 1, map = function(t) return { t[0] } end }) +s.index[0]:select(nil, { iterator = 'ALL', offset = 0, limit = 4294967295 }) +s.index[0]:select({}, { iterator = 'ALL', offset = 0, limit = 4294967295 }) +s.index[0]:select(1) +s.index[0]:select(1, { iterator = box.index.EQ }) +s.index[0]:select(1, { iterator = 'EQ' }) +s.index[0]:select(1, { iterator = 'GE' }) +s.index[0]:select(1, { iterator = 'GE', limit = 2 }) +s.index[0]:select(1, { iterator = 'LE', limit = 2 }) +s.index[0]:select(1, { iterator = 'GE', offset = 10, limit = 2 }) -s:eselect(2) +s:select(2) s:drop() diff --git a/test/box/session.result b/test/box/session.result index 7894e39af5d8d14ecb3bb451bc260d748b147e54..4678a1ddccfd54e02443d6cbfe905f1bd9c7ba59 100644 --- a/test/box/session.result +++ b/test/box/session.result @@ -166,7 +166,7 @@ box.session.on_disconnect(audit_disconnect) ... --# create connection con_three to default --# set connection con_three -space:select{box.session.id()}[0] == box.session.id() +space:get{box.session.id()}[0] == box.session.id() --- - true ... @@ -186,3 +186,11 @@ active_connections space:drop() --- ... +box.session.uid() +--- +- 1 +... +box.session.user() +--- +- admin +... diff --git a/test/box/session.test.lua b/test/box/session.test.lua index aaed261cbbf39b6b919ead798e434c6c2a6f4501..f5b5111edce8e9012f2276636634eaa66fc834cd 100644 --- a/test/box/session.test.lua +++ b/test/box/session.test.lua @@ -69,7 +69,7 @@ box.session.on_disconnect(audit_disconnect) --# create connection con_three to default --# set connection con_three -space:select{box.session.id()}[0] == box.session.id() +space:get{box.session.id()}[0] == box.session.id() --# set connection default --# drop connection con_three @@ -79,3 +79,6 @@ box.session.on_disconnect(nil, audit_disconnect) active_connections space:drop() + +box.session.uid() +box.session.user() diff --git a/test/box/snap_io_rate_limit.cfg b/test/box/snap_io_rate_limit.cfg index 60a7a7ad2e3768b51868121e74e84fd132878a4a..e26b5054e8fe1466c55f2e7ed7e94f00bede49ba 100644 --- a/test/box/snap_io_rate_limit.cfg +++ b/test/box/snap_io_rate_limit.cfg @@ -6,8 +6,8 @@ pid_file = "box.pid" logger="cat - >> tarantool.log" -primary_port = 33013 -admin_port = 33015 +primary_port = 3301 +admin_port = 3313 rows_per_wal = 50 too_long_threshold=2 diff --git a/test/box/socket.result b/test/box/socket.result index 82b40765dc925d19e9a12f2df7db1da48f623535..4637fcc3b630f0a1353e205f75528c0cc8480dc6 100644 --- a/test/box/socket.result +++ b/test/box/socket.result @@ -899,7 +899,7 @@ ping s:close() --- ... - replies = 0 packet = msgpack.encode({[0] = 64, [1] = 0}) packet = msgpack.encode(packet:len())..packet function bug1160869() local s = box.socket.tcp() s:connect('127.0.0.1', box.cfg.primary_port) box.fiber.resume( box.fiber.create(function() box.fiber.detach() while true do _, status = s:recv(18) if status == "eof" then error("unexpected eof") end replies = replies + 1 end end) ) return s:send(packet) end + replies = 0 packet = msgpack.encode({[0] = 64, [1] = 0}) packet = msgpack.encode(packet:len())..packet function bug1160869() local s = box.socket.tcp() s:connect('127.0.0.1', box.cfg.primary_port) s:recv(128) box.fiber.resume( box.fiber.create(function() box.fiber.detach() while true do _, status = s:recv(18) if status == "eof" then error("unexpected eof") end replies = replies + 1 end end) ) return s:send(packet) end --- ... bug1160869() @@ -921,7 +921,7 @@ replies --- - 3 ... - s = nil syncno = 0 reps = 0 packet = msgpack.encode({[0] = 64, [1] = 0}) packet = msgpack.encode(packet:len())..packet function iostart() if s ~= nil then return end s = box.socket.tcp() s:connect('127.0.0.1', box.cfg.primary_port) box.fiber.resume( box.fiber.create(function() box.fiber.detach() while true do s:recv(18) if status == "eof" then error("unexpected eof") end reps = reps + 1 end end)) end function iotest() iostart() syncno = syncno + 1 packet = msgpack.encode({[0] = 64, [1] = syncno}) packet = msgpack.encode(packet:len())..packet return s:send(packet) end + s = nil syncno = 0 reps = 0 packet = msgpack.encode({[0] = 64, [1] = 0}) packet = msgpack.encode(packet:len())..packet function iostart() if s ~= nil then return end s = box.socket.tcp() s:connect('127.0.0.1', box.cfg.primary_port) s:recv(128) box.fiber.resume( box.fiber.create(function() box.fiber.detach() while true do s:recv(18) if status == "eof" then error("unexpected eof") end reps = reps + 1 end end)) end function iotest() iostart() syncno = syncno + 1 packet = msgpack.encode({[0] = 64, [1] = syncno}) packet = msgpack.encode(packet:len())..packet return s:send(packet) end --- ... iotest() @@ -946,7 +946,7 @@ reps test_listen_done = false --- ... - function server() ms = box.socket.tcp() ms:bind('127.0.0.1', 8181) ms:listen() test_listen_done = true while true do local s = ms:accept( .5 ) if s ~= 'timeout' then print("accepted connection ", s) s:send('Hello world') s:shutdown(box.socket.SHUT_RDWR) end end end fbr = box.fiber.wrap(server) + function server() ms = box.socket.tcp() ms:bind('127.0.0.1', 8181) ms:listen() test_listen_done = true while true do local s = ms:accept( .5 ) if s ~= 'timeout' then print("accepted connection ", s) s:send('Hello world') s:shutdown(box.socket.SHUT_RDWR) end end end fbr = box.fiber.wrap(server) --- ... wait_cout = 100 while not test_listen_done and wait_cout > 0 do box.fiber.sleep(0.001) wait_cout = wait_cout - 1 end diff --git a/test/box/socket.test.py b/test/box/socket.test.py index c5862682e82378c577ebe9d9a5f28e7dae6ae76d..0b86dd8553fbbfb3672a7d13bcbd511851fa288c 100644 --- a/test/box/socket.test.py +++ b/test/box/socket.test.py @@ -514,19 +514,20 @@ replies = 0 packet = msgpack.encode({[0] = 64, [1] = 0}) packet = msgpack.encode(packet:len())..packet function bug1160869() - local s = box.socket.tcp() - s:connect('127.0.0.1', box.cfg.primary_port) - box.fiber.resume( box.fiber.create(function() - box.fiber.detach() - while true do - _, status = s:recv(18) + local s = box.socket.tcp() + s:connect('127.0.0.1', box.cfg.primary_port) + s:recv(128) + box.fiber.resume( box.fiber.create(function() + box.fiber.detach() + while true do + _, status = s:recv(18) if status == "eof" then error("unexpected eof") end - replies = replies + 1 - end - end) ) - return s:send(packet) + replies = replies + 1 + end + end) ) + return s:send(packet) end """ admin(test.replace('\n', ' ')) @@ -544,29 +545,30 @@ reps = 0 packet = msgpack.encode({[0] = 64, [1] = 0}) packet = msgpack.encode(packet:len())..packet function iostart() - if s ~= nil then - return - end - s = box.socket.tcp() - s:connect('127.0.0.1', box.cfg.primary_port) - box.fiber.resume( box.fiber.create(function() - box.fiber.detach() - while true do - s:recv(18) + if s ~= nil then + return + end + s = box.socket.tcp() + s:connect('127.0.0.1', box.cfg.primary_port) + s:recv(128) + box.fiber.resume( box.fiber.create(function() + box.fiber.detach() + while true do + s:recv(18) if status == "eof" then error("unexpected eof") end - reps = reps + 1 - end - end)) + reps = reps + 1 + end + end)) end function iotest() - iostart() - syncno = syncno + 1 + iostart() + syncno = syncno + 1 packet = msgpack.encode({[0] = 64, [1] = syncno}) packet = msgpack.encode(packet:len())..packet - return s:send(packet) + return s:send(packet) end """ admin(test.replace('\n', ' ')) @@ -582,19 +584,19 @@ admin("reps") # test=""" function server() - ms = box.socket.tcp() - ms:bind('127.0.0.1', 8181) - ms:listen() - test_listen_done = true - - while true do - local s = ms:accept( .5 ) - if s ~= 'timeout' then - print("accepted connection ", s) - s:send('Hello world') - s:shutdown(box.socket.SHUT_RDWR) - end - end + ms = box.socket.tcp() + ms:bind('127.0.0.1', 8181) + ms:listen() + test_listen_done = true + + while true do + local s = ms:accept( .5 ) + if s ~= 'timeout' then + print("accepted connection ", s) + s:send('Hello world') + s:shutdown(box.socket.SHUT_RDWR) + end + end end fbr = box.fiber.wrap(server) diff --git a/test/box/sql.result b/test/box/sql.result index ef1e79a47b07d601776c51d5d39611c0d88ebc8b..764055da360e41705bd97128c0b21b94c28de046 100644 --- a/test/box/sql.result +++ b/test/box/sql.result @@ -1,7 +1,22 @@ -space = box.schema.create_space('tweedledum', { id = 0 }) +function f() box.schema.create_space('test', { id = 0 }) end --- ... -space:create_index('primary', { type = 'hash' }) +box.schema.user.create('test', { password = 'test' }) +--- +... +box.schema.func.create('f') +--- +... +box.schema.user.grant('test', 'Write', 'space', '_space') +--- +... +box.schema.user.grant('test', 'Execute', 'function', 'f') +--- +... +call f() +--- +... +box.space.test:create_index('primary', { type = 'hash' }) --- ... ping @@ -170,6 +185,9 @@ select * from t4294967295 where k0 = 0 box.space[0]:drop() --- ... +box.schema.user.drop('test') +--- +... # # A test case for: http://bugs.launchpad.net/bugs/716683 # Admin console should not stall on unknown command. diff --git a/test/box/sql.test.py b/test/box/sql.test.py index 19af93c2cc93779d415d62692f92f7601e79239b..77a7698a70a1c974c4be19efa2beb2bdd3014e6b 100644 --- a/test/box/sql.test.py +++ b/test/box/sql.test.py @@ -1,19 +1,14 @@ import tarantool -sql.set_schema({ - 0 : { - 'default_type': tarantool.STR, - 'fields' : { - 0 : tarantool.NUM, - 1 : tarantool.STR - }, - 'indexes': { - 0 : [0] # HASH - } - } -}) -admin("space = box.schema.create_space('tweedledum', { id = 0 })") -admin("space:create_index('primary', { type = 'hash' })") +admin("function f() box.schema.create_space('test', { id = 0 }) end") +admin("box.schema.user.create('test', { password = 'test' })") +admin("box.schema.func.create('f')") +admin("box.schema.user.grant('test', 'Write', 'space', '_space')") +admin("box.schema.user.grant('test', 'Execute', 'function', 'f')") +sql.authenticate('test', 'test') +# call from sql to have the right owner +sql("call f()") +admin("box.space.test:create_index('primary', { type = 'hash' })") sql("ping") # xxx: bug -- currently selects no rows sql("select * from t0") @@ -73,6 +68,7 @@ sql("select * from t1 where k0 = 0") sql("select * from t65537 where k0 = 0") sql("select * from t4294967295 where k0 = 0") admin("box.space[0]:drop()") +admin("box.schema.user.drop('test')") print """# # A test case for: http://bugs.launchpad.net/bugs/716683 diff --git a/test/box/stat.result b/test/box/stat.result index 809b150120014f502a471c6e74f7453278c6bcbd..a6bf3953ff026edc5174c2423131a02277a821a3 100644 --- a/test/box/stat.result +++ b/test/box/stat.result @@ -18,7 +18,7 @@ box.stat() total: 0 rps: 0 SELECT: - total: 0 + total: 1 rps: 0 REPLACE: total: 0 diff --git a/test/box/tarantool.cfg b/test/box/tarantool.cfg index 7afb21ed0571ef7cc3bb89cf5617c1001284116b..66a06d4ec41d47846616726553db4413914b6ee3 100644 --- a/test/box/tarantool.cfg +++ b/test/box/tarantool.cfg @@ -22,11 +22,11 @@ logger="cat - >> tarantool.log" # # Read only and read-write port. -primary_port = 33013 +primary_port = 3301 # # The port for administrative commands. # -admin_port = 33015 +admin_port = 3313 # # Each write ahead log contains this many rows. # When the limit is reached, Tarantool closes diff --git a/test/box/tarantool_bug750658.cfg b/test/box/tarantool_bug750658.cfg index bbdd3b7bc2c0e3ffb38128d2cc2b6ccace6f6a72..620382930eda65504967833c00795337c09332d0 100644 --- a/test/box/tarantool_bug750658.cfg +++ b/test/box/tarantool_bug750658.cfg @@ -17,11 +17,11 @@ pid_file = "box.pid" # # Read only and read-write port. -primary_port = 33013 +primary_port = 3301 # # The port for administrative commands. # -admin_port = 33015 +admin_port = 3313 # # Each write ahead log contains this many rows. # When the limit is reached, Tarantool closes diff --git a/test/box/tarantool_bug876541.cfg b/test/box/tarantool_bug876541.cfg index f18e0005aa0ac907503b751a592cea19ef50ae0d..f9bf9cade0e76273fdfcc9fc11923c08f79b81bc 100644 --- a/test/box/tarantool_bug876541.cfg +++ b/test/box/tarantool_bug876541.cfg @@ -4,8 +4,8 @@ pid_file = "box.pid" logger="cat - >> tarantool.log" -primary_port = 33013 -admin_port = 33015 +primary_port = 3301 +admin_port = 3313 rows_per_wal = 50 diff --git a/test/box/tarantool_bug_gh-99.cfg b/test/box/tarantool_bug_gh-99.cfg index d6e503acbca59ff9eef35cbe5404dca677bce4fe..93f140e80498b3b10db6485f9368d980c8e22c59 100644 --- a/test/box/tarantool_bug_gh-99.cfg +++ b/test/box/tarantool_bug_gh-99.cfg @@ -4,8 +4,8 @@ pid_file = "box.pid" logger="cat - >> tarantool.log" -primary_port = 33013 -admin_port = 33015 +primary_port = 3301 +admin_port = 3313 rows_per_wal = 50 diff --git a/test/box/tarantool_bug_gh100.cfg b/test/box/tarantool_bug_gh100.cfg index 14ed949ee0c60cd45fa9baca66e9142efd0fb5b9..2b6e6742b1d5a89a9fc53c085617b822c19dec42 100644 --- a/test/box/tarantool_bug_gh100.cfg +++ b/test/box/tarantool_bug_gh100.cfg @@ -4,8 +4,8 @@ pid_file = "box.pid" logger="cat - >> tarantool.log" -primary_port = 33013 -admin_port = 33015 +primary_port = 3301 +admin_port = 3313 # Invalid value rows_per_wal = 0 diff --git a/test/box/tarantool_good.cfg b/test/box/tarantool_good.cfg index e969a0bf548dfafd2278001a0b0aa072177df596..31118a9eb638e7475cf103bb88cfce55c6478c44 100644 --- a/test/box/tarantool_good.cfg +++ b/test/box/tarantool_good.cfg @@ -4,8 +4,8 @@ pid_file = "box.pid" logger="cat - >> tarantool.log" -primary_port = 33013 -admin_port = 33015 +primary_port = 3301 +admin_port = 3313 rows_per_wal = 50 # These are modifiable settings, change them. diff --git a/test/box/tarantool_scriptdir.cfg b/test/box/tarantool_scriptdir.cfg index 7afb21ed0571ef7cc3bb89cf5617c1001284116b..66a06d4ec41d47846616726553db4413914b6ee3 100644 --- a/test/box/tarantool_scriptdir.cfg +++ b/test/box/tarantool_scriptdir.cfg @@ -22,11 +22,11 @@ logger="cat - >> tarantool.log" # # Read only and read-write port. -primary_port = 33013 +primary_port = 3301 # # The port for administrative commands. # -admin_port = 33015 +admin_port = 3313 # # Each write ahead log contains this many rows. # When the limit is reached, Tarantool closes diff --git a/test/box/tarantool_with_cpt.cfg b/test/box/tarantool_with_cpt.cfg index 13be2ee89fb6df772d3045fd94fcec8b80a0da87..eb5ac706990490b914534e6a5d3088ca808e253c 100644 --- a/test/box/tarantool_with_cpt.cfg +++ b/test/box/tarantool_with_cpt.cfg @@ -6,8 +6,8 @@ pid_file = "box.pid" logger="cat - >> tarantool.log" -primary_port = 33013 -admin_port = 33015 +primary_port = 3301 +admin_port = 3313 rows_per_wal = 50 # These are modifiable settings, change them. diff --git a/test/box/tarantool_wo_cpt.cfg b/test/box/tarantool_wo_cpt.cfg index b5fc1cb0e4ea68e0450ebc1946888cb002e851a6..dd089b992037868661d44d1e79b496f4fcc93d78 100644 --- a/test/box/tarantool_wo_cpt.cfg +++ b/test/box/tarantool_wo_cpt.cfg @@ -5,8 +5,8 @@ pid_file = "box.pid" logger="cat - >> tarantool.log" -primary_port = 33013 -admin_port = 33015 +primary_port = 3301 +admin_port = 3313 rows_per_wal = 50 # These are modifiable settings, change them. diff --git a/test/box/temp_spaces.result b/test/box/temp_spaces.result index 0b4af59995369eeb4fe5297cb3b72d80c36b28f6..41b8ca4e187853cb1b80b673349a331320779b82 100644 --- a/test/box/temp_spaces.result +++ b/test/box/temp_spaces.result @@ -1,5 +1,8 @@ -- temporary spaces -- not a temporary +FLAGS = 5 +--- +... s = box.schema.create_space('t', { temporary = true }) --- ... @@ -42,7 +45,7 @@ s:insert{1, 2, 3} --- - [1, 2, 3] ... -s:select{1} +s:get{1} --- - [1, 2, 3] ... @@ -50,16 +53,19 @@ s:len() --- - 1 ... -box.space[box.schema.SPACE_ID]:update(s.n, {{'=', 3, 'temporary'}}) +box.space[box.schema.SPACE_ID]:update(s.n, {{'=', FLAGS, 'temporary'}}) --- -- [512, 0, 't', 'temporary'] +- [512, 1, 't', 'memtx', 0, 'temporary'] ... -box.space[box.schema.SPACE_ID]:update(s.n, {{'=', 3, ''}}) +box.space[box.schema.SPACE_ID]:update(s.n, {{'=', FLAGS, ''}}) --- - error: 'Can''t modify space 512: can not switch temporary flag on a non-empty space' ... --# stop server default --# start server default +FLAGS = 5 +--- +... s = box.space.t --- ... @@ -71,50 +77,50 @@ s.temporary --- - true ... -box.space[box.schema.SPACE_ID]:update(s.n, {{'=', 3, 'no-temporary'}}) +box.space[box.schema.SPACE_ID]:update(s.n, {{'=', FLAGS, 'no-temporary'}}) --- -- [512, 0, 't', 'no-temporary'] +- [512, 1, 't', 'memtx', 0, 'no-temporary'] ... s.temporary --- - false ... -box.space[box.schema.SPACE_ID]:update(s.n, {{'=', 3, ',:asfda:temporary'}}) +box.space[box.schema.SPACE_ID]:update(s.n, {{'=', FLAGS, ',:asfda:temporary'}}) --- -- [512, 0, 't', ',:asfda:temporary'] +- [512, 1, 't', 'memtx', 0, ',:asfda:temporary'] ... s.temporary --- - false ... -box.space[box.schema.SPACE_ID]:update(s.n, {{'=', 3, 'a,b,c,d,e'}}) +box.space[box.schema.SPACE_ID]:update(s.n, {{'=', FLAGS, 'a,b,c,d,e'}}) --- -- [512, 0, 't', 'a,b,c,d,e'] +- [512, 1, 't', 'memtx', 0, 'a,b,c,d,e'] ... s.temporary --- - false ... -box.space[box.schema.SPACE_ID]:update(s.n, {{'=', 3, 'temporary'}}) +box.space[box.schema.SPACE_ID]:update(s.n, {{'=', FLAGS, 'temporary'}}) --- -- [512, 0, 't', 'temporary'] +- [512, 1, 't', 'memtx', 0, 'temporary'] ... s.temporary --- - true ... -s:select{1} +s:get{1} --- ... s:insert{1, 2, 3} --- - [1, 2, 3] ... -box.space[box.schema.SPACE_ID]:update(s.n, {{'=', 3, 'temporary'}}) +box.space[box.schema.SPACE_ID]:update(s.n, {{'=', FLAGS, 'temporary'}}) --- -- [512, 0, 't', 'temporary'] +- [512, 1, 't', 'memtx', 0, 'temporary'] ... -box.space[box.schema.SPACE_ID]:update(s.n, {{'=', 3, 'no-temporary'}}) +box.space[box.schema.SPACE_ID]:update(s.n, {{'=', FLAGS, 'no-temporary'}}) --- - error: 'Can''t modify space 512: can not switch temporary flag on a non-empty space' ... @@ -122,9 +128,9 @@ s:delete{1} --- - [1, 2, 3] ... -box.space[box.schema.SPACE_ID]:update(s.n, {{'=', 3, 'no-temporary'}}) +box.space[box.schema.SPACE_ID]:update(s.n, {{'=', FLAGS, 'no-temporary'}}) --- -- [512, 0, 't', 'no-temporary'] +- [512, 1, 't', 'memtx', 0, 'no-temporary'] ... s:drop() --- diff --git a/test/box/temp_spaces.test.lua b/test/box/temp_spaces.test.lua index 348962c75d64aef02dfb552bf7fa68ff2946e059..194f2eff8b4ab6152587030d92900ebf35697e91 100644 --- a/test/box/temp_spaces.test.lua +++ b/test/box/temp_spaces.test.lua @@ -1,5 +1,6 @@ -- temporary spaces -- not a temporary +FLAGS = 5 s = box.schema.create_space('t', { temporary = true }) s.temporary s:drop() @@ -18,34 +19,35 @@ s = box.schema.create_space('t', { temporary = true }) s:create_index('primary', { type = 'hash' }) s:insert{1, 2, 3} -s:select{1} +s:get{1} s:len() -box.space[box.schema.SPACE_ID]:update(s.n, {{'=', 3, 'temporary'}}) -box.space[box.schema.SPACE_ID]:update(s.n, {{'=', 3, ''}}) +box.space[box.schema.SPACE_ID]:update(s.n, {{'=', FLAGS, 'temporary'}}) +box.space[box.schema.SPACE_ID]:update(s.n, {{'=', FLAGS, ''}}) --# stop server default --# start server default +FLAGS = 5 s = box.space.t s:len() s.temporary -box.space[box.schema.SPACE_ID]:update(s.n, {{'=', 3, 'no-temporary'}}) +box.space[box.schema.SPACE_ID]:update(s.n, {{'=', FLAGS, 'no-temporary'}}) s.temporary -box.space[box.schema.SPACE_ID]:update(s.n, {{'=', 3, ',:asfda:temporary'}}) +box.space[box.schema.SPACE_ID]:update(s.n, {{'=', FLAGS, ',:asfda:temporary'}}) s.temporary -box.space[box.schema.SPACE_ID]:update(s.n, {{'=', 3, 'a,b,c,d,e'}}) +box.space[box.schema.SPACE_ID]:update(s.n, {{'=', FLAGS, 'a,b,c,d,e'}}) s.temporary -box.space[box.schema.SPACE_ID]:update(s.n, {{'=', 3, 'temporary'}}) +box.space[box.schema.SPACE_ID]:update(s.n, {{'=', FLAGS, 'temporary'}}) s.temporary -s:select{1} +s:get{1} s:insert{1, 2, 3} -box.space[box.schema.SPACE_ID]:update(s.n, {{'=', 3, 'temporary'}}) -box.space[box.schema.SPACE_ID]:update(s.n, {{'=', 3, 'no-temporary'}}) +box.space[box.schema.SPACE_ID]:update(s.n, {{'=', FLAGS, 'temporary'}}) +box.space[box.schema.SPACE_ID]:update(s.n, {{'=', FLAGS, 'no-temporary'}}) s:delete{1} -box.space[box.schema.SPACE_ID]:update(s.n, {{'=', 3, 'no-temporary'}}) +box.space[box.schema.SPACE_ID]:update(s.n, {{'=', FLAGS, 'no-temporary'}}) s:drop() diff --git a/test/box/tuple.result b/test/box/tuple.result index c4d644269499101fdbed5afb21411a268cfaa3b9..080270e1110ff4f5cedeaad025dfe59d01c56a94 100644 --- a/test/box/tuple.result +++ b/test/box/tuple.result @@ -282,7 +282,7 @@ space:replace{777, { 'a', 'b', 'c', {'d', 'e', t}}} - [777, ['a', 'b', 'c', ['d', 'e', [0, 777, '0', '1', '2', '3']]]] ... -- A test case for tuple:totable() method -t=space:select{777}:totable() +t=space:get{777}:totable() --- ... t[2], t[3], t[4], t[5] @@ -377,15 +377,15 @@ t:next(3) ... t:next(4) --- -- error: '[string "-- tuple.lua (internal file)..."]:65: error: invalid key to ''next''' +- error: '[string "-- tuple.lua (internal file)..."]:69: error: invalid key to ''next''' ... t:next(-1) --- -- error: '[string "-- tuple.lua (internal file)..."]:65: error: invalid key to ''next''' +- error: '[string "-- tuple.lua (internal file)..."]:69: error: invalid key to ''next''' ... t:next("fdsaf") --- -- error: '[string "-- tuple.lua (internal file)..."]:48: error: invalid key to ''next''' +- error: '[string "-- tuple.lua (internal file)..."]:52: error: invalid key to ''next''' ... box.tuple.new({'x', 'y', 'z'}):next() --- @@ -397,7 +397,7 @@ t=space:insert{1953719668} ... t:next(1684234849) --- -- error: '[string "-- tuple.lua (internal file)..."]:65: error: invalid key to ''next''' +- error: '[string "-- tuple.lua (internal file)..."]:69: error: invalid key to ''next''' ... t:next(1) --- @@ -466,7 +466,8 @@ gen, init, state = t:pairs() ... gen, init, state --- -- <tuple iterator> +- gen: <tuple iterator> + param: ['a', 'b', 'c'] - ['a', 'b', 'c'] - null ... @@ -552,7 +553,7 @@ r = {} ... for _state, val in t:pairs(10) do table.insert(r, val) end --- -- error: '[string "-- tuple.lua (internal file)..."]:65: error: invalid key to ''next''' +- error: '[string "-- tuple.lua (internal file)..."]:69: error: invalid key to ''next''' ... r --- @@ -572,16 +573,68 @@ r ... t:pairs(nil) --- -- <tuple iterator> +- gen: <tuple iterator> + param: ['a', 'b', 'c'] - ['a', 'b', 'c'] - null ... t:pairs("fdsaf") --- -- <tuple iterator> +- state: fdsaf + gen: <tuple iterator> + param: ['a', 'b', 'c'] - ['a', 'b', 'c'] - fdsaf ... +-------------------------------------------------------------------------------- +-- test msgpack.encode + tuple +-------------------------------------------------------------------------------- +msgpackffi = require('msgpackffi') +--- +... +t = box.tuple.new({'a', 'b', 'c'}) +--- +... +msgpack.decode(msgpackffi.encode(t)) +--- +- - a + - b + - c +- 8 +... +msgpack.decode(msgpack.encode(t)) +--- +- - a + - b + - c +- 8 +... +msgpack.decode(msgpackffi.encode({1, {'x', 'y', t, 'z'}, 2, 3})) +--- +- - 1 + - - x + - y + - - a + - b + - c + - z + - 2 + - 3 +- 19 +... +msgpack.decode(msgpack.encode({1, {'x', 'y', t, 'z'}, 2, 3})) +--- +- - 1 + - - x + - y + - - a + - b + - c + - z + - 2 + - 3 +- 19 +... space:drop() --- ... diff --git a/test/box/tuple.test.lua b/test/box/tuple.test.lua index e2d0912067177bf31afcbe685993815dbbcb339e..1714e4ef2434275d0adcaa6a2ab7900343baa4fe 100644 --- a/test/box/tuple.test.lua +++ b/test/box/tuple.test.lua @@ -88,7 +88,7 @@ t space:replace(t) space:replace{777, { 'a', 'b', 'c', {'d', 'e', t}}} -- A test case for tuple:totable() method -t=space:select{777}:totable() +t=space:get{777}:totable() t[2], t[3], t[4], t[5] space:truncate() -- A test case for Bug#1119389 '(lbox_tuple_index) crashes on 'nil' argument' @@ -180,4 +180,16 @@ r t:pairs(nil) t:pairs("fdsaf") +-------------------------------------------------------------------------------- +-- test msgpack.encode + tuple +-------------------------------------------------------------------------------- + +msgpackffi = require('msgpackffi') + +t = box.tuple.new({'a', 'b', 'c'}) +msgpack.decode(msgpackffi.encode(t)) +msgpack.decode(msgpack.encode(t)) +msgpack.decode(msgpackffi.encode({1, {'x', 'y', t, 'z'}, 2, 3})) +msgpack.decode(msgpack.encode({1, {'x', 'y', t, 'z'}, 2, 3})) + space:drop() diff --git a/test/box/xlog.result b/test/box/xlog.result index d59b95353febf6a4fb9c2ae1a360c82edd1728b7..ad4de5f8ec3b26afc3ea2ad5841dfc9256485797 100644 --- a/test/box/xlog.result +++ b/test/box/xlog.result @@ -35,19 +35,3 @@ box.space[0]:insert{3, 'third tuple'} # Inprogress xlog with bad record must be deleted during recovery. 00000000000000000006.xlog.inprogress has been successfully deleted - -A test case for https://bugs.launchpad.net/tarantool/+bug/1052018 -panic_on_wal_error doens't work for duplicate key errors - -box.space[0]:select{1} ---- -- [1, 'First record'] -... -box.space[0]:select{2} ---- -- [2, 'Second record'] -... -#box.space[0] ---- -- 0 -... diff --git a/test/box/xlog.test.py b/test/box/xlog.test.py index 096cb249d52f376a583445d1b3bd22c7ccde395f..213e04f5715d8c24d30366a37dd340b88f70bea3 100644 --- a/test/box/xlog.test.py +++ b/test/box/xlog.test.py @@ -107,22 +107,47 @@ server.start() if not os.access(wal_inprogress, os.F_OK) and not os.access(wal, os.F_OK): print "00000000000000000006.xlog.inprogress has been successfully deleted" -print """ -A test case for https://bugs.launchpad.net/tarantool/+bug/1052018 -panic_on_wal_error doens't work for duplicate key errors -""" -server.stop() -server.cfgfile_source = "box/panic_on_wal_error.cfg" -server.deploy() -server.stop() -shutil.copy(abspath("box/dup_key1.xlog"), - os.path.join(server.vardir, "00000000000000000002.xlog")) -shutil.copy(abspath("box/dup_key2.xlog"), - os.path.join(server.vardir, "00000000000000000004.xlog")) -server.start() -admin("box.space[0]:select{1}") -admin("box.space[0]:select{2}") -admin("#box.space[0]") +#print """ +#A test case for https://bugs.launchpad.net/tarantool/+bug/1052018 +#panic_on_wal_error doesn't work for duplicate key errors +#""" + +# Step-by-step instruction for log files preparation +# needed for bugtest #1052018. +# +# +# 1. box.schema.create_space('test') +# 2. box.space['test']:create_index('primary') +# 3. box.space['test']:insert{1, 'first tuple} +# 4. box.space['test']:insert{2, 'second tuple} +# 5. stop tarantool +# 6. copy xlog to dup_key1.xlog +# 7. remove xlog +# 8. start tarantool +# 9. box.schema.create_space('test') +# 10. box.space['test']:create_index('primary') +# 11. box.space['test']:insert{1, 'first tuple} +# 12. box.space['test']:delete{1} +# 13. stop tarantool +# 14. start tarantool +# 15. box.space['test']:insert{1, 'third tuple'} +# 16. box.space['test']:insert{2, 'fourth tuple'} +# 17. stop tarantool +# 18. copy xlog to dup_key2.xlog +# + +#server.stop() +#server.cfgfile_source = "box/panic_on_wal_error.cfg" +#server.deploy() +#server.stop() +#shutil.copy(abspath("box/dup_key1.xlog"), + #os.path.join(server.vardir, "00000000000000000002.xlog")) +#shutil.copy(abspath("box/dup_key2.xlog"), + #os.path.join(server.vardir, "00000000000000000004.xlog")) +#server.start() +#admin("box.space['test']:get{1}") +#admin("box.space['test']:get{2}") +#admin("box.space['test']:len()") # cleanup server.stop() diff --git a/test/connector_c/CMakeLists.txt b/test/connector_c/CMakeLists.txt deleted file mode 100644 index e3446fba10956440a62b9edb0f645995c89f117e..0000000000000000000000000000000000000000 --- a/test/connector_c/CMakeLists.txt +++ /dev/null @@ -1,13 +0,0 @@ -file(GLOB all_sources *.c *.m *.mm) -set_source_files_compile_flags("TESTS" ${all_sources}) - -include_directories("${PROJECT_SOURCE_DIR}/test/unit") -include_directories("${PROJECT_SOURCE_DIR}/connector/c/include") - -tarantool_client("protocol" protocol.c) -tarantool_client("tt" tt.c) -tarantool_client("tp" tp.c) -tarantool_client("update" update.c) -tarantool_client("xlog" xlog.c) -tarantool_client("rpl" rpl.c) -tarantool_client("snap" snap.c) diff --git a/test/connector_c/cfg/master.cfg b/test/connector_c/cfg/master.cfg deleted file mode 100644 index 59dc00f297d0c2b7cde75bea6649bc03ec02c75c..0000000000000000000000000000000000000000 --- a/test/connector_c/cfg/master.cfg +++ /dev/null @@ -1,9 +0,0 @@ - -slab_alloc_arena = 0.1 -pid_file = "box.pid" -logger="cat - >> tarantool.log" - -primary_port = 33013 -admin_port = 33015 - -rows_per_wal = 50 diff --git a/test/connector_c/cfg/tarantool.cfg b/test/connector_c/cfg/tarantool.cfg deleted file mode 100644 index 59dc00f297d0c2b7cde75bea6649bc03ec02c75c..0000000000000000000000000000000000000000 --- a/test/connector_c/cfg/tarantool.cfg +++ /dev/null @@ -1,9 +0,0 @@ - -slab_alloc_arena = 0.1 -pid_file = "box.pid" -logger="cat - >> tarantool.log" - -primary_port = 33013 -admin_port = 33015 - -rows_per_wal = 50 diff --git a/test/connector_c/connector.result b/test/connector_c/connector.result deleted file mode 100644 index 193491abfef4b108f786bcba5810bb40a539f8a0..0000000000000000000000000000000000000000 --- a/test/connector_c/connector.result +++ /dev/null @@ -1,53 +0,0 @@ -box.insert(box.schema.SPACE_ID, 0, 0, 'tweedledum') ---- -- [0, 0, 'tweedledum'] -... -box.insert(box.schema.INDEX_ID, 0, 0, 'primary', 'hash', 1, 1, 0, 'str') ---- -- [0, 0, 'primary', 1752392040, 1, 1, 0, 'str'] -... -> tuple1 [OK] -> tuple2 [OK] -> list [OK] -> stream buffer [OK] -> tuple set [OK] -> iterator tuple [OK] -> iterator tuple (single field) [OK] -> iterator tuple (tnt_field) [OK] -> iterator tuple (empty) [OK] -> iterator list [OK] -> marshaling ping [OK] -> marshaling insert [OK] -> marshaling delete [OK] -> marshaling call [OK] -> marshaling select [OK] -> marshaling update [OK] -> connect [OK] -> ping [OK] -> insert [OK] -> update [OK] -> select [OK] -> delete [OK] -> call [OK] -> call (no args) [OK] -> reply [OK] -> lex ws [OK] -> lex integer [OK] -> lex string [OK] -> lex punctuation [OK] -> lex ids [OK] -> lex keywords [OK] -> lex keys and tables [OK] -> lex stack [OK] -> lex bad string1 [OK] -> lex bad string2 [OK] -> sql ping [OK] -> sql insert [OK] -> sql update [OK] -> sql select [OK] -> sql select limit [OK] -> sql delete [OK] -> sql call [OK] -box.space[0]:drop() ---- -... diff --git a/test/connector_c/connector.snap b/test/connector_c/connector.snap deleted file mode 100644 index ffc209f51d042180e4cfd71166febcfb31959c0f..0000000000000000000000000000000000000000 Binary files a/test/connector_c/connector.snap and /dev/null differ diff --git a/test/connector_c/connector.test.py b/test/connector_c/connector.test.py deleted file mode 100644 index 000b486a9ef1b9c123eda2c723a66c419678097e..0000000000000000000000000000000000000000 --- a/test/connector_c/connector.test.py +++ /dev/null @@ -1,16 +0,0 @@ -import subprocess -import sys -import os - -admin("box.insert(box.schema.SPACE_ID, 0, 0, 'tweedledum')") -admin("box.insert(box.schema.INDEX_ID, 0, 0, 'primary', 'hash', 1, 1, 0, 'str')") - -p = subprocess.Popen([os.path.join(builddir, "test/connector_c/tt")], - stdout=subprocess.PIPE) -p.wait() -for line in p.stdout.readlines(): - sys.stdout.write(line) - -admin("box.space[0]:drop()") - -# vim: syntax=python diff --git a/test/connector_c/connector.xlog b/test/connector_c/connector.xlog deleted file mode 100644 index af5a837d453d449f57fd1627708fdf60d95196d9..0000000000000000000000000000000000000000 Binary files a/test/connector_c/connector.xlog and /dev/null differ diff --git a/test/connector_c/protocol.c b/test/connector_c/protocol.c deleted file mode 100644 index 8d4b348963fff9d54f1cb24ad1532bd332d36fc0..0000000000000000000000000000000000000000 --- a/test/connector_c/protocol.c +++ /dev/null @@ -1,151 +0,0 @@ - -#include <stdlib.h> -#include <stdio.h> -#include <inttypes.h> - -#include "tarantool/util.h" -#include "errcode.h" - -#include <tarantool/tnt.h> -#include <tarantool/tnt_net.h> -#include <tarantool/tnt_io.h> - -/** Client handler. Reused between tests. */ -struct tnt_stream *t; - -#define header() printf("\t*** %s ***\n", __func__) -#define footer() printf("\t*** %s: done ***\n ", __func__) - -/** Test the ping command. */ -void test_ping() -{ - header(); - const char message[]= { 0x00, 0xff, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0 - }; - tnt_io_send_raw(TNT_SNET_CAST(t), (char*)message, sizeof(message), 1); - t->wrcnt++; - struct tnt_iter i; - tnt_iter_reply(&i, t); - tnt_next(&i); - struct tnt_reply *r = TNT_IREPLY_PTR(&i); - printf("return_code: %"PRIu32"\n", r->code); /* =0 */ - tnt_iter_free(&i); - footer(); -} - -/** Test the ping command. */ -void test_replace() -{ - header(); - const char message[]= { - 0xd, 0x0, 0x0, 0x0, 0x11, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, - 0x4, 0x1, 0x0, 0x0, 0x0 }; - tnt_io_send_raw(TNT_SNET_CAST(t), (char*)message, sizeof(message), 1); - t->wrcnt++; - struct tnt_iter i; - tnt_iter_reply(&i, t); - tnt_next(&i); - struct tnt_reply *r = TNT_IREPLY_PTR(&i); - printf("return_code: %"PRIu32"\n", r->code); /* =0 */ - tnt_iter_free(&i); - footer(); -} - -/** A test case for Bug#702397 - * https://bugs.launchpad.net/tarantool/+bug/702397 "If SELECT - * request specifies tuple count 0, no error" - */ -void test_bug702397() -{ - header(); - const char message[]= { - 0x11, 0x0, 0x0, 0x0, 0x14, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0 }; - tnt_io_send_raw(TNT_SNET_CAST(t), (char*)message, sizeof(message), 1); - t->wrcnt++; - struct tnt_iter i; - tnt_iter_reply(&i, t); - tnt_next(&i); - struct tnt_reply *r = TNT_IREPLY_PTR(&i); - printf("return_code: %s, %s\n", - tnt_errcode_str(TNT_REPLY_ERR(r)), r->error); - tnt_iter_free(&i); - footer(); -} - -/** A test case for Bug#702399 - * https://bugs.launchpad.net/tarantool/+bug/702399 - * ERR_CODE_ILLEGAL_PARAMS is returned when there is no such key - */ -void test_bug702399() -{ - header(); - const char message[]= { - 0x11, 0x0, 0x0, 0x0, 0x1d, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xff, 0xff, 0xff, 0xff, - 0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, - 0x4, 0x1, 0x0, 0x0, 0x0 }; - tnt_io_send_raw(TNT_SNET_CAST(t), (char*)message, sizeof(message), 1); - t->wrcnt++; - struct tnt_iter i; - tnt_iter_reply(&i, t); - tnt_next(&i); - struct tnt_reply *r = TNT_IREPLY_PTR(&i); - printf("return_code: %s, %s\n", - tnt_errcode_str(TNT_REPLY_ERR(r)), r->error); - tnt_iter_free(&i); - footer(); -} - -/** A test case for Bug#1009992 - * https://bugs.launchpad.net/tarantool/+bug/1009992 - * ER_ILLEGAL_PARAMS is returned on bad operation id - */ -void test_bug1009992() -{ - header(); - struct tnt_header h = { - .type = 12345678, /* bad operation */ - .len = 0, - .reqid = 0 - }; - tnt_io_send_raw(TNT_SNET_CAST(t), (char*)&h, sizeof(h), 1); - t->wrcnt++; - struct tnt_iter i; - tnt_iter_reply(&i, t); - tnt_next(&i); - struct tnt_reply *r = TNT_IREPLY_PTR(&i); - printf("return_code: %s, %s\n", - tnt_errcode_str(TNT_REPLY_ERR(r)), r->error); - tnt_iter_free(&i); - footer(); -} - -int main() -{ - t = tnt_net(NULL); - if (t == NULL) - return 1; - tnt_set(t, TNT_OPT_HOSTNAME, "localhost"); - tnt_set(t, TNT_OPT_PORT, 33013); - if (tnt_init(t) == -1) - return 1; - if (tnt_connect(t) == -1) - return 1; - - test_ping(); - test_replace(); - test_bug702397(); - test_bug702399(); - test_bug1009992(); - - tnt_stream_free(t); - return 0; -} diff --git a/test/connector_c/protocol.result b/test/connector_c/protocol.result deleted file mode 100644 index eb11e644b88da6156b0f917adcb2db42e72f6244..0000000000000000000000000000000000000000 --- a/test/connector_c/protocol.result +++ /dev/null @@ -1,26 +0,0 @@ -box.insert(box.schema.SPACE_ID, 0, 0, 'tweedledum') ---- -- [0, 0, 'tweedledum'] -... -box.insert(box.schema.INDEX_ID, 0, 0, 'primary', 'hash', 1, 1, 0, 'str') ---- -- [0, 0, 'primary', 1752392040, 1, 1, 0, 'str'] -... - *** test_ping *** -return_code: 0 - *** test_ping: done *** - *** test_replace *** -return_code: 0 - *** test_replace: done *** - *** test_bug702397 *** -return_code: ER_ILLEGAL_PARAMS, Illegal parameters, tuple count must be positive - *** test_bug702397: done *** - *** test_bug702399 *** -return_code: ER_NO_SUCH_INDEX, No index #1 is defined in space 0 - *** test_bug702399: done *** - *** test_bug1009992 *** -return_code: ER_ILLEGAL_PARAMS, Illegal parameters, unsupported command code, check the error log - *** test_bug1009992: done *** - box.space[0]:drop() ---- -... diff --git a/test/connector_c/protocol.test.py b/test/connector_c/protocol.test.py deleted file mode 100644 index 8942e65d1329a6ef28b8308f11fbce2b2d66ccd1..0000000000000000000000000000000000000000 --- a/test/connector_c/protocol.test.py +++ /dev/null @@ -1,17 +0,0 @@ -# encoding: utf-8 -# -import subprocess -import sys -import os - -admin("box.insert(box.schema.SPACE_ID, 0, 0, 'tweedledum')") -admin("box.insert(box.schema.INDEX_ID, 0, 0, 'primary', 'hash', 1, 1, 0, 'str')") -p = subprocess.Popen([ os.path.join(builddir, "test/connector_c/protocol") ], - stdout=subprocess.PIPE) -p.wait() -for line in p.stdout.readlines(): - sys.stdout.write(line) - -admin("box.space[0]:drop()") - -# vim: syntax=python diff --git a/test/connector_c/rpl.c b/test/connector_c/rpl.c deleted file mode 100644 index d57112f317c27a00558935fcd93d17000dfae01c..0000000000000000000000000000000000000000 --- a/test/connector_c/rpl.c +++ /dev/null @@ -1,88 +0,0 @@ - -/* - * Copyright (C) 2011 Mail.RU - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include <stdlib.h> -#include <stdint.h> -#include <inttypes.h> -#include <stdbool.h> -#include <stdio.h> -#include <string.h> - -#include <connector/c/include/tarantool/tnt.h> -#include <connector/c/include/tarantool/tnt_net.h> -#include <connector/c/include/tarantool/tnt_xlog.h> -#include <connector/c/include/tarantool/tnt_rpl.h> - -static char *opname(uint32_t type) { - switch (type) { - case TNT_OP_PING: return "Ping"; - case TNT_OP_INSERT: return "Insert"; - case TNT_OP_DELETE: return "Delete"; - case TNT_OP_UPDATE: return "Update"; - case TNT_OP_SELECT: return "Select"; - case TNT_OP_CALL: return "Call"; - } - return "Unknown"; -} - -int -main(int argc, char * argv[]) -{ - if (argc != 4) { - printf("usage %s: host port limit\n", argv[0]); - return 1; - } - struct tnt_stream s; - tnt_rpl(&s); - struct tnt_stream sn; - tnt_net(&sn); - tnt_set(&sn, TNT_OPT_HOSTNAME, argv[1]); - tnt_set(&sn, TNT_OPT_PORT, atoi(argv[2])); - tnt_set(&sn, TNT_OPT_SEND_BUF, 0); - tnt_set(&sn, TNT_OPT_RECV_BUF, 0); - tnt_rpl_attach(&s, &sn); - if (tnt_rpl_open(&s, 2) == -1) - return 1; - - struct tnt_iter i; - tnt_iter_request(&i, &s); - - int limit = atoi(argv[3]); - while (limit-- > 0 && tnt_next(&i)) { - struct tnt_stream_rpl *sr = TNT_RPL_CAST(&s); - printf("%s lsn: %"PRIu64", time: %f, len: %d\n", - opname(sr->row.op), - sr->hdr.lsn, - sr->hdr.tm, sr->hdr.len); - } - if (i.status == TNT_ITER_FAIL) - printf("parsing failed\n"); - - tnt_iter_free(&i); - tnt_stream_free(&s); - tnt_stream_free(&sn); - return 0; -} diff --git a/test/connector_c/snap.c b/test/connector_c/snap.c deleted file mode 100644 index 7c434a6b8cc043dc7aefdf79c30e1cdb9af6739e..0000000000000000000000000000000000000000 --- a/test/connector_c/snap.c +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * 1. Redistributions of source code must retain the above - * copyright notice, this list of conditions and the - * following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * <COPYRIGHT HOLDER> OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF - * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ -#include <stdlib.h> -#include <stdint.h> -#include <inttypes.h> -#include <stdbool.h> -#include <stdio.h> -#include <string.h> -#include <ctype.h> - -#include <connector/c/include/tarantool/tnt.h> -#include <connector/c/include/tarantool/tnt_net.h> -#include <connector/c/include/tarantool/tnt_snapshot.h> - -static void print_tuple(struct tnt_tuple *tu) { - printf("["); - struct tnt_iter ifl; - tnt_iter(&ifl, tu); - while (tnt_next(&ifl)) { - if (TNT_IFIELD_IDX(&ifl) != 0) - printf(", "); - char *data = TNT_IFIELD_DATA(&ifl); - uint32_t size = TNT_IFIELD_SIZE(&ifl); - if (!isprint(data[0]) && (size == 4 || size == 8)) { - if (size == 4) { - uint32_t i = *((uint32_t*)data); - printf("%"PRIu32, i); - } else { - uint64_t i = *((uint64_t*)data); - printf("%"PRIu64, i); - } - } else { - printf("'%-.*s'", size, data); - } - } - if (ifl.status == TNT_ITER_FAIL) - printf("<parsing error>"); - tnt_iter_free(&ifl); - printf("]\n"); -} - -int -main(int argc, char * argv[]) -{ - if (argc != 2) - return 1; - - struct tnt_stream s; - tnt_snapshot(&s); - - if (tnt_snapshot_open(&s, argv[1]) == -1) - return 1; - - struct tnt_iter i; - tnt_iter_storage(&i, &s); - - while (tnt_next(&i)) { - struct tnt_iter_storage *is = TNT_ISTORAGE(&i); - print_tuple(&is->t); - } - if (i.status == TNT_ITER_FAIL) - printf("parsing failed: %s\n", tnt_snapshot_strerror(&s)); - - tnt_iter_free(&i); - tnt_stream_free(&s); - return 0; -} diff --git a/test/connector_c/snap.result b/test/connector_c/snap.result deleted file mode 100644 index f1a932f385dc64ffaed7be4b458b975530d19a93..0000000000000000000000000000000000000000 --- a/test/connector_c/snap.result +++ /dev/null @@ -1,4 +0,0 @@ -['3', '3'] -['hello', 'world'] -['1', 'world'] -['2', '2'] diff --git a/test/connector_c/snap.test.py b/test/connector_c/snap.test.py deleted file mode 100644 index 27512ed05eb5a5b191c3a687ce19eccc9861153e..0000000000000000000000000000000000000000 --- a/test/connector_c/snap.test.py +++ /dev/null @@ -1,11 +0,0 @@ -import subprocess -import sys -import os - -p = subprocess.Popen([os.path.join(builddir, "test/connector_c/snap"), - os.path.abspath("connector_c/connector.snap")], - stdout=subprocess.PIPE) -o,e = p.communicate() -sys.stdout.write(o) - -# vim: syntax=python diff --git a/test/connector_c/suite.ini.disabled b/test/connector_c/suite.ini.disabled deleted file mode 100644 index 468e565472e47f375137538a452f30a064e0f57d..0000000000000000000000000000000000000000 --- a/test/connector_c/suite.ini.disabled +++ /dev/null @@ -1,8 +0,0 @@ -[default] -core = tarantool -description = tarantool/box connector C -config = cfg/tarantool.cfg -# put disabled tests here -# disabled = xlog_rpl.test -# put disabled in valgrind test here -#valgrind_disabled = diff --git a/test/connector_c/tp.c b/test/connector_c/tp.c deleted file mode 100644 index 72b8c8d910d4f956af5b7f51bd7d4c671200afc9..0000000000000000000000000000000000000000 --- a/test/connector_c/tp.c +++ /dev/null @@ -1,131 +0,0 @@ - -#include <stdio.h> -#include <unistd.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <stdio.h> -#include <tp.h> - -static void reply_print(struct tp *rep) { - while (tp_next(rep)) { - printf("tuple fields: %d\n", tp_tuplecount(rep)); - printf("tuple size: %d\n", tp_tuplesize(rep)); - printf("["); - while (tp_nextfield(rep)) { - printf("%-.*s", tp_getfieldsize(rep), tp_getfield(rep)); - if (tp_hasnextfield(rep)) - printf(", "); - } - printf("]\n"); - } -} - -static inline int -test_check_read_reply(int fd) { - struct tp rep; - tp_init(&rep, NULL, 0, tp_realloc, NULL); - while (1) { - ssize_t to_read = tp_req(&rep); - if (to_read <= 0) - break; - ssize_t new_size = tp_ensure(&rep, to_read); - if (new_size == -1) { - // no memory (?) - return 1; - } - ssize_t res = read(fd, rep.p, to_read); - if (res == 0) { - // eof - return 1; - } else if (res < 0) { - // error - return 1; - } - tp_use(&rep, res); - } - - ssize_t server_code = tp_reply(&rep); - - if (server_code != 0) { - printf("error: %-.*s\n", tp_replyerrorlen(&rep), - tp_replyerror(&rep)); - tp_free(&rep); - return 1; - } - if (tp_replyop(&rep) == 17) { /* select */ - reply_print(&rep); - } else - if (tp_replyop(&rep) == 13) { /* insert */ - } else { - return 1; - } - tp_free(&rep); - return 0; -} - -static inline int -test_check_read(void) -{ - int fd; - struct sockaddr_in tt; - if ((fd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) { - printf("Failed to create socket\n"); - return 1; - } - - memset(&tt, 0, sizeof(tt)); - tt.sin_family = AF_INET; - tt.sin_addr.s_addr = inet_addr("127.0.0.1"); - tt.sin_port = htons(33013); - if (connect(fd, (struct sockaddr *) &tt, sizeof(tt)) < 0) { - printf("Failed to connect\n"); - return 1; - } - - struct tp req; - tp_init(&req, NULL, 0, tp_realloc, NULL); - tp_insert(&req, 0, 0); - tp_tuple(&req); - tp_sz(&req, "_i32"); - tp_sz(&req, "0e72ae1a-d0be-4e49-aeb9-aebea074363c"); - tp_select(&req, 0, 0, 0, 1); - tp_tuple(&req); - tp_sz(&req, "_i32"); - int rc = write(fd, tp_buf(&req), tp_used(&req)); - if (rc != tp_used(&req)) - return 1; - - tp_free(&req); - - rc = test_check_read_reply(fd); - if (rc != 0) - return 1; - rc = test_check_read_reply(fd); - if (rc != 0) - return 1; - - close(fd); - return 0; -} - -static inline void -test_check_buffer_initialized(void) { - struct tp req; - tp_init(&req, NULL, 0, tp_realloc, NULL); - tp_select(&req, 0, 0, 0, 0); /* could fail on assert */ - tp_tuple(&req); - tp_sz(&req, "key"); - tp_free(&req); -} - -int -main(int argc, char *argv[]) -{ - (void)argc; - (void)argv; - test_check_buffer_initialized(); - test_check_read(); - return 0; -} diff --git a/test/connector_c/tp.result b/test/connector_c/tp.result deleted file mode 100644 index a5d915b32aaa31ae0f11247f927fa6879062eda9..0000000000000000000000000000000000000000 --- a/test/connector_c/tp.result +++ /dev/null @@ -1,14 +0,0 @@ -box.insert(box.schema.SPACE_ID, 0, 0, 'tweedledum') ---- -- [0, 0, 'tweedledum'] -... -box.insert(box.schema.INDEX_ID, 0, 0, 'primary', 'hash', 1, 1, 0, 'str') ---- -- [0, 0, 'primary', 1752392040, 1, 1, 0, 'str'] -... -tuple fields: 2 -tuple size: 42 -[_i32, 0e72ae1a-d0be-4e49-aeb9-aebea074363c] -box.space[0]:drop() ---- -... diff --git a/test/connector_c/tp.test.py b/test/connector_c/tp.test.py deleted file mode 100644 index a3161c5f34ae29e8098581cd5eac9b863d562974..0000000000000000000000000000000000000000 --- a/test/connector_c/tp.test.py +++ /dev/null @@ -1,13 +0,0 @@ -import subprocess -import sys -import os - -admin("box.insert(box.schema.SPACE_ID, 0, 0, 'tweedledum')") -admin("box.insert(box.schema.INDEX_ID, 0, 0, 'primary', 'hash', 1, 1, 0, 'str')") - -p = subprocess.Popen([os.path.join(builddir, "test/connector_c/tp")], - stdout=subprocess.PIPE) -o,e = p.communicate() -sys.stdout.write(o) - -admin("box.space[0]:drop()") diff --git a/test/connector_c/tt.c b/test/connector_c/tt.c deleted file mode 100644 index db3b8d6c210707ba26c8657ca41444b41205d728..0000000000000000000000000000000000000000 --- a/test/connector_c/tt.c +++ /dev/null @@ -1,1197 +0,0 @@ - -/* - * Copyright (C) 2011 Mail.RU - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include <stdlib.h> -#include <stdint.h> -#include <stdbool.h> -#include <stdio.h> -#include <string.h> -#include <limits.h> - -#include <connector/c/include/tarantool/tnt.h> -#include <connector/c/include/tarantool/tnt_net.h> -#include <connector/c/include/tarantool/tnt_io.h> -#include <connector/c/include/tarantool/tnt_queue.h> -#include <connector/c/include/tarantool/tnt_utf8.h> -#include <connector/c/include/tarantool/tnt_lex.h> -#include <connector/c/include/tarantool/tnt_sql.h> - -struct tt_test; - -typedef void (*tt_testf_t)(struct tt_test *t); - -struct tt_test { - char *name; - tt_testf_t cb; - struct tt_test *next; -}; - -struct tt_list { - struct tt_test *head, *tail; - int count; -}; - -static struct tt_test* tt_test(struct tt_list *list, char *name, tt_testf_t cb) { - struct tt_test *t = malloc(sizeof(struct tt_test)); - if (t == NULL) - return NULL; - t->name = strdup(name); - t->cb = cb; - t->next = NULL; - if (list->head == NULL) - list->head = t; - else - list->tail->next = t; - list->tail = t; - list->count++; - return t; -} - -static void tt_free(struct tt_list *list) { - struct tt_test *i = list->head; - struct tt_test *n = NULL; - while (i) { - n = i->next; - free(i->name); - free(i); - i = n; - } -} - -static void tt_run(struct tt_list *list) { - struct tt_test *i = list->head; - while (i) { - printf("> %-30s", i->name); - fflush(NULL); - i->cb(i); - printf("[OK]\n"); - i = i->next; - } -} - -static void -tt_assert(struct tt_test *t, char *file, int line, int expr, char *exprsz) { - if (expr) - return; - (void)t; - printf("[%s:%d] %s\n", file, line, exprsz); - abort(); -} - -#define TT_ASSERT(EXPR) \ - tt_assert(test, __FILE__, __LINE__, (EXPR), #EXPR) - -/* basic tuple creation */ -static void tt_tnt_tuple1(struct tt_test *test) { - struct tnt_tuple t; - tnt_tuple_init(&t); - tnt_tuple(&t, "%s%d", "foo", 123); - TT_ASSERT(t.alloc == 0); - TT_ASSERT(t.cardinality == 2); - TT_ASSERT(t.data != NULL); - TT_ASSERT(t.size != 0); - tnt_tuple_free(&t); - struct tnt_tuple *tp = tnt_tuple(NULL, "%s%d", "foo", 123); - TT_ASSERT(tp->alloc == 1); - TT_ASSERT(tp->cardinality == 2); - TT_ASSERT(tp->data != NULL); - TT_ASSERT(tp->size != 0); - tnt_tuple_free(tp); -} - -/* basic tuple field manipulation */ -static void tt_tnt_tuple2(struct tt_test *test) { - struct tnt_tuple t; - tnt_tuple_init(&t); - tnt_tuple_add(&t, "foo", 4); - TT_ASSERT(t.alloc == 0); - TT_ASSERT(t.cardinality == 1); - TT_ASSERT(t.data != NULL); - TT_ASSERT(t.size != 0); - tnt_tuple_add(&t, "bar", 4); - TT_ASSERT(t.cardinality == 2); - tnt_tuple_add(&t, "baz", 4); - TT_ASSERT(t.cardinality == 3); - tnt_tuple(&t, "%s%d", "xyz", 123); - TT_ASSERT(t.cardinality == 5); - tnt_tuple_free(&t); -} - -/* basic list operations */ -static void tt_tnt_list(struct tt_test *test) { - struct tnt_list list; - tnt_list_init(&list); - tnt_list(&list, tnt_tuple(NULL, "%s", "foo"), NULL); - TT_ASSERT(list.list != NULL); - TT_ASSERT(list.alloc == 0); - TT_ASSERT(list.count == 1); - tnt_list(&list, tnt_tuple(NULL, "%s", "foo"), NULL); - tnt_list(&list, tnt_tuple(NULL, "%s", "foo"), NULL); - TT_ASSERT(list.count == 3); - struct tnt_tuple t; - tnt_tuple_init(&t); - tnt_list_at(&list, &t); - TT_ASSERT(list.count == 4); - tnt_list_free(&list); - struct tnt_list *l = - tnt_list(NULL, - tnt_tuple(NULL, "%s", "foo"), - tnt_tuple(NULL, "%s", "bar"), - tnt_tuple(NULL, "%s", "baz"), NULL); - TT_ASSERT(l->alloc == 1); - TT_ASSERT(l->list != NULL); - TT_ASSERT(l->count == 3); - tnt_list_free(l); -} - -/* stream buffer */ -static void tt_tnt_sbuf(struct tt_test *test) { - struct tnt_stream s; - tnt_buf(&s); - TT_ASSERT(s.alloc == 0); - struct tnt_stream_buf *sb = TNT_SBUF_CAST(&s); - TT_ASSERT(sb->data == NULL); - TT_ASSERT(sb->size == 0); - TT_ASSERT(sb->rdoff == 0); - TT_ASSERT(s.wrcnt == 0); - struct tnt_tuple *kv = tnt_tuple(NULL, "%s%d", "key", 123); - tnt_insert(&s, 0, 0, kv); - TT_ASSERT(sb->data != NULL); - TT_ASSERT(sb->size != 0); - TT_ASSERT(sb->rdoff == 0); - TT_ASSERT(s.wrcnt == 1); - tnt_insert(&s, 0, 0, kv); - TT_ASSERT(s.wrcnt == 2); - tnt_tuple_free(kv); - tnt_stream_free(&s); -} - -/* tuple set */ -static void tt_tnt_tuple_set(struct tt_test *test) { - char buf[75]; - *((uint32_t*)buf) = 2; /* cardinality */ - /* 4 + 1 + 5 + 1 + 64 = 75 */ - uint32_t off = sizeof(uint32_t); - int esize = tnt_enc_size(5); - tnt_enc_write(buf + off, 5); - off += esize + 5; - esize = tnt_enc_size(64); - tnt_enc_write(buf + off, 64); - off += esize + 64; - struct tnt_tuple t; - tnt_tuple_init(&t); - TT_ASSERT(tnt_tuple_set(&t, buf, 70) == NULL); - TT_ASSERT(tnt_tuple_set(&t, buf, sizeof(buf)) != NULL); - tnt_tuple_free(&t); -} - -/* iterator tuple */ -static void tt_tnt_iter1(struct tt_test *test) { - struct tnt_tuple *t = tnt_tuple(NULL, "%s%d%s", "foo", 123, "bar"); - TT_ASSERT(t->cardinality == 3); - struct tnt_iter i; - tnt_iter(&i, t); - TT_ASSERT(tnt_next(&i) == 1); - TT_ASSERT(TNT_IFIELD_IDX(&i) == 0); - TT_ASSERT(TNT_IFIELD_SIZE(&i) == 3); - TT_ASSERT(memcmp(TNT_IFIELD_DATA(&i), "foo", 3) == 0); - TT_ASSERT(tnt_next(&i) == 1); - TT_ASSERT(TNT_IFIELD_SIZE(&i) == 4); - TT_ASSERT(TNT_IFIELD_IDX(&i) == 1); - TT_ASSERT(*(uint32_t*)TNT_IFIELD_DATA(&i) == 123); - TT_ASSERT(tnt_next(&i) == 1); - TT_ASSERT(TNT_IFIELD_IDX(&i) == 2); - TT_ASSERT(TNT_IFIELD_SIZE(&i) == 3); - TT_ASSERT(memcmp(TNT_IFIELD_DATA(&i), "bar", 3) == 0); - TT_ASSERT(tnt_next(&i) == 0); - tnt_iter_free(&i); - tnt_tuple_free(t); -} - -/* iterator tuple single field */ -static void tt_tnt_iter11(struct tt_test *test) { - struct tnt_tuple *t = tnt_tuple(NULL, "%s", "foo"); - TT_ASSERT(t->cardinality == 1); - struct tnt_iter i; - tnt_iter(&i, t); - TT_ASSERT(tnt_next(&i) == 1); - TT_ASSERT(TNT_IFIELD_IDX(&i) == 0); - TT_ASSERT(TNT_IFIELD_SIZE(&i) == 3); - TT_ASSERT(memcmp(TNT_IFIELD_DATA(&i), "foo", 3) == 0); - TT_ASSERT(tnt_next(&i) == 0); - tnt_iter_free(&i); - tnt_tuple_free(t); -} - -/* iterator tuple field */ -static void tt_tnt_iter2(struct tt_test *test) { - struct tnt_tuple *t = tnt_tuple(NULL, "%s%d%s", "foo", 123, "bar"); - TT_ASSERT(t->cardinality == 3); - struct tnt_iter *i = tnt_field(NULL, t, 0); - TT_ASSERT(i->alloc != 0); - TT_ASSERT(tnt_field(i, NULL, 0) != NULL); - TT_ASSERT(TNT_IFIELD_IDX(i) == 0); - TT_ASSERT(TNT_IFIELD_SIZE(i) == 3); - TT_ASSERT(memcmp(TNT_IFIELD_DATA(i), "foo", 3) == 0); - TT_ASSERT(tnt_field(i, NULL, 1) != NULL); - TT_ASSERT(TNT_IFIELD_SIZE(i) == 4); - TT_ASSERT(TNT_IFIELD_IDX(i) == 1); - TT_ASSERT(*(uint32_t*)TNT_IFIELD_DATA(i) == 123); - TT_ASSERT(tnt_field(i, NULL, 2) != NULL); - TT_ASSERT(TNT_IFIELD_IDX(i) == 2); - TT_ASSERT(TNT_IFIELD_SIZE(i) == 3); - TT_ASSERT(memcmp(TNT_IFIELD_DATA(i), "bar", 3) == 0); - TT_ASSERT(tnt_field(i, NULL, 3) == NULL); - tnt_iter_free(i); - tnt_tuple_free(t); -} - -/* iterator list */ -static void tt_tnt_iter3(struct tt_test *test) { - struct tnt_tuple t1, t2, t3; - tnt_tuple_init(&t1); - tnt_tuple_init(&t2); - tnt_tuple_init(&t3); - tnt_tuple(&t1, "%s", "foo"); - tnt_tuple(&t2, "%s", "bar"); - tnt_tuple(&t3, "%s", "baz"); - struct tnt_list *l = tnt_list(NULL, &t1, &t2, &t3, NULL); - TT_ASSERT(l->count == 3); - struct tnt_iter i; - tnt_iter_list(&i, l); - TT_ASSERT(tnt_next(&i) == 1); - TT_ASSERT(TNT_ILIST_TUPLE(&i) == &t1); - TT_ASSERT(tnt_next(&i) == 1); - TT_ASSERT(TNT_ILIST_TUPLE(&i) == &t2); - TT_ASSERT(tnt_next(&i) == 1); - TT_ASSERT(TNT_ILIST_TUPLE(&i) == &t3); - TT_ASSERT(tnt_next(&i) == 0); - tnt_tuple_free(&t1); - tnt_tuple_free(&t2); - tnt_tuple_free(&t3); - tnt_iter_free(&i); - tnt_list_free(l); -} - -/* iterator empty tuple */ -static void tt_tnt_iter4(struct tt_test *test) { - char buf[4]; - memset(buf, 0, sizeof(buf)); - struct tnt_tuple t; - tnt_tuple_init(&t); - tnt_tuple_set(&t, buf, sizeof(buf)); - struct tnt_iter i; - tnt_iter(&i, &t); - TT_ASSERT(tnt_next(&i) == 0); - tnt_iter_free(&i); - tnt_tuple_free(&t); -} - -/* marshal ping */ -static void tt_tnt_marshal_ping(struct tt_test *test) { - struct tnt_stream s; - tnt_buf(&s); - tnt_ping(&s); - tnt_ping(&s); - struct tnt_iter i; - tnt_iter_request(&i, &s); - TT_ASSERT(tnt_next(&i) == 1); - struct tnt_request *r = TNT_IREQUEST_PTR(&i); - TT_ASSERT(r->h.type == TNT_OP_PING); - TT_ASSERT(tnt_next(&i) == 1); - TT_ASSERT(r->h.type == TNT_OP_PING); - TT_ASSERT(tnt_next(&i) == 0); - tnt_iter_free(&i); - tnt_stream_free(&s); -} - -/* marshal insert */ -static void tt_tnt_marshal_insert(struct tt_test *test) { - struct tnt_stream s; - tnt_buf(&s); - struct tnt_tuple t; - tnt_tuple_init(&t); - tnt_tuple(&t, "%s%d", "foo", 123); - tnt_insert(&s, 0, 0, &t); - tnt_insert(&s, 0, 0, &t); - struct tnt_iter i; - tnt_iter_request(&i, &s); - TT_ASSERT(tnt_next(&i) == 1); - struct tnt_request *r = TNT_IREQUEST_PTR(&i); - TT_ASSERT(r->h.type == TNT_OP_INSERT); - struct tnt_iter *f = tnt_field(NULL, &r->r.insert.t, 0); - TT_ASSERT(tnt_field(f, NULL, 0) != NULL); - TT_ASSERT(TNT_IFIELD_IDX(f) == 0); - TT_ASSERT(TNT_IFIELD_SIZE(f) == 3); - TT_ASSERT(memcmp(TNT_IFIELD_DATA(f), "foo", 3) == 0); - TT_ASSERT(tnt_field(f, NULL, 1) != NULL); - TT_ASSERT(TNT_IFIELD_SIZE(f) == 4); - TT_ASSERT(TNT_IFIELD_IDX(f) == 1); - TT_ASSERT(*(uint32_t*)TNT_IFIELD_DATA(f) == 123); - TT_ASSERT(tnt_next(&i) == 1); - r = TNT_IREQUEST_PTR(&i); - TT_ASSERT(r->h.type == TNT_OP_INSERT); - TT_ASSERT(tnt_field(f, NULL, 0) != NULL); - TT_ASSERT(TNT_IFIELD_IDX(f) == 0); - TT_ASSERT(TNT_IFIELD_SIZE(f) == 3); - TT_ASSERT(memcmp(TNT_IFIELD_DATA(f), "foo", 3) == 0); - TT_ASSERT(tnt_field(f, NULL, 1) != NULL); - TT_ASSERT(TNT_IFIELD_SIZE(f) == 4); - TT_ASSERT(TNT_IFIELD_IDX(f) == 1); - TT_ASSERT(*(uint32_t*)TNT_IFIELD_DATA(f) == 123); - TT_ASSERT(tnt_next(&i) == 0); - tnt_tuple_free(&t); - tnt_iter_free(&i); - tnt_stream_free(&s); -} - -/* marshal delete */ -static void tt_tnt_marshal_delete(struct tt_test *test) { - struct tnt_stream s; - tnt_buf(&s); - struct tnt_tuple t; - tnt_tuple_init(&t); - tnt_tuple(&t, "%s", "foo"); - tnt_delete(&s, 0, 0, &t); - tnt_delete(&s, 0, 0, &t); - struct tnt_iter i; - tnt_iter_request(&i, &s); - TT_ASSERT(tnt_next(&i) == 1); - struct tnt_request *r = TNT_IREQUEST_PTR(&i); - TT_ASSERT(r->h.type == TNT_OP_DELETE); - struct tnt_iter *f = tnt_field(NULL, &r->r.del.t, 0); - TT_ASSERT(tnt_field(f, NULL, 0) != NULL); - TT_ASSERT(TNT_IFIELD_IDX(f) == 0); - TT_ASSERT(TNT_IFIELD_SIZE(f) == 3); - TT_ASSERT(memcmp(TNT_IFIELD_DATA(f), "foo", 3) == 0); - TT_ASSERT(tnt_next(&i) == 1); - r = TNT_IREQUEST_PTR(&i); - TT_ASSERT(r->h.type == TNT_OP_DELETE); - TT_ASSERT(tnt_field(f, NULL, 0) != NULL); - TT_ASSERT(TNT_IFIELD_IDX(f) == 0); - TT_ASSERT(TNT_IFIELD_SIZE(f) == 3); - TT_ASSERT(memcmp(TNT_IFIELD_DATA(f), "foo", 3) == 0); - TT_ASSERT(tnt_next(&i) == 0); - tnt_tuple_free(&t); - tnt_iter_free(&i); - tnt_stream_free(&s); -} - -/* marshal call */ -static void tt_tnt_marshal_call(struct tt_test *test) { - struct tnt_stream s; - tnt_buf(&s); - struct tnt_tuple t; - tnt_tuple_init(&t); - tnt_tuple(&t, "%s%d", "foo", 123); - tnt_call(&s, 0, "box.select", &t); - tnt_call(&s, 0, "box.select", &t); - struct tnt_iter i; - tnt_iter_request(&i, &s); - TT_ASSERT(tnt_next(&i) == 1); - struct tnt_request *r = TNT_IREQUEST_PTR(&i); - TT_ASSERT(r->h.type == TNT_OP_CALL); - TT_ASSERT(strcmp(r->r.call.proc, "box.select") == 0); - struct tnt_iter *f = tnt_field(NULL, &r->r.call.t, 0); - TT_ASSERT(tnt_field(f, NULL, 0) != NULL); - TT_ASSERT(TNT_IFIELD_IDX(f) == 0); - TT_ASSERT(TNT_IFIELD_SIZE(f) == 3); - TT_ASSERT(memcmp(TNT_IFIELD_DATA(f), "foo", 3) == 0); - TT_ASSERT(tnt_field(f, NULL, 1) != NULL); - TT_ASSERT(TNT_IFIELD_SIZE(f) == 4); - TT_ASSERT(TNT_IFIELD_IDX(f) == 1); - TT_ASSERT(*(uint32_t*)TNT_IFIELD_DATA(f) == 123); - TT_ASSERT(tnt_next(&i) == 1); - r = TNT_IREQUEST_PTR(&i); - TT_ASSERT(r->h.type == TNT_OP_CALL); - TT_ASSERT(strcmp(r->r.call.proc, "box.select") == 0); - TT_ASSERT(tnt_field(f, NULL, 0) != NULL); - TT_ASSERT(TNT_IFIELD_IDX(f) == 0); - TT_ASSERT(TNT_IFIELD_SIZE(f) == 3); - TT_ASSERT(memcmp(TNT_IFIELD_DATA(f), "foo", 3) == 0); - TT_ASSERT(tnt_field(f, NULL, 1) != NULL); - TT_ASSERT(TNT_IFIELD_SIZE(f) == 4); - TT_ASSERT(TNT_IFIELD_IDX(f) == 1); - TT_ASSERT(*(uint32_t*)TNT_IFIELD_DATA(f) == 123); - TT_ASSERT(tnt_next(&i) == 0); - tnt_tuple_free(&t); - tnt_iter_free(&i); - tnt_stream_free(&s); -} - -/* marshal select */ -static void tt_tnt_marshal_select(struct tt_test *test) { - struct tnt_stream s; - tnt_buf(&s); - struct tnt_list list; - tnt_list_init(&list); - tnt_list(&list, tnt_tuple(NULL, "%s", "foo"), - tnt_tuple(NULL, "%s%d", "bar", 444), - tnt_tuple(NULL, "%s%d%d", "baz", 1, 2), - NULL); - tnt_select(&s, 0, 0, 0, 1, &list); - struct tnt_iter i; - tnt_iter_request(&i, &s); - TT_ASSERT(tnt_next(&i) == 1); - struct tnt_request *r = TNT_IREQUEST_PTR(&i); - TT_ASSERT(r->h.type == TNT_OP_SELECT); - struct tnt_iter il; - tnt_iter_list(&il, &r->r.select.l); - TT_ASSERT(tnt_next(&il) == 1); - struct tnt_tuple *t = TNT_ILIST_TUPLE(&il); - struct tnt_iter *f = tnt_field(NULL, t, 0); - TT_ASSERT(tnt_field(f, NULL, 0) != NULL); - TT_ASSERT(TNT_IFIELD_IDX(f) == 0); - TT_ASSERT(TNT_IFIELD_SIZE(f) == 3); - TT_ASSERT(memcmp(TNT_IFIELD_DATA(f), "foo", 3) == 0); - tnt_iter_free(f); - TT_ASSERT(tnt_next(&il) == 1); - t = TNT_ILIST_TUPLE(&il); - f = tnt_field(NULL, t, 0); - TT_ASSERT(tnt_field(f, NULL, 0) != NULL); - TT_ASSERT(TNT_IFIELD_IDX(f) == 0); - TT_ASSERT(TNT_IFIELD_SIZE(f) == 3); - TT_ASSERT(memcmp(TNT_IFIELD_DATA(f), "bar", 3) == 0); - TT_ASSERT(tnt_field(f, NULL, 1) != NULL); - TT_ASSERT(TNT_IFIELD_SIZE(f) == 4); - TT_ASSERT(TNT_IFIELD_IDX(f) == 1); - TT_ASSERT(*(uint32_t*)TNT_IFIELD_DATA(f) == 444); - tnt_iter_free(f); - TT_ASSERT(tnt_next(&il) == 1); - t = TNT_ILIST_TUPLE(&il); - f = tnt_field(NULL, t, 0); - TT_ASSERT(tnt_field(f, NULL, 0) != NULL); - TT_ASSERT(TNT_IFIELD_IDX(f) == 0); - TT_ASSERT(TNT_IFIELD_SIZE(f) == 3); - TT_ASSERT(memcmp(TNT_IFIELD_DATA(f), "baz", 3) == 0); - TT_ASSERT(tnt_field(f, NULL, 1) != NULL); - TT_ASSERT(TNT_IFIELD_SIZE(f) == 4); - TT_ASSERT(TNT_IFIELD_IDX(f) == 1); - TT_ASSERT(*(uint32_t*)TNT_IFIELD_DATA(f) == 1); - TT_ASSERT(tnt_field(f, NULL, 2) != NULL); - TT_ASSERT(TNT_IFIELD_SIZE(f) == 4); - TT_ASSERT(TNT_IFIELD_IDX(f) == 2); - TT_ASSERT(*(uint32_t*)TNT_IFIELD_DATA(f) == 2); - tnt_iter_free(f); - TT_ASSERT(tnt_next(&il) == 0); - tnt_iter_free(&i); - tnt_iter_free(&il); - tnt_list_free(&list); - tnt_stream_free(&s); -} - -/* marshal update */ -static void tt_tnt_marshal_update(struct tt_test *test) { - struct tnt_stream s, ops; - tnt_buf(&s); - tnt_buf(&ops); - struct tnt_tuple t; - tnt_tuple_init(&t); - tnt_tuple(&t, "%s", "foo"); - tnt_update_assign(&ops, 444, "FOO", 3); - tnt_update_arith(&ops, 2, TNT_UPDATE_ADD, 7); - TT_ASSERT(tnt_update(&s, 0, 0, &t, &ops) > 0); - struct tnt_iter i; - tnt_iter_request(&i, &s); - TT_ASSERT(tnt_next(&i) == 1); - struct tnt_request *r = TNT_IREQUEST_PTR(&i); - TT_ASSERT(r->h.type == TNT_OP_UPDATE); - TT_ASSERT(r->r.update.opc == 2); - struct tnt_iter *f = tnt_field(NULL, &r->r.update.t, 0); - TT_ASSERT(tnt_field(f, NULL, 0) != NULL); - TT_ASSERT(TNT_IFIELD_IDX(f) == 0); - TT_ASSERT(TNT_IFIELD_SIZE(f) == 3); - TT_ASSERT(memcmp(TNT_IFIELD_DATA(f), "foo", 3) == 0); - TT_ASSERT(r->r.update.opv[0].op == TNT_UPDATE_ASSIGN); - TT_ASSERT(r->r.update.opv[0].field == 444); - TT_ASSERT(r->r.update.opv[0].size == 3); - TT_ASSERT(memcmp(r->r.update.opv[0].data, "FOO", 3) == 0); - TT_ASSERT(r->r.update.opv[1].op == TNT_UPDATE_ADD); - TT_ASSERT(r->r.update.opv[1].field == 2); - TT_ASSERT(r->r.update.opv[1].size == 4); - TT_ASSERT(*(uint32_t*)r->r.update.opv[1].data == 7); - TT_ASSERT(tnt_next(&i) == 0); - tnt_tuple_free(&t); - tnt_stream_free(&s); - tnt_stream_free(&ops); - tnt_iter_free(&i); -} - -static struct tnt_stream net; - -/* network connection */ -static void tt_tnt_net_connect(struct tt_test *test) { - TT_ASSERT(tnt_net(&net) != NULL); - TT_ASSERT(tnt_set(&net, TNT_OPT_HOSTNAME, "localhost") == 0); - TT_ASSERT(tnt_set(&net, TNT_OPT_PORT, 33013) == 0); - TT_ASSERT(tnt_init(&net) == 0); - TT_ASSERT(tnt_connect(&net) == 0); -} - -/* ping */ -static void tt_tnt_net_ping(struct tt_test *test) { - TT_ASSERT(tnt_ping(&net) > 0); - TT_ASSERT(tnt_flush(&net) > 0); - struct tnt_iter i; - tnt_iter_reply(&i, &net); - while (tnt_next(&i)) { - struct tnt_reply *r = TNT_IREPLY_PTR(&i); - TT_ASSERT(r->code == 0); - TT_ASSERT(r->op == TNT_OP_PING); - } - tnt_iter_free(&i); -} - -/* insert */ -static void tt_tnt_net_insert(struct tt_test *test) { - tnt_stream_reqid(&net, 777); - struct tnt_tuple kv1; - tnt_tuple_init(&kv1); - tnt_tuple(&kv1, "%d%s", 123, "foo"); - TT_ASSERT(tnt_insert(&net, 0, 0, &kv1) > 0); - struct tnt_tuple kv2; - tnt_tuple_init(&kv2); - tnt_tuple(&kv2, "%d%s", 321, "bar"); - TT_ASSERT(tnt_insert(&net, 0, 0, &kv2) > 0); - TT_ASSERT(tnt_flush(&net) > 0); - tnt_tuple_free(&kv1); - tnt_tuple_free(&kv2); - struct tnt_iter i; - tnt_iter_reply(&i, &net); - while (tnt_next(&i)) { - struct tnt_reply *r = TNT_IREPLY_PTR(&i); - TT_ASSERT(r->reqid == 777); - TT_ASSERT(r->code == 0); - TT_ASSERT(r->op == TNT_OP_INSERT); - TT_ASSERT(r->count == 1); - } - tnt_iter_free(&i); -} - -/* update */ -static void tt_tnt_net_update(struct tt_test *test) { - struct tnt_stream ops; - TT_ASSERT(tnt_buf(&ops) != NULL); - tnt_update_arith(&ops, 0, TNT_UPDATE_ADD, 7); - tnt_update_assign(&ops, 1, "FOO", 3); - struct tnt_tuple *k = tnt_tuple(NULL, "%d", 123); - TT_ASSERT(tnt_update(&net, 0, 0, k, &ops) > 0); - tnt_tuple_free(k); - tnt_stream_free(&ops); - TT_ASSERT(tnt_flush(&net) > 0); - struct tnt_iter i; - tnt_iter_reply(&i, &net); - while (tnt_next(&i)) { - struct tnt_reply *r = TNT_IREPLY_PTR(&i); - TT_ASSERT(r->code == 0); - TT_ASSERT(r->op == TNT_OP_UPDATE); - TT_ASSERT(r->count == 1); - } -} - -/* select */ -static void tt_tnt_net_select(struct tt_test *test) { - struct tnt_list *search = - tnt_list(NULL, tnt_tuple(NULL, "%d", 130), NULL); - TT_ASSERT(tnt_select(&net, 0, 0, 0, 1, search) > 0); - TT_ASSERT(tnt_flush(&net) > 0); - tnt_list_free(search); - struct tnt_iter i; - tnt_iter_reply(&i, &net); - while (tnt_next(&i)) { - struct tnt_reply *r = TNT_IREPLY_PTR(&i); - TT_ASSERT(r->code == 0); - TT_ASSERT(r->op == TNT_OP_SELECT); - TT_ASSERT(r->count == 1); - struct tnt_iter il; - tnt_iter_list(&il, TNT_REPLY_LIST(r)); - TT_ASSERT(tnt_next(&il) == 1); - struct tnt_tuple *tp; - tp = TNT_ILIST_TUPLE(&il); - TT_ASSERT(tp->cardinality == 2); - TT_ASSERT(tp->alloc == 1); - TT_ASSERT(tp->data != NULL); - TT_ASSERT(tp->size != 0); - struct tnt_iter ifl; - tnt_iter(&ifl, tp); - TT_ASSERT(tnt_next(&ifl) == 1); - TT_ASSERT(TNT_IFIELD_IDX(&ifl) == 0); - TT_ASSERT(TNT_IFIELD_SIZE(&ifl) == 4); - TT_ASSERT(*(uint32_t*)TNT_IFIELD_DATA(&ifl) == 130); - TT_ASSERT(tnt_next(&ifl) == 1); - TT_ASSERT(TNT_IFIELD_IDX(&ifl) == 1); - TT_ASSERT(TNT_IFIELD_SIZE(&ifl) == 3); - TT_ASSERT(memcmp(TNT_IFIELD_DATA(&ifl), "FOO", 3) == 0); - TT_ASSERT(tnt_next(&ifl) == 0); - tnt_iter_free(&ifl); - tnt_iter_free(&il); - } -} - -/* delete */ -static void tt_tnt_net_delete(struct tt_test *test) { - struct tnt_tuple k; - tnt_tuple_init(&k); - tnt_tuple(&k, "%d", 321); - TT_ASSERT(tnt_delete(&net, 0, 0, &k) > 0); - TT_ASSERT(tnt_flush(&net) > 0); - tnt_tuple_free(&k); - struct tnt_iter i; - tnt_iter_reply(&i, &net); - while (tnt_next(&i)) { - struct tnt_reply *r = TNT_IREPLY_PTR(&i); - TT_ASSERT(r->code == 0); - TT_ASSERT(r->op == TNT_OP_DELETE); - TT_ASSERT(r->count == 1); - } - tnt_iter_free(&i); -} - -/* call */ -static void tt_tnt_net_call(struct tt_test *test) { - struct tnt_tuple args; - tnt_tuple_init(&args); - tnt_tuple(&args, "%s%d%s%s", "0", 333, "B", "C"); - TT_ASSERT(tnt_call(&net, 0, "box.insert", &args) > 0); - TT_ASSERT(tnt_flush(&net) > 0); - tnt_tuple_free(&args); - struct tnt_iter i; - tnt_iter_reply(&i, &net); - while (tnt_next(&i)) { - struct tnt_reply *r = TNT_IREPLY_PTR(&i); - TT_ASSERT(r->code == 0); - TT_ASSERT(r->op == TNT_OP_CALL); - TT_ASSERT(r->count == 1); - } - tnt_iter_free(&i); -} - -/* call (no args) */ -static void tt_tnt_net_call_na(struct tt_test *test) { - struct tnt_tuple args; - tnt_tuple_init(&args); - TT_ASSERT(tnt_call(&net, 0, "box.insert", &args) > 0); - TT_ASSERT(tnt_flush(&net) > 0); - tnt_tuple_free(&args); - struct tnt_iter i; - tnt_iter_reply(&i, &net); - while (tnt_next(&i)) { - struct tnt_reply *r = TNT_IREPLY_PTR(&i); - TT_ASSERT(r->code != 0); - TT_ASSERT(strstr(r->error, "box.pack") != NULL); - } - tnt_iter_free(&i); -} - -/* reply */ -static void tt_tnt_net_reply(struct tt_test *test) { - struct tnt_tuple kv1, kv2; - tnt_tuple_init(&kv1); - tnt_tuple(&kv1, "%d%s", 587, "foo"); - TT_ASSERT(tnt_insert(&net, 0, TNT_FLAG_RETURN, &kv1) > 0); - tnt_tuple_free(&kv1); - tnt_tuple_init(&kv2); - tnt_tuple(&kv2, "%d%s", 785, "bar"); - TT_ASSERT(tnt_insert(&net, 0, TNT_FLAG_RETURN, &kv2) > 0); - tnt_tuple_free(&kv2); - TT_ASSERT(tnt_flush(&net) > 0); - - struct tnt_stream_net *s = TNT_SNET_CAST(&net); - int current = 0; - size_t off = 0; - ssize_t size = 0; - char buffer[512]; - - while (current != 2) { - struct tnt_reply r; - tnt_reply_init(&r); - int rc = tnt_reply(&r, buffer, size, &off); - TT_ASSERT(rc != -1); - if (rc == 1) { - ssize_t res = tnt_io_recv_raw(s, buffer + size, off, 1); - TT_ASSERT(res > 0); - size += off; - continue; - } - TT_ASSERT(rc == 0); - TT_ASSERT(r.code == 0); - TT_ASSERT(r.op == TNT_OP_INSERT); - TT_ASSERT(r.count == 1); - if (current == 0) { - struct tnt_iter il; - tnt_iter_list(&il, TNT_REPLY_LIST(&r)); - TT_ASSERT(tnt_next(&il) == 1); - struct tnt_tuple *tp = TNT_ILIST_TUPLE(&il); - TT_ASSERT(tp->cardinality == 2); - TT_ASSERT(tp->alloc == 1); - TT_ASSERT(tp->data != NULL); - TT_ASSERT(tp->size != 0); - struct tnt_iter ifl; - tnt_iter(&ifl, tp); - TT_ASSERT(tnt_next(&ifl) == 1); - TT_ASSERT(TNT_IFIELD_IDX(&ifl) == 0); - TT_ASSERT(TNT_IFIELD_SIZE(&ifl) == 4); - TT_ASSERT(*(uint32_t*)TNT_IFIELD_DATA(&ifl) == 587); - TT_ASSERT(tnt_next(&ifl) == 1); - TT_ASSERT(TNT_IFIELD_IDX(&ifl) == 1); - TT_ASSERT(TNT_IFIELD_SIZE(&ifl) == 3); - TT_ASSERT(memcmp(TNT_IFIELD_DATA(&ifl), "foo", 3) == 0); - TT_ASSERT(tnt_next(&ifl) == 0); - tnt_iter_free(&ifl); - tnt_iter_free(&il); - off = 0; - size = 0; - } else - if (current == 1) { - struct tnt_iter il; - tnt_iter_list(&il, TNT_REPLY_LIST(&r)); - TT_ASSERT(tnt_next(&il) == 1); - struct tnt_tuple *tp = TNT_ILIST_TUPLE(&il); - TT_ASSERT(tp->cardinality == 2); - TT_ASSERT(tp->alloc == 1); - TT_ASSERT(tp->data != NULL); - TT_ASSERT(tp->size != 0); - struct tnt_iter ifl; - tnt_iter(&ifl, tp); - TT_ASSERT(tnt_next(&ifl) == 1); - TT_ASSERT(TNT_IFIELD_IDX(&ifl) == 0); - TT_ASSERT(TNT_IFIELD_SIZE(&ifl) == 4); - TT_ASSERT(*(uint32_t*)TNT_IFIELD_DATA(&ifl) == 785); - TT_ASSERT(tnt_next(&ifl) == 1); - TT_ASSERT(TNT_IFIELD_IDX(&ifl) == 1); - TT_ASSERT(TNT_IFIELD_SIZE(&ifl) == 3); - TT_ASSERT(memcmp(TNT_IFIELD_DATA(&ifl), "bar", 3) == 0); - TT_ASSERT(tnt_next(&ifl) == 0); - tnt_iter_free(&ifl); - tnt_iter_free(&il); - } - tnt_reply_free(&r); - current++; - } - - net.wrcnt -= 2; -} - -extern struct tnt_lex_keyword tnt_sql_keywords[]; - -/* lex ws */ -static void tt_tnt_lex_ws(struct tt_test *test) { - unsigned char sz[] = " # abcde fghjk ## hh\n # zzz\n#NOCR"; - struct tnt_lex l; - tnt_lex_init(&l, tnt_sql_keywords, sz, sizeof(sz) - 1); - struct tnt_tk *tk; - TT_ASSERT(tnt_lex(&l, &tk) == TNT_TK_EOF); - tnt_lex_free(&l); -} - -/* lex integer */ -static void tt_tnt_lex_int(struct tt_test *test) { - unsigned char sz[] = "\f\r\n 123 34\n\t\r56 888L56 2147483646 2147483647 " - "-2147483648 -2147483649 72057594037927935"; - struct tnt_lex l; - tnt_lex_init(&l, tnt_sql_keywords, sz, sizeof(sz) - 1); - struct tnt_tk *tk; - TT_ASSERT(tnt_lex(&l, &tk) == TNT_TK_NUM32 && TNT_TK_I32(tk) == 123); - TT_ASSERT(tnt_lex(&l, &tk) == TNT_TK_NUM32 && TNT_TK_I32(tk) == 34); - TT_ASSERT(tnt_lex(&l, &tk) == TNT_TK_NUM32 && TNT_TK_I32(tk) == 56); - TT_ASSERT(tnt_lex(&l, &tk) == TNT_TK_NUM64 && TNT_TK_I64(tk) == 888); - TT_ASSERT(tnt_lex(&l, &tk) == TNT_TK_NUM32 && TNT_TK_I32(tk) == 56); - - TT_ASSERT(tnt_lex(&l, &tk) == TNT_TK_NUM32 && TNT_TK_I32(tk) == INT_MAX - 1); - TT_ASSERT(tnt_lex(&l, &tk) == TNT_TK_NUM64 && TNT_TK_I64(tk) == INT_MAX); - TT_ASSERT(tnt_lex(&l, &tk) == TNT_TK_NUM32 && TNT_TK_I32(tk) == INT_MIN); - TT_ASSERT(tnt_lex(&l, &tk) == TNT_TK_NUM64 && TNT_TK_I64(tk) == INT_MIN - 1LL); - TT_ASSERT(tnt_lex(&l, &tk) == TNT_TK_NUM64 && TNT_TK_I64(tk) == 72057594037927935LL); - TT_ASSERT(tnt_lex(&l, &tk) == TNT_TK_EOF); - tnt_lex_free(&l); -} - -/* lex punctuation */ -static void tt_tnt_lex_punct(struct tt_test *test) { - unsigned char sz[] = "123,34\n-10\t:\r(56)"; - struct tnt_lex l; - tnt_lex_init(&l, tnt_sql_keywords, sz, sizeof(sz) - 1); - struct tnt_tk *tk; - TT_ASSERT(tnt_lex(&l, &tk) == TNT_TK_NUM32 && TNT_TK_I32(tk) == 123); - TT_ASSERT(tnt_lex(&l, &tk) == ',' && TNT_TK_I32(tk) == ','); - TT_ASSERT(tnt_lex(&l, &tk) == TNT_TK_NUM32 && TNT_TK_I32(tk) == 34); - TT_ASSERT(tnt_lex(&l, &tk) == TNT_TK_NUM32 && TNT_TK_I32(tk) == -10); - TT_ASSERT(tnt_lex(&l, &tk) == ':' && TNT_TK_I32(tk) == ':'); - TT_ASSERT(tnt_lex(&l, &tk) == '('&& TNT_TK_I32(tk) == '('); - TT_ASSERT(tnt_lex(&l, &tk) == TNT_TK_NUM32 && TNT_TK_I32(tk) == 56); - TT_ASSERT(tnt_lex(&l, &tk) == ')' && TNT_TK_I32(tk) == ')'); - TT_ASSERT(tnt_lex(&l, &tk) == TNT_TK_EOF); - tnt_lex_free(&l); -} - -/* lex string */ -static void tt_tnt_lex_str(struct tt_test *test) { - unsigned char sz[] = " 'hello'\n\t 'world' 'вÑем привет!'"; - struct tnt_lex l; - tnt_lex_init(&l, tnt_sql_keywords, sz, sizeof(sz) - 1); - struct tnt_tk *tk; - TT_ASSERT(tnt_lex(&l, &tk) == TNT_TK_STRING && - TNT_TK_S(tk)->size == 5 && - memcmp(TNT_TK_S(tk)->data, "hello", 5) == 0); - TT_ASSERT(tnt_lex(&l, &tk) == TNT_TK_STRING && - TNT_TK_S(tk)->size == 5 && - memcmp(TNT_TK_S(tk)->data, "world", 5) == 0); - TT_ASSERT(tnt_lex(&l, &tk) == TNT_TK_STRING && - TNT_TK_S(tk)->size == 22 && - memcmp(TNT_TK_S(tk)->data, "вÑем привет!", 22) == 0); - TT_ASSERT(tnt_lex(&l, &tk) == TNT_TK_EOF); - tnt_lex_free(&l); -} - -/* lex id's */ -static void tt_tnt_lex_ids(struct tt_test *test) { - unsigned char sz[] = " hello\nÑтот безумный безумный мир\t world "; - struct tnt_lex l; - tnt_lex_init(&l, tnt_sql_keywords, sz, sizeof(sz) - 1); - struct tnt_tk *tk; - TT_ASSERT(tnt_lex(&l, &tk) == TNT_TK_ID && - TNT_TK_S(tk)->size == 5 && - memcmp(TNT_TK_S(tk)->data, "hello", 5) == 0); - TT_ASSERT(tnt_lex(&l, &tk) == TNT_TK_ID && - TNT_TK_S(tk)->size == 8 && - memcmp(TNT_TK_S(tk)->data, "Ñтот", 8) == 0); - TT_ASSERT(tnt_lex(&l, &tk) == TNT_TK_ID && - TNT_TK_S(tk)->size == 16 && - memcmp(TNT_TK_S(tk)->data, "безумный", 16) == 0); - TT_ASSERT(tnt_lex(&l, &tk) == TNT_TK_ID && - TNT_TK_S(tk)->size == 16 && - memcmp(TNT_TK_S(tk)->data, "безумный", 16) == 0); - TT_ASSERT(tnt_lex(&l, &tk) == TNT_TK_ID && - TNT_TK_S(tk)->size == 6 && - memcmp(TNT_TK_S(tk)->data, "мир", 6) == 0); - TT_ASSERT(tnt_lex(&l, &tk) == TNT_TK_ID && - TNT_TK_S(tk)->size == 5 && - memcmp(TNT_TK_S(tk)->data, "world", 5) == 0); - TT_ASSERT(tnt_lex(&l, &tk) == TNT_TK_EOF); - tnt_lex_free(&l); -} - -/* lex keys and tables */ -static void tt_tnt_lex_kt(struct tt_test *test) { - unsigned char sz[] = " k0\n\tk20 t0 k1000 t55 k001 t8"; - struct tnt_lex l; - tnt_lex_init(&l, tnt_sql_keywords, sz, sizeof(sz) - 1); - struct tnt_tk *tk; - TT_ASSERT(tnt_lex(&l, &tk) == TNT_TK_KEY && TNT_TK_I32(tk) == 0); - TT_ASSERT(tnt_lex(&l, &tk) == TNT_TK_KEY && TNT_TK_I32(tk) == 20); - TT_ASSERT(tnt_lex(&l, &tk) == TNT_TK_TABLE && TNT_TK_I32(tk) == 0); - TT_ASSERT(tnt_lex(&l, &tk) == TNT_TK_KEY && TNT_TK_I32(tk) == 1000); - TT_ASSERT(tnt_lex(&l, &tk) == TNT_TK_TABLE && TNT_TK_I32(tk) == 55); - TT_ASSERT(tnt_lex(&l, &tk) == TNT_TK_KEY && TNT_TK_I32(tk) == 1); - TT_ASSERT(tnt_lex(&l, &tk) == TNT_TK_TABLE && TNT_TK_I32(tk) == 8); - TT_ASSERT(tnt_lex(&l, &tk) == TNT_TK_EOF); - tnt_lex_free(&l); -} - -/* lex keywords */ -static void tt_tnt_lex_kw(struct tt_test *test) { - unsigned char sz[] = " INSERT UPDATE INTO OR FROM WHERE VALUES"; - struct tnt_lex l; - tnt_lex_init(&l, tnt_sql_keywords, sz, sizeof(sz) - 1); - struct tnt_tk *tk; - TT_ASSERT(tnt_lex(&l, &tk) == TNT_TK_INSERT); - TT_ASSERT(tnt_lex(&l, &tk) == TNT_TK_UPDATE); - TT_ASSERT(tnt_lex(&l, &tk) == TNT_TK_INTO); - TT_ASSERT(tnt_lex(&l, &tk) == TNT_TK_OR); - TT_ASSERT(tnt_lex(&l, &tk) == TNT_TK_FROM); - TT_ASSERT(tnt_lex(&l, &tk) == TNT_TK_WHERE); - TT_ASSERT(tnt_lex(&l, &tk) == TNT_TK_VALUES); - TT_ASSERT(tnt_lex(&l, &tk) == TNT_TK_EOF); - tnt_lex_free(&l); -} - -/* lex stack */ -static void tt_tnt_lex_stack(struct tt_test *test) { - unsigned char sz[] = " 1 'hey' ,.55"; - struct tnt_lex l; - tnt_lex_init(&l, tnt_sql_keywords, sz, sizeof(sz) - 1); - struct tnt_tk *tk1, *tk2, *tk3, *tk4, *tk5, *tk6; - TT_ASSERT(tnt_lex(&l, &tk1) == TNT_TK_NUM32); - TT_ASSERT(tnt_lex(&l, &tk2) == TNT_TK_STRING); - TT_ASSERT(tnt_lex(&l, &tk3) == ','); - TT_ASSERT(tnt_lex(&l, &tk4) == '.'); - TT_ASSERT(tnt_lex(&l, &tk5) == TNT_TK_NUM32); - TT_ASSERT(tnt_lex(&l, &tk6) == TNT_TK_EOF); - tnt_lex_push(&l, tk5); - tnt_lex_push(&l, tk4); - tnt_lex_push(&l, tk3); - tnt_lex_push(&l, tk2); - tnt_lex_push(&l, tk1); - TT_ASSERT(tnt_lex(&l, &tk1) == TNT_TK_NUM32); - TT_ASSERT(tnt_lex(&l, &tk2) == TNT_TK_STRING); - TT_ASSERT(tnt_lex(&l, &tk3) == ','); - TT_ASSERT(tnt_lex(&l, &tk4) == '.'); - TT_ASSERT(tnt_lex(&l, &tk5) == TNT_TK_NUM32); - TT_ASSERT(tnt_lex(&l, &tk6) == TNT_TK_EOF); - tnt_lex_free(&l); -} - -/* lex bad string 1 */ -static void tt_tnt_lex_badstr1(struct tt_test *test) { - unsigned char sz[] = " '"; - struct tnt_lex l; - tnt_lex_init(&l, tnt_sql_keywords, sz, sizeof(sz) - 1); - struct tnt_tk *tk; - TT_ASSERT(tnt_lex(&l, &tk) == TNT_TK_ERROR); - tnt_lex_free(&l); - -} - -/* lex bad string 2 */ -static void tt_tnt_lex_badstr2(struct tt_test *test) { - unsigned char sz[] = " '\n'"; - struct tnt_lex l; - tnt_lex_init(&l, tnt_sql_keywords, sz, sizeof(sz) - 1); - struct tnt_tk *tk; - TT_ASSERT(tnt_lex(&l, &tk) == TNT_TK_ERROR); - tnt_lex_free(&l); -} - -/* sql ping */ -static void tt_tnt_sql_ping(struct tt_test *test) { - char *e = NULL; - char q[] = "PING"; - TT_ASSERT(tnt_query(&net, q, sizeof(q) - 1, &e) == 0); - TT_ASSERT(tnt_flush(&net) > 0); - struct tnt_iter i; - tnt_iter_reply(&i, &net); - while (tnt_next(&i)) { - struct tnt_reply *r = TNT_IREPLY_PTR(&i); - TT_ASSERT(r->code == 0); - TT_ASSERT(r->op == TNT_OP_PING); - } - tnt_iter_free(&i); -} - -/* sql insert */ -static void tt_tnt_sql_insert(struct tt_test *test) { - char *e = NULL; - char q[] = "insert into t0 values (222, 'baz')"; - TT_ASSERT(tnt_query(&net, q, sizeof(q) - 1, &e) == 0); - TT_ASSERT(tnt_flush(&net) > 0); - struct tnt_iter i; - tnt_iter_reply(&i, &net); - while (tnt_next(&i)) { - struct tnt_reply *r = TNT_IREPLY_PTR(&i); - TT_ASSERT(r->code == 0); - TT_ASSERT(r->op == TNT_OP_INSERT); - TT_ASSERT(r->count == 1); - } - tnt_iter_free(&i); -} - -/* sql update */ -static void tt_tnt_sql_update(struct tt_test *test) { - char *e; - char q1[] = "update t0 set k0 = 7 where k0 = 222"; - TT_ASSERT(tnt_query(&net, q1, sizeof(q1) - 1, &e) == 0); - /* 7 + 1 = 8 */ - char q2[] = "update t0 set k0 = k0 + 1 where k0 = 7"; - TT_ASSERT(tnt_query(&net, q2, sizeof(q2) - 1, &e) == 0); - /* 8 | 2 = 10 */ - char q3[] = "update t0 set k0 = k0 | 2 where k0 = 8"; - TT_ASSERT(tnt_query(&net, q3, sizeof(q3) - 1, &e) == 0); - /* 10 & 2 = 2 */ - char q4[] = "update t0 set k0 = k0 & 2 where k0 = 10"; - TT_ASSERT(tnt_query(&net, q4, sizeof(q4) - 1, &e) == 0); - /* 2 ^ 123 = 121 */ - char q5[] = "update t0 set k0 = k0 ^ 123 where k0 = 2"; - TT_ASSERT(tnt_query(&net, q5, sizeof(q5) - 1, &e) == 0); - /* assign */ - char q6[] = "update t0 set k0 = 222, k1 = 'hello world' where k0 = 121"; - TT_ASSERT(tnt_query(&net, q6, sizeof(q6) - 1, &e) == 0); - /* splice */ - char q7[] = "update t0 set k1 = splice(k1, 0, 2, 'AB') where k0 = 222"; - TT_ASSERT(tnt_query(&net, q7, sizeof(q7) - 1, &e) == 0); - TT_ASSERT(tnt_flush(&net) > 0); - struct tnt_iter i; - tnt_iter_reply(&i, &net); - while (tnt_next(&i)) { - struct tnt_reply *r = TNT_IREPLY_PTR(&i); - TT_ASSERT(r->code == 0); - TT_ASSERT(r->op == TNT_OP_UPDATE); - TT_ASSERT(r->count == 1); - } - tnt_iter_free(&i); -} - -/* sql select */ -static void tt_tnt_sql_select(struct tt_test *test) { - char *e = NULL; - char q[] = "select * from t0 where k0 = 222 or k0 = 222"; - TT_ASSERT(tnt_query(&net, q, sizeof(q) - 1, &e) == 0); - TT_ASSERT(tnt_flush(&net) > 0); - struct tnt_iter i; - tnt_iter_reply(&i, &net); - while (tnt_next(&i)) { - struct tnt_reply *r = TNT_IREPLY_PTR(&i); - TT_ASSERT(r->code == 0); - TT_ASSERT(r->op == TNT_OP_SELECT); - TT_ASSERT(r->count == 2); - struct tnt_iter il; - tnt_iter_list(&il, TNT_REPLY_LIST(r)); - TT_ASSERT(tnt_next(&il) == 1); - struct tnt_tuple *tp; - tp = TNT_ILIST_TUPLE(&il); - TT_ASSERT(tp->cardinality == 2); - TT_ASSERT(tp->alloc == 1); - TT_ASSERT(tp->data != NULL); - TT_ASSERT(tp->size != 0); - struct tnt_iter ifl; - tnt_iter(&ifl, tp); - TT_ASSERT(tnt_next(&ifl) == 1); - TT_ASSERT(TNT_IFIELD_IDX(&ifl) == 0); - TT_ASSERT(TNT_IFIELD_SIZE(&ifl) == 4); - TT_ASSERT(*(uint32_t*)TNT_IFIELD_DATA(&ifl) == 222); - TT_ASSERT(tnt_next(&ifl) == 1); - TT_ASSERT(TNT_IFIELD_IDX(&ifl) == 1); - TT_ASSERT(TNT_IFIELD_SIZE(&ifl) == 11); - TT_ASSERT(memcmp(TNT_IFIELD_DATA(&ifl), "ABllo world", 11) == 0); - TT_ASSERT(tnt_next(&ifl) == 0); - tnt_iter_free(&ifl); - tnt_iter_free(&il); - } - tnt_iter_free(&i); -} - -/* sql select limit */ -static void tt_tnt_sql_select_limit(struct tt_test *test) { - char *e = NULL; - char q[] = "select * from t0 where k0 = 222 limit 0"; - TT_ASSERT(tnt_query(&net, q, sizeof(q) - 1, &e) == 0); - TT_ASSERT(tnt_flush(&net) > 0); - struct tnt_iter i; - tnt_iter_reply(&i, &net); - while (tnt_next(&i)) { - struct tnt_reply *r = TNT_IREPLY_PTR(&i); - TT_ASSERT(r->code == 0); - TT_ASSERT(r->op == TNT_OP_SELECT); - TT_ASSERT(r->count == 0); - } - tnt_iter_free(&i); -} - -/* sql delete */ -static void tt_tnt_sql_delete(struct tt_test *test) { - char *e = NULL; - char q[] = "delete from t0 where k0 = 222"; - TT_ASSERT(tnt_query(&net, q, sizeof(q) - 1, &e) == 0); - TT_ASSERT(tnt_flush(&net) > 0); - struct tnt_iter i; - tnt_iter_reply(&i, &net); - while (tnt_next(&i)) { - struct tnt_reply *r = TNT_IREPLY_PTR(&i); - TT_ASSERT(r->code == 0); - TT_ASSERT(r->op == TNT_OP_DELETE); - TT_ASSERT(r->count == 1); - } - tnt_iter_free(&i); -} - -/* sql call */ -static void tt_tnt_sql_call(struct tt_test *test) { - char *e = NULL; - char q[] = "call box.insert('0', 454, 'abc', 'cba')"; - TT_ASSERT(tnt_query(&net, q, sizeof(q) - 1, &e) == 0); - TT_ASSERT(tnt_flush(&net) > 0); - struct tnt_iter i; - tnt_iter_reply(&i, &net); - while (tnt_next(&i)) { - struct tnt_reply *r = TNT_IREPLY_PTR(&i); - TT_ASSERT(r->code == 0); - TT_ASSERT(r->op == TNT_OP_CALL); - TT_ASSERT(r->count == 1); - } - tnt_iter_free(&i); -} - -int -main(int argc, char * argv[]) -{ - (void)argc, (void)argv; - - struct tt_list t; - memset(&t, 0, sizeof(t)); - - /* common data manipulation */ - tt_test(&t, "tuple1", tt_tnt_tuple1); - tt_test(&t, "tuple2", tt_tnt_tuple2); - tt_test(&t, "list", tt_tnt_list); - tt_test(&t, "stream buffer", tt_tnt_sbuf); - tt_test(&t, "tuple set", tt_tnt_tuple_set); - tt_test(&t, "iterator tuple", tt_tnt_iter1); - tt_test(&t, "iterator tuple (single field)", tt_tnt_iter11); - tt_test(&t, "iterator tuple (tnt_field)", tt_tnt_iter2); - tt_test(&t, "iterator tuple (empty)", tt_tnt_iter4); - tt_test(&t, "iterator list", tt_tnt_iter3); - /* marshaling */ - tt_test(&t, "marshaling ping", tt_tnt_marshal_ping); - tt_test(&t, "marshaling insert", tt_tnt_marshal_insert); - tt_test(&t, "marshaling delete", tt_tnt_marshal_delete); - tt_test(&t, "marshaling call", tt_tnt_marshal_call); - tt_test(&t, "marshaling select", tt_tnt_marshal_select); - tt_test(&t, "marshaling update", tt_tnt_marshal_update); - /* common operations */ - tt_test(&t, "connect", tt_tnt_net_connect); - tt_test(&t, "ping", tt_tnt_net_ping); - tt_test(&t, "insert", tt_tnt_net_insert); - tt_test(&t, "update", tt_tnt_net_update); - tt_test(&t, "select", tt_tnt_net_select); - tt_test(&t, "delete", tt_tnt_net_delete); - tt_test(&t, "call", tt_tnt_net_call); - tt_test(&t, "call (no args)", tt_tnt_net_call_na); - tt_test(&t, "reply", tt_tnt_net_reply); - /* sql lexer */ - tt_test(&t, "lex ws", tt_tnt_lex_ws); - tt_test(&t, "lex integer", tt_tnt_lex_int); - tt_test(&t, "lex string", tt_tnt_lex_str); - tt_test(&t, "lex punctuation", tt_tnt_lex_punct); - tt_test(&t, "lex ids", tt_tnt_lex_ids); - tt_test(&t, "lex keywords", tt_tnt_lex_kw); - tt_test(&t, "lex keys and tables", tt_tnt_lex_kt); - tt_test(&t, "lex stack", tt_tnt_lex_stack); - tt_test(&t, "lex bad string1", tt_tnt_lex_badstr1); - tt_test(&t, "lex bad string2", tt_tnt_lex_badstr2); - /* sql stmts */ - tt_test(&t, "sql ping", tt_tnt_sql_ping); - tt_test(&t, "sql insert", tt_tnt_sql_insert); - tt_test(&t, "sql update", tt_tnt_sql_update); - tt_test(&t, "sql select", tt_tnt_sql_select); - tt_test(&t, "sql select limit", tt_tnt_sql_select_limit); - tt_test(&t, "sql delete", tt_tnt_sql_delete); - tt_test(&t, "sql call", tt_tnt_sql_call); - - tt_run(&t); - tt_free(&t); - - tnt_stream_free(&net); - return 0; -} diff --git a/test/connector_c/update.c b/test/connector_c/update.c deleted file mode 100644 index 4f357d7c1fee396770c7f2467058340816a88c7f..0000000000000000000000000000000000000000 --- a/test/connector_c/update.c +++ /dev/null @@ -1,992 +0,0 @@ - -/* - * Copyright (C) 2011 Mail.RU - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include <stdlib.h> -#include <stdio.h> -#include <stdbool.h> -#include <string.h> -#include <limits.h> - -#include <connector/c/include/tarantool/tnt.h> -#include <connector/c/include/tarantool/tnt_net.h> -#include <connector/c/include/tarantool/tnt_io.h> - -#include "tarantool/util.h" -#include <errcode.h> -#include <unit.h> - -/*========================================================================== - * test variables - *==========================================================================*/ - -/** tarantool connector instance */ -static struct tnt_stream *tnt; - -static char *long_string = "A long time ago, in a galaxy far, far away...\n" - "It is a period of civil war. Rebel\n" - "spaceships, striking from a hidden\n" - "base, have won their first victory\n" - "against the evil Galactic Empire.\n" - "During the battle, Rebel spies managed\n" - "to steal secret plans to the Empire's\n" - "ultimate weapon, the Death Star, an\n" - "armored space station with enough\n" - "power to destroy an entire planet.\n" - "Pursued by the Empire's sinister agents,\n" - "Princess Leia races home aboard her\n" - "starship, custodian of the stolen plans\n" - "that can save her people and restore\n" - "freedom to the galaxy...."; - -/*========================================================================== - * function declaration - *==========================================================================*/ - -/*-------------------------------------------------------------------------- - * tarantool management functions - *--------------------------------------------------------------------------*/ - -/** insert tuple */ -void -insert_tuple(struct tnt_tuple *tuple); - -/** select tuple by key */ -void -select_tuple(int32_t key); - -/** update fields */ -void -update(int32_t key, struct tnt_stream *stream); - -/** add update fields operation: set int32 */ -void -update_set_i32(struct tnt_stream *stream, int32_t field, int32_t value); - -/** add update fields operation: set string */ -void -update_set_str(struct tnt_stream *stream, int32_t field, char *str); - -/** add update fields operation: splice string */ -void -update_splice_str(struct tnt_stream *stream, int32_t field, int32_t offset, int32_t length, - char *list); - -/** add update fields operation: delete field */ -void -update_delete_field(struct tnt_stream *stream, int32_t field); - -/** add update fields operation: insert before int32 */ -void -update_insert_i32(struct tnt_stream *stream, int32_t field, int32_t value); - -/** add update fields operation: insert before string */ -void -update_insert_str(struct tnt_stream *stream, int32_t field, char *str); - -/** receive reply from server */ -void -recv_command(char *command); - -/** print tuple */ -void -print_tuple(struct tnt_tuple *tuple); - -/*-------------------------------------------------------------------------- - * test suite functions - *--------------------------------------------------------------------------*/ - -/** setup test suite */ -void -test_suite_setup(); - -/** clean-up test suite */ -void -test_suite_tear_down(); - -/** print tarantool error message and exit */ -void -fail_tnt_error(char *msg, int error_code); - -/** print tarantool error message and exit */ -void -fail_tnt_perror(char *msg); - - -/*-------------------------------------------------------------------------- - * test cases functions - *--------------------------------------------------------------------------*/ - -/** update fields test case: simple set operation test */ -void -test_simple_set(); - -/** update fields test case: long set operation test */ -void -test_long_set(); - -/** update fields test case: append(set) operation test */ -void -test_append(); - -/** update fields test case: 32-bit arithmetics operations test */ -void -test_arith_i32(); - -/** update fields test case: 64-bit arithmetics operations test */ -void -test_arith_i64(); - -/** update fields test case: multi arithmetics operations test */ -void -test_multi_arith(); - -/** update fields test case: splice operations test */ -void -test_splice(); - -/** update fields test case: set and spice operations test */ -void -test_set_and_splice(); - -/** update fields test case: delete field operations test */ -void -test_delete_field(); - -/** update fields test case: insert field operations test */ -void -test_insert_field(); - -/** update fields test case: boundary arguments values test */ -void -test_boundary_args(); - - -/*========================================================================== - * function definition - *==========================================================================*/ - -int -main() -{ - /* initialize suite */ - test_suite_setup(); - /* run tests */ - test_simple_set(); - test_long_set(); - test_append(); - test_arith_i32(); - test_arith_i64(); - test_multi_arith(); - test_splice(); - test_set_and_splice(); - test_delete_field(); - test_insert_field(); - test_boundary_args(); - /* clean-up suite */ - test_suite_tear_down(); - return EXIT_SUCCESS; -} - - -/*-------------------------------------------------------------------------- - * tarantool management functions - *--------------------------------------------------------------------------*/ - -void -insert_tuple(struct tnt_tuple *tuple) -{ - if (tnt_insert(tnt, 0, TNT_FLAG_RETURN, tuple) < 0) - fail_tnt_perror("tnt_insert"); - if (tnt_flush(tnt) < 0) - fail_tnt_perror("tnt_flush"); - recv_command("insert"); -} - -void -select_tuple(int32_t key) -{ - struct tnt_list tuple_list; - tnt_list_init(&tuple_list); - struct tnt_tuple *tuple = tnt_list_at(&tuple_list, NULL); - tnt_tuple(tuple, "%d", key); - if (tnt_select(tnt, 0, 0, 0, 1, &tuple_list) < 0) - fail_tnt_perror("tnt_select"); - if (tnt_flush(tnt) < 0) - fail_tnt_perror("tnt_flush"); - recv_command("select"); - tnt_list_free(&tuple_list); -} - -void -update(int32_t key, struct tnt_stream *stream) -{ - struct tnt_tuple *k = tnt_tuple(NULL, "%d", key); - if (tnt_update(tnt, 0, TNT_FLAG_RETURN, k, stream) < 0) - fail_tnt_perror("tnt_update"); - if (tnt_flush(tnt) < 0) - fail_tnt_perror("tnt_flush"); - tnt_tuple_free(k); - recv_command("update fields"); -} - -void -update_set_i32(struct tnt_stream *stream, int32_t field, int32_t value) -{ - int result = tnt_update_assign(stream, field, (char *)&value, sizeof(value)); - if (result < 0) - fail_tnt_error("tnt_update_assign", result); -} - -void -update_set_str(struct tnt_stream *stream, int32_t field, char *str) -{ - int result = tnt_update_assign(stream, field, str, strlen(str)); - if (result < 0) - fail_tnt_error("tnt_update_assign", result); -} - -void -update_splice_str(struct tnt_stream *stream, int32_t field, int32_t offset, int32_t length, - char *list) -{ - int result = tnt_update_splice(stream, field, offset, length, list, - strlen(list)); - if (result < 0) - fail_tnt_error("tnt_update_splice", result); -} - -void -update_delete_field(struct tnt_stream *stream, int32_t field) -{ - int result = tnt_update_delete(stream, field); - if (result < 0) - fail_tnt_error("tnt_update_delete", result); -} - -void -update_insert_i32(struct tnt_stream *stream, int32_t field, int32_t value) -{ - int result = tnt_update_insert(stream, field, (char *)&value, - sizeof(value)); - if (result < 0) - fail_tnt_error("tnt_update_insert", result); -} - -void -update_insert_str(struct tnt_stream *stream, int32_t field, char *str) -{ - int result = tnt_update_insert(stream, field, str, strlen(str)); - if (result < 0) - fail_tnt_error("tnt_update_insert_before", result); -} - -void -recv_command(char *command) -{ - struct tnt_iter i; - tnt_iter_reply(&i, tnt); - while (tnt_next(&i)) { - struct tnt_reply *r = TNT_IREPLY_PTR(&i); - printf("%s: respond %s (op: %"PRIu32", reqid: %"PRIu32", code: %"PRIu32", count: %"PRIu32")\n", - command, tnt_strerror(tnt), - r->op, - r->reqid, - r->code, - r->count); - struct tnt_iter it; - tnt_iter_list(&it, TNT_REPLY_LIST(r)); - while (tnt_next(&it)) { - struct tnt_tuple *tu = TNT_ILIST_TUPLE(&it); - print_tuple(tu); - } - tnt_iter_free(&it); - } - if (i.status == TNT_ITER_FAIL) - fail_tnt_perror("tnt_next"); - tnt_iter_free(&i); -} - -void -print_tuple(struct tnt_tuple *tuple) -{ - bool is_first = true; - printf("("); - - struct tnt_iter ifl; - tnt_iter(&ifl, tuple); - while (tnt_next(&ifl)) { - char *data = TNT_IFIELD_DATA(&ifl); - uint32_t size = TNT_IFIELD_SIZE(&ifl); - if (!is_first) { - printf(", "); - } - is_first = false; - - switch(size) { - case 1: - printf("%"PRIi8" (0x%02"PRIx8")", *(int8_t *)data, *(int8_t *)data); - break; - case 2: - printf("%"PRIi16" (0x%04"PRIx16")", *(int16_t *)data, *(int16_t *)data); - break; - case 4: - printf("%"PRIi32" (0x%08"PRIx32")", *(int32_t *)data, *(int32_t *)data); - break; - case 8: - printf("%"PRIi64" (0x%016"PRIx64")", *(int64_t *)data, *(int64_t *)data); - break; - default: - printf("'%.*s'", size, data); - break; - } - } - fail_if(ifl.status == TNT_ITER_FAIL); - tnt_iter_free(&ifl); - printf(")\n"); -} - - -/*-------------------------------------------------------------------------- - * test suite functions - *--------------------------------------------------------------------------*/ - -void -test_suite_setup() -{ - tnt = tnt_net(NULL); - fail_if(tnt == NULL); - - tnt_set(tnt, TNT_OPT_HOSTNAME, "localhost"); - tnt_set(tnt, TNT_OPT_PORT, 33013); - tnt_set(tnt, TNT_OPT_SEND_BUF, 128000); - - if (tnt_init(tnt) == -1) - fail_tnt_perror("tnt_init"); - if (tnt_connect(tnt) == -1) - fail_tnt_perror("tnt_connect"); -} - -void -test_suite_tear_down() -{ - tnt_stream_free(tnt); -} - -void -fail_tnt_error(char *msg, int error_code) -{ - printf("fail: %s: %i\n", msg, error_code); - exit(EXIT_FAILURE); -} - -void -fail_tnt_perror(char *msg) -{ - printf("fail: %s: %s\n", msg, tnt_strerror(tnt)); - exit(EXIT_FAILURE); -} - - -/*-------------------------------------------------------------------------- - * test cases functions - *--------------------------------------------------------------------------*/ - -void -test_simple_set() -{ - header(); - - /* insert tuple */ - printf("# insert tuple\n"); - struct tnt_tuple *tuple = tnt_tuple(NULL, "%d%d%d%s", 1, 2, 0, ""); - insert_tuple(tuple); - tnt_tuple_free(tuple); - - printf("# test simple set field\n"); - struct tnt_stream *stream = tnt_buf(NULL); - update_set_str(stream, 1, "new field value"); - update_set_str(stream, 2, ""); - update_set_str(stream, 3, "fLaC"); - update(1, stream); - tnt_stream_free(stream); - - printf("# set field\n"); - stream = tnt_buf(NULL); - update_set_str(stream, 1, "value?"); - update_set_str(stream, 1, "very very very very very long field value?"); - update_set_str(stream, 1, "field's new value"); - update(1, stream); - tnt_stream_free(stream); - - stream = tnt_buf(NULL); - printf("# test set primary key\n"); - update_set_i32(stream, 0, 2); - update(1, stream); - tnt_stream_free(stream); - - footer(); -} - -void -test_long_set() -{ - header(); - - printf("# insert tuple\n"); - struct tnt_tuple *tuple = tnt_tuple(NULL, "%d%s%s%s", - 1, "first", "", "third"); - insert_tuple(tuple); - tnt_tuple_free(tuple); - - printf("# test set big value in empty field\n"); - struct tnt_stream *stream = tnt_buf(NULL); - update_set_str(stream, 2, long_string); - update(1, stream); - tnt_stream_free(stream); - - printf("# test replace long value to short\n"); - stream = tnt_buf(NULL); - update_set_str(stream, 2, "short string"); - update(1, stream); - tnt_stream_free(stream); - - footer(); -} - -void -test_append() -{ - header(); - - /* insert tuple */ - printf("# insert tuple\n"); - struct tnt_tuple *tuple = tnt_tuple(NULL, "%d%s", 1, "first"); - insert_tuple(tuple); - tnt_tuple_free(tuple); - - /* test append field */ - struct tnt_stream *stream = tnt_buf(NULL); - printf("# test append field\n"); - update_set_str(stream, 2, "second"); - update(1, stream); - tnt_stream_free(stream); - - /* test multi append field */ - stream = tnt_buf(NULL); - printf("# test multi append\n"); - update_set_str(stream, 3, "3"); - update_set_str(stream, 3, "new field value"); - update_set_str(stream, 3, "other new field value"); - update_set_str(stream, 3, "third"); - update(1, stream); - tnt_stream_free(stream); - - /* test append many field */ - stream = tnt_buf(NULL); - printf("# test append many fields\n"); - update_set_str(stream, 4, "fourth"); - update_set_str(stream, 5, "fifth"); - update_set_str(stream, 6, "sixth"); - update_set_str(stream, 7, "seventh"); - update_set_str(stream, 8, long_string); - update(1, stream); - tnt_stream_free(stream); - - /* test append and change field */ - stream = tnt_buf(NULL); - printf("# test append and change field\n"); - update_set_str(stream, 9, long_string); - update_splice_str(stream, 9, 1, 544, "ac"); - tnt_update_arith_i32(stream, 9, TNT_UPDATE_XOR, 0x3ffffff); - tnt_update_arith_i32(stream, 9, TNT_UPDATE_ADD, 1024); - update(1, stream); - tnt_stream_free(stream); - - /* test set to not an exist field */ - stream = tnt_buf(NULL); - printf("# test set to not an exist field\n"); - update_set_str(stream, 0xDEADBEEF, "invalid!"); - update(1, stream); - tnt_stream_free(stream); - - footer(); -} - -void -test_arith_i32() -{ - header(); - - printf("# insert tuple\n"); - struct tnt_tuple *tuple = tnt_tuple(NULL, "%d%d%d%d", 1, 2, 0, 0); - insert_tuple(tuple); - tnt_tuple_free(tuple); - - printf("# test add\n"); - struct tnt_stream *stream = tnt_buf(NULL); - tnt_update_arith_i32(stream, 1, TNT_UPDATE_ADD, 16); - update(1, stream); - tnt_stream_free(stream); - - printf("# test overflow add\n"); - stream = tnt_buf(NULL); - tnt_update_arith_i32(stream, 1, TNT_UPDATE_ADD, INT32_MAX); - update(1, stream); - tnt_stream_free(stream); - - printf("# test underflow add\n"); - stream = tnt_buf(NULL); - tnt_update_arith_i32(stream, 1, TNT_UPDATE_ADD, INT32_MIN); - update(1, stream); - tnt_stream_free(stream); - - printf("# test or\n"); - stream = tnt_buf(NULL); - tnt_update_arith_i32(stream, 2, TNT_UPDATE_OR, 0xbacfbacf); - tnt_update_arith_i32(stream, 3, TNT_UPDATE_OR, 0xfabcfabc); - update(1, stream); - tnt_stream_free(stream); - - printf("# test xor\n"); - stream = tnt_buf(NULL); - tnt_update_arith_i32(stream, 2, TNT_UPDATE_XOR, 0xffffffff); - tnt_update_arith_i32(stream, 3, TNT_UPDATE_XOR, 0xffffffff); - update(1, stream); - tnt_stream_free(stream); - - printf("# test and\n"); - stream = tnt_buf(NULL); - tnt_update_arith_i32(stream, 2, TNT_UPDATE_AND, 0xf0f0f0f0); - tnt_update_arith_i32(stream, 3, TNT_UPDATE_AND, 0x0f0f0f0f); - update(1, stream); - tnt_stream_free(stream); - - footer(); -} - -/** update fields test case: 64-bit arithmetics operations test */ -void -test_arith_i64() -{ - header(); - - printf("# insert tuple\n"); - struct tnt_tuple *tuple = tnt_tuple(NULL, "%d%ll%ll%ll", 1, 2, 0, 0, 0); - insert_tuple(tuple); - tnt_tuple_free(tuple); - - printf("# test add\n"); - struct tnt_stream *stream = tnt_buf(NULL); - tnt_update_arith_i64(stream, 1, TNT_UPDATE_ADD, 16); - update(1, stream); - tnt_stream_free(stream); - - printf("# test overflow add\n"); - stream = tnt_buf(NULL); - tnt_update_arith_i64(stream, 1, TNT_UPDATE_ADD, INT64_MAX); - update(1, stream); - tnt_stream_free(stream); - - printf("# test underflow add\n"); - stream = tnt_buf(NULL); - tnt_update_arith_i64(stream, 1, TNT_UPDATE_ADD, INT64_MIN); - update(1, stream); - tnt_stream_free(stream); - - printf("# test or\n"); - stream = tnt_buf(NULL); - tnt_update_arith_i64(stream, 2, TNT_UPDATE_OR, 0xbacfbacfbacfbacf); - tnt_update_arith_i64(stream, 3, TNT_UPDATE_OR, 0xfabcfabcfabcfabc); - update(1, stream); - tnt_stream_free(stream); - - printf("# test xor\n"); - stream = tnt_buf(NULL); - tnt_update_arith_i64(stream, 2, TNT_UPDATE_XOR, 0xffffffffffffffff); - tnt_update_arith_i64(stream, 3, TNT_UPDATE_XOR, 0xffffffffffffffff); - update(1, stream); - tnt_stream_free(stream); - - printf("# test and\n"); - stream = tnt_buf(NULL); - tnt_update_arith_i64(stream, 2, TNT_UPDATE_AND, 0xf0f0f0f0f0f0f0f0); - tnt_update_arith_i64(stream, 3, TNT_UPDATE_AND, 0x0f0f0f0f0f0f0f0f); - update(1, stream); - tnt_stream_free(stream); - - printf("# test casting 32-bit operand to 64-bit\n"); - stream = tnt_buf(NULL); - tnt_update_arith_i32(stream, 1, TNT_UPDATE_ADD, 16); - update(1, stream); - tnt_stream_free(stream); - - footer(); -} - -void -test_multi_arith() -{ - header(); - - printf("# insert tuple\n"); - struct tnt_tuple *tuple = tnt_tuple(NULL, "%d%s%d%s", 1, "first", 128, "third"); - insert_tuple(tuple); - tnt_tuple_free(tuple); - - printf("# test simple and\n"); - struct tnt_stream *stream = tnt_buf(NULL); - update_set_i32(stream, 2, 0); - update_set_str(stream, 1, "first field new value"); - tnt_update_arith_i32(stream, 2, TNT_UPDATE_XOR, 0xF00F); - update_set_str(stream, 3, "third field new value"); - tnt_update_arith_i32(stream, 2, TNT_UPDATE_OR, 0xF00F); - update(1, stream); - tnt_stream_free(stream); - - footer(); -} - -void -test_splice() -{ - header(); - - printf("# insert tuple\n"); - struct tnt_tuple *tuple = tnt_tuple(NULL, "%d%s%s%s", 1, "first", "hi, this is a test string!", "third"); - insert_tuple(tuple); - tnt_tuple_free(tuple); - - struct tnt_stream *stream = tnt_buf(NULL); - printf("# test cut from begin\n"); - update_splice_str(stream, 2, 0, 4, ""); - update(1, stream); - tnt_stream_free(stream); - - printf("# test cut from middle\n"); - stream = tnt_buf(NULL); - update_splice_str(stream, 2, 9, -8, ""); - update(1, stream); - tnt_stream_free(stream); - - printf("# test cut from end\n"); - stream = tnt_buf(NULL); - update_splice_str(stream, 2, -1, 1, ""); - update(1, stream); - tnt_stream_free(stream); - - printf("# test insert before begin\n"); - stream = tnt_buf(NULL); - update_splice_str(stream, 2, 0, 0, "Bonjour, "); - update(1, stream); - tnt_stream_free(stream); - - printf("# test insert after end\n"); - stream = tnt_buf(NULL); - update_splice_str(stream, 2, 10000, 0, " o_O!?"); - update(1, stream); - tnt_stream_free(stream); - - printf("# test replace in begin\n"); - stream = tnt_buf(NULL); - update_splice_str(stream, 2, 0, 7, "Hello"); - update(1, stream); - tnt_stream_free(stream); - - printf("# test replace in middle\n"); - stream = tnt_buf(NULL); - update_splice_str(stream, 2, 17, -6, "field"); - update(1, stream); - tnt_stream_free(stream); - - printf("# test replace in end\n"); - stream = tnt_buf(NULL); - update_splice_str(stream, 2, -6, 4, "! Is this Sparta"); - update(1, stream); - tnt_stream_free(stream); - - footer(); -} - -void -test_set_and_splice() -{ - header(); - - printf("# insert tuple\n"); - struct tnt_tuple *tuple = tnt_tuple(NULL, "%d%s%s%s", 1, - "first", - "hi, this is a test string!", - "third"); - insert_tuple(tuple); - tnt_tuple_free(tuple); - - printf("# test set long string and splice to short\n"); - struct tnt_stream *stream = tnt_buf(NULL); - update_set_str(stream, 2, long_string); - update_splice_str(stream, 2, 45, 500, " away away away"); - update(1, stream); - tnt_stream_free(stream); - - printf("# test set short value and splice to long\n"); - stream = tnt_buf(NULL); - update_set_str(stream, 2, "test"); - update_splice_str(stream, 2, -4, 4, long_string); - update(1, stream); - tnt_stream_free(stream); - - printf("# test splice to long and set to short\n"); - stream = tnt_buf(NULL); - update_splice_str(stream, 3, -5, 5, long_string); - update_set_str(stream, 2, "short name"); - update(1, stream); - tnt_stream_free(stream); - - footer(); -} - -void -test_delete_field() -{ - header(); - - printf("# insert tuple\n"); - struct tnt_tuple *tuple = tnt_tuple(NULL, "%d%s%s%s%d%d%d%d%d%d%d%d%d%d", - 1, - "first", - "hi, this is a test string!", - "third", - 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); - insert_tuple(tuple); - tnt_tuple_free(tuple); - - printf("# test simple delete fields\n"); - struct tnt_stream *stream = tnt_buf(NULL); - update_delete_field(stream, 2); - update(1, stream); - tnt_stream_free(stream); - - printf("# test useless operations with delete fields\n"); - stream = tnt_buf(NULL); - update_set_i32(stream, 1, 0); - tnt_update_arith_i32(stream, 1, TNT_UPDATE_ADD, 1); - tnt_update_arith_i32(stream, 1, TNT_UPDATE_ADD, 1); - tnt_update_arith_i32(stream, 1, TNT_UPDATE_ADD, 1); - tnt_update_arith_i32(stream, 1, TNT_UPDATE_ADD, 1); - tnt_update_arith_i32(stream, 1, TNT_UPDATE_ADD, 1); - tnt_update_arith_i32(stream, 1, TNT_UPDATE_ADD, 1); - tnt_update_arith_i32(stream, 1, TNT_UPDATE_ADD, 1); - tnt_update_arith_i32(stream, 1, TNT_UPDATE_ADD, 1); - update_delete_field(stream, 1); - update(1, stream); - tnt_stream_free(stream); - - printf("# test multi delete fields\n"); - stream = tnt_buf(NULL); - update_delete_field(stream, 2); - update_delete_field(stream, 3); - update_delete_field(stream, 4); - update_delete_field(stream, 5); - update_delete_field(stream, 6); - update_delete_field(stream, 7); - update_delete_field(stream, 8); - update_delete_field(stream, 9); - update_delete_field(stream, 10); - update(1, stream); - tnt_stream_free(stream); - - printf("# test multi delete fields\n"); - stream = tnt_buf(NULL); - update_delete_field(stream, 1); - update_set_i32(stream, 1, 3); - tnt_update_arith_i32(stream, 1, TNT_UPDATE_ADD, 1); - tnt_update_arith_i32(stream, 1, TNT_UPDATE_ADD, 1); - tnt_update_arith_i32(stream, 1, TNT_UPDATE_ADD, 1); - tnt_update_arith_i32(stream, 1, TNT_UPDATE_ADD, 1); - tnt_update_arith_i32(stream, 1, TNT_UPDATE_ADD, 1); - tnt_update_arith_i32(stream, 1, TNT_UPDATE_ADD, 1); - update(1, stream); - tnt_stream_free(stream); - - printf("# test append and delete\n"); - stream = tnt_buf(NULL); - update_set_str(stream, 3, "second"); - update_delete_field(stream, 3); - update_set_str(stream, 3, "third"); - update_set_str(stream, 4, "third"); - update_delete_field(stream, 4); - update_set_str(stream, 4, "third"); - update_set_str(stream, 4, "fourth"); - update_set_str(stream, 5, "fifth"); - update_set_str(stream, 6, "sixth"); - update_set_str(stream, 7, "seventh"); - update_set_str(stream, 8, "eighth"); - update_set_str(stream, 9, "ninth"); - update_delete_field(stream, 7); - update_delete_field(stream, 6); - update(1, stream); - tnt_stream_free(stream); - - printf("# test double delete\n"); - stream = tnt_buf(NULL); - update_delete_field(stream, 3); - update_delete_field(stream, 3); - update(1, stream); - tnt_stream_free(stream); - select_tuple(1); - - printf("# test delete not an exist field\n"); - stream = tnt_buf(NULL); - update_delete_field(stream, 0xDEADBEEF); - update(1, stream); - tnt_stream_free(stream); - select_tuple(1); - - footer(); -} - -void -test_insert_field() -{ - header(); - - printf("# insert tuple\n"); - struct tnt_tuple *tuple = tnt_tuple(NULL, "%d%s", 9, "eleven"); - insert_tuple(tuple); - tnt_tuple_free(tuple); - - printf("# insert new field before primary key\n"); - struct tnt_stream *stream = tnt_buf(NULL); - update_insert_i32(stream, 0, 7); - update_insert_i32(stream, 0, 8); - update(9, stream); - tnt_stream_free(stream); - - printf("# insert a new field before last field\n"); - stream = tnt_buf(NULL); - update_insert_i32(stream, 3, 10); - update(7, stream); - tnt_stream_free(stream); - - printf("# double insert at the end\n"); - stream = tnt_buf(NULL); - update_set_i32(stream, 5, 14); - update_insert_i32(stream, 6, 12); - update_insert_i32(stream, 5, 13); - update(7, stream); - tnt_stream_free(stream); - - printf("# multi insert \n"); - stream = tnt_buf(NULL); - update_insert_i32(stream, 5, 15); - update_insert_i32(stream, 5, 14); - update_insert_i32(stream, 5, 13); - update_insert_i32(stream, 5, 12); - update(7, stream); - tnt_stream_free(stream); - - printf("# insert before next to last field\n"); - stream = tnt_buf(NULL); - update_insert_i32(stream, 8, 15); - update(7, stream); - tnt_stream_free(stream); - - printf("# insert before next to last field\n"); - stream = tnt_buf(NULL); - update_set_i32(stream, 9, 17); - update_insert_i32(stream, 9, 16); - update_set_i32(stream, 10, 19); - update_insert_i32(stream, 10, 18); - update(7, stream); - tnt_stream_free(stream); - - printf("# insert second tuple\n"); - tuple = tnt_tuple(NULL, "%d%s%d", 0, "one", 11); - insert_tuple(tuple); - tnt_tuple_free(tuple); - - stream = tnt_buf(NULL); - printf("# multi insert\n"); - update_set_i32(stream, 1, -11); - tnt_update_arith(stream, 1, TNT_UPDATE_ADD, 1); - update_insert_i32(stream, 1, 1); - tnt_update_arith(stream, 1, TNT_UPDATE_ADD, 2); - update_insert_i32(stream, 1, 2); - update_insert_i32(stream, 1, 3); - tnt_update_arith(stream, 1, TNT_UPDATE_ADD, 3); - tnt_update_arith(stream, 1, TNT_UPDATE_ADD, 4); - tnt_update_arith(stream, 1, TNT_UPDATE_ADD, 5); - update_insert_i32(stream, 1, 4); - update_insert_i32(stream, 1, 5); - tnt_update_arith(stream, 1, TNT_UPDATE_ADD, 6); - update_insert_i32(stream, 1, 6); - update_insert_i32(stream, 1, 7); - update_insert_i32(stream, 1, 8); - update_insert_i32(stream, 1, 9); - update(0, stream); - tnt_stream_free(stream); - - printf("# insert before invalid field number\n"); - stream = tnt_buf(NULL); - update_insert_str(stream, 100000, "ooppps!"); - update(7, stream); - tnt_stream_free(stream); - - footer(); -} - -void -test_boundary_args() -{ - header(); - - const int max_update_op_cnt = 4000; - - printf("# insert tuple\n"); - struct tnt_tuple *tuple = tnt_tuple(NULL, "%d%d", 0, 1); - insert_tuple(tuple); - tnt_tuple_free(tuple); - - printf("# test: try to do update w/o operations\n"); - struct tnt_stream *stream = tnt_buf(NULL); - update(0, stream); - tnt_stream_free(stream); - - printf("# test: update w/ maximal allowed opearions count\n"); - stream = tnt_buf(NULL); - for (int i = 0; i < max_update_op_cnt; ++i) - tnt_update_arith_i32(stream, 1, TNT_UPDATE_ADD, 1); - update(0, stream); - tnt_stream_free(stream); - - printf("# test: update w/ grater than maximal allowed opearions count\n"); - stream = tnt_buf(NULL); - for (int i = 0; i < max_update_op_cnt + 1; ++i) - tnt_update_arith_i32(stream, 1, TNT_UPDATE_ADD, 1); - update(0, stream); - tnt_stream_free(stream); - - footer(); -} diff --git a/test/connector_c/update.result b/test/connector_c/update.result deleted file mode 100644 index e1d2b52a7983a84acfedb14a9881c9c97cbe021e..0000000000000000000000000000000000000000 --- a/test/connector_c/update.result +++ /dev/null @@ -1,291 +0,0 @@ -box.insert(box.schema.SPACE_ID, 0, 0, 'tweedledum') ---- -- [0, 0, 'tweedledum'] -... -box.insert(box.schema.INDEX_ID, 0, 0, 'primary', 'hash', 1, 1, 0, 'str') ---- -- [0, 0, 'primary', 1752392040, 1, 1, 0, 'str'] -... - *** test_simple_set *** -# insert tuple -insert: respond ok (op: 13, reqid: 0, code: 0, count: 1) -(1 (0x00000001), 2 (0x00000002), 0 (0x00000000), '') -# test simple set field -update fields: respond ok (op: 19, reqid: 0, code: 0, count: 1) -(1 (0x00000001), 'new field value', '', 1130450022 (0x43614c66)) -# set field -update fields: respond ok (op: 19, reqid: 0, code: 0, count: 1) -(1 (0x00000001), 'field's new value', '', 1130450022 (0x43614c66)) -# test set primary key -update fields: respond ok (op: 19, reqid: 0, code: 0, count: 1) -(2 (0x00000002), 'field's new value', '', 1130450022 (0x43614c66)) - *** test_simple_set: done *** - *** test_long_set *** -# insert tuple -insert: respond ok (op: 13, reqid: 0, code: 0, count: 1) -(1 (0x00000001), 'first', '', 'third') -# test set big value in empty field -update fields: respond ok (op: 19, reqid: 0, code: 0, count: 1) -(1 (0x00000001), 'first', 'A long time ago, in a galaxy far, far away... -It is a period of civil war. Rebel -spaceships, striking from a hidden -base, have won their first victory -against the evil Galactic Empire. -During the battle, Rebel spies managed -to steal secret plans to the Empire's -ultimate weapon, the Death Star, an -armored space station with enough -power to destroy an entire planet. -Pursued by the Empire's sinister agents, -Princess Leia races home aboard her -starship, custodian of the stolen plans -that can save her people and restore -freedom to the galaxy....', 'third') -# test replace long value to short -update fields: respond ok (op: 19, reqid: 0, code: 0, count: 1) -(1 (0x00000001), 'first', 'short string', 'third') - *** test_long_set: done *** - *** test_append *** -# insert tuple -insert: respond ok (op: 13, reqid: 0, code: 0, count: 1) -(1 (0x00000001), 'first') -# test append field -update fields: respond ok (op: 19, reqid: 0, code: 0, count: 1) -(1 (0x00000001), 'first', 'second') -# test multi append -update fields: respond ok (op: 19, reqid: 0, code: 0, count: 1) -(1 (0x00000001), 'first', 'second', 'third') -# test append many fields -update fields: respond ok (op: 19, reqid: 0, code: 0, count: 1) -(1 (0x00000001), 'first', 'second', 'third', 'fourth', 'fifth', 'sixth', 'seventh', 'A long time ago, in a galaxy far, far away... -It is a period of civil war. Rebel -spaceships, striking from a hidden -base, have won their first victory -against the evil Galactic Empire. -During the battle, Rebel spies managed -to steal secret plans to the Empire's -ultimate weapon, the Death Star, an -armored space station with enough -power to destroy an entire planet. -Pursued by the Empire's sinister agents, -Princess Leia races home aboard her -starship, custodian of the stolen plans -that can save her people and restore -freedom to the galaxy....') -# test append and change field -update fields: respond ok (op: 19, reqid: 0, code: 0, count: 1) -(1 (0x00000001), 'first', 'second', 'third', 'fourth', 'fifth', 'sixth', 'seventh', 'A long time ago, in a galaxy far, far away... -It is a period of civil war. Rebel -spaceships, striking from a hidden -base, have won their first victory -against the evil Galactic Empire. -During the battle, Rebel spies managed -to steal secret plans to the Empire's -ultimate weapon, the Death Star, an -armored space station with enough -power to destroy an entire planet. -Pursued by the Empire's sinister agents, -Princess Leia races home aboard her -starship, custodian of the stolen plans -that can save her people and restore -freedom to the galaxy....', 765239998 (0x2d9ca2be)) -# test set to not an exist field -update fields: respond ok (op: 19, reqid: 0, code: 13826, count: 0) - *** test_append: done *** - *** test_arith_i32 *** -# insert tuple -insert: respond ok (op: 13, reqid: 0, code: 0, count: 1) -(1 (0x00000001), 2 (0x00000002), 0 (0x00000000), 0 (0x00000000)) -# test add -update fields: respond ok (op: 19, reqid: 0, code: 0, count: 1) -(1 (0x00000001), 18 (0x00000012), 0 (0x00000000), 0 (0x00000000)) -# test overflow add -update fields: respond ok (op: 19, reqid: 0, code: 0, count: 1) -(1 (0x00000001), -2147483631 (0x80000011), 0 (0x00000000), 0 (0x00000000)) -# test underflow add -update fields: respond ok (op: 19, reqid: 0, code: 0, count: 1) -(1 (0x00000001), 17 (0x00000011), 0 (0x00000000), 0 (0x00000000)) -# test or -update fields: respond ok (op: 19, reqid: 0, code: 0, count: 1) -(1 (0x00000001), 17 (0x00000011), -1160791345 (0xbacfbacf), -88278340 (0xfabcfabc)) -# test xor -update fields: respond ok (op: 19, reqid: 0, code: 0, count: 1) -(1 (0x00000001), 17 (0x00000011), 1160791344 (0x45304530), 88278339 (0x05430543)) -# test and -update fields: respond ok (op: 19, reqid: 0, code: 0, count: 1) -(1 (0x00000001), 17 (0x00000011), 1076903984 (0x40304030), 84083971 (0x05030503)) - *** test_arith_i32: done *** - *** test_arith_i64 *** -# insert tuple -insert: respond ok (op: 13, reqid: 0, code: 0, count: 1) -(1 (0x00000001), 2 (0x0000000000000002), 0 (0x0000000000000000), 0 (0x0000000000000000)) -# test add -update fields: respond ok (op: 19, reqid: 0, code: 0, count: 1) -(1 (0x00000001), 18 (0x0000000000000012), 0 (0x0000000000000000), 0 (0x0000000000000000)) -# test overflow add -update fields: respond ok (op: 19, reqid: 0, code: 0, count: 1) -(1 (0x00000001), -9223372036854775791 (0x8000000000000011), 0 (0x0000000000000000), 0 (0x0000000000000000)) -# test underflow add -update fields: respond ok (op: 19, reqid: 0, code: 0, count: 1) -(1 (0x00000001), 17 (0x0000000000000011), 0 (0x0000000000000000), 0 (0x0000000000000000)) -# test or -update fields: respond ok (op: 19, reqid: 0, code: 0, count: 1) -(1 (0x00000001), 17 (0x0000000000000011), -4985560861120677169 (0xbacfbacfbacfbacf), -379152579038479684 (0xfabcfabcfabcfabc)) -# test xor -update fields: respond ok (op: 19, reqid: 0, code: 0, count: 1) -(1 (0x00000001), 17 (0x0000000000000011), 4985560861120677168 (0x4530453045304530), 379152579038479683 (0x0543054305430543)) -# test and -update fields: respond ok (op: 19, reqid: 0, code: 0, count: 1) -(1 (0x00000001), 17 (0x0000000000000011), 4625267393289011248 (0x4030403040304030), 361137905646896387 (0x0503050305030503)) -# test casting 32-bit operand to 64-bit -update fields: respond ok (op: 19, reqid: 0, code: 0, count: 1) -(1 (0x00000001), 33 (0x0000000000000021), 4625267393289011248 (0x4030403040304030), 361137905646896387 (0x0503050305030503)) - *** test_arith_i64: done *** - *** test_multi_arith *** -# insert tuple -insert: respond ok (op: 13, reqid: 0, code: 0, count: 1) -(1 (0x00000001), 'first', 128 (0x00000080), 'third') -# test simple and -update fields: respond ok (op: 19, reqid: 0, code: 0, count: 1) -(1 (0x00000001), 'first field new value', 61455 (0x0000f00f), 'third field new value') - *** test_multi_arith: done *** - *** test_splice *** -# insert tuple -insert: respond ok (op: 13, reqid: 0, code: 0, count: 1) -(1 (0x00000001), 'first', 'hi, this is a test string!', 'third') -# test cut from begin -update fields: respond ok (op: 19, reqid: 0, code: 0, count: 1) -(1 (0x00000001), 'first', 'this is a test string!', 'third') -# test cut from middle -update fields: respond ok (op: 19, reqid: 0, code: 0, count: 1) -(1 (0x00000001), 'first', 'this is a string!', 'third') -# test cut from end -update fields: respond ok (op: 19, reqid: 0, code: 0, count: 1) -(1 (0x00000001), 'first', 'this is a string', 'third') -# test insert before begin -update fields: respond ok (op: 19, reqid: 0, code: 0, count: 1) -(1 (0x00000001), 'first', 'Bonjour, this is a string', 'third') -# test insert after end -update fields: respond ok (op: 19, reqid: 0, code: 0, count: 1) -(1 (0x00000001), 'first', 'Bonjour, this is a string o_O!?', 'third') -# test replace in begin -update fields: respond ok (op: 19, reqid: 0, code: 0, count: 1) -(1 (0x00000001), 'first', 'Hello, this is a string o_O!?', 'third') -# test replace in middle -update fields: respond ok (op: 19, reqid: 0, code: 0, count: 1) -(1 (0x00000001), 'first', 'Hello, this is a field o_O!?', 'third') -# test replace in end -update fields: respond ok (op: 19, reqid: 0, code: 0, count: 1) -(1 (0x00000001), 'first', 'Hello, this is a field! Is this Sparta!?', 'third') - *** test_splice: done *** - *** test_set_and_splice *** -# insert tuple -insert: respond ok (op: 13, reqid: 0, code: 0, count: 1) -(1 (0x00000001), 'first', 'hi, this is a test string!', 'third') -# test set long string and splice to short -update fields: respond ok (op: 19, reqid: 0, code: 0, count: 1) -(1 (0x00000001), 'first', 'A long time ago, in a galaxy far, far away... away away away.', 'third') -# test set short value and splice to long -update fields: respond ok (op: 19, reqid: 0, code: 0, count: 1) -(1 (0x00000001), 'first', 'A long time ago, in a galaxy far, far away... -It is a period of civil war. Rebel -spaceships, striking from a hidden -base, have won their first victory -against the evil Galactic Empire. -During the battle, Rebel spies managed -to steal secret plans to the Empire's -ultimate weapon, the Death Star, an -armored space station with enough -power to destroy an entire planet. -Pursued by the Empire's sinister agents, -Princess Leia races home aboard her -starship, custodian of the stolen plans -that can save her people and restore -freedom to the galaxy....', 'third') -# test splice to long and set to short -update fields: respond ok (op: 19, reqid: 0, code: 0, count: 1) -(1 (0x00000001), 'first', 'short name', 'A long time ago, in a galaxy far, far away... -It is a period of civil war. Rebel -spaceships, striking from a hidden -base, have won their first victory -against the evil Galactic Empire. -During the battle, Rebel spies managed -to steal secret plans to the Empire's -ultimate weapon, the Death Star, an -armored space station with enough -power to destroy an entire planet. -Pursued by the Empire's sinister agents, -Princess Leia races home aboard her -starship, custodian of the stolen plans -that can save her people and restore -freedom to the galaxy....') - *** test_set_and_splice: done *** - *** test_delete_field *** -# insert tuple -insert: respond ok (op: 13, reqid: 0, code: 0, count: 1) -(1 (0x00000001), 'first', 'hi, this is a test string!', 'third', 1 (0x00000001), 2 (0x00000002), 3 (0x00000003), 4 (0x00000004), 5 (0x00000005), 6 (0x00000006), 7 (0x00000007), 8 (0x00000008), 9 (0x00000009), 10 (0x0000000a)) -# test simple delete fields -update fields: respond ok (op: 19, reqid: 0, code: 0, count: 1) -(1 (0x00000001), 'first', 'third', 1 (0x00000001), 2 (0x00000002), 3 (0x00000003), 4 (0x00000004), 5 (0x00000005), 6 (0x00000006), 7 (0x00000007), 8 (0x00000008), 9 (0x00000009), 10 (0x0000000a)) -# test useless operations with delete fields -update fields: respond ok (op: 19, reqid: 0, code: 0, count: 1) -(1 (0x00000001), 'third', 1 (0x00000001), 2 (0x00000002), 3 (0x00000003), 4 (0x00000004), 5 (0x00000005), 6 (0x00000006), 7 (0x00000007), 8 (0x00000008), 9 (0x00000009), 10 (0x0000000a)) -# test multi delete fields -update fields: respond ok (op: 19, reqid: 0, code: 13826, count: 0) -# test multi delete fields -update fields: respond ok (op: 19, reqid: 0, code: 0, count: 1) -(1 (0x00000001), 9 (0x00000009), 2 (0x00000002), 3 (0x00000003), 4 (0x00000004), 5 (0x00000005), 6 (0x00000006), 7 (0x00000007), 8 (0x00000008), 9 (0x00000009), 10 (0x0000000a)) -# test append and delete -update fields: respond ok (op: 19, reqid: 0, code: 0, count: 1) -(1 (0x00000001), 9 (0x00000009), 2 (0x00000002), 'third', 'fourth', 'fifth', 'eighth', 'ninth') -# test double delete -update fields: respond ok (op: 19, reqid: 0, code: 0, count: 1) -(1 (0x00000001), 9 (0x00000009), 2 (0x00000002), 'fifth', 'eighth', 'ninth') -select: respond ok (op: 17, reqid: 0, code: 0, count: 1) -(1 (0x00000001), 9 (0x00000009), 2 (0x00000002), 'fifth', 'eighth', 'ninth') -# test delete not an exist field -update fields: respond ok (op: 19, reqid: 0, code: 13826, count: 0) -select: respond ok (op: 17, reqid: 0, code: 0, count: 1) -(1 (0x00000001), 9 (0x00000009), 2 (0x00000002), 'fifth', 'eighth', 'ninth') - *** test_delete_field: done *** - *** test_insert_field *** -# insert tuple -insert: respond ok (op: 13, reqid: 0, code: 0, count: 1) -(9 (0x00000009), 'eleven') -# insert new field before primary key -update fields: respond ok (op: 19, reqid: 0, code: 0, count: 1) -(8 (0x00000008), 7 (0x00000007), 9 (0x00000009), 'eleven') -# insert a new field before last field -update fields: respond ok (op: 19, reqid: 0, code: 0, count: 0) -# double insert at the end -update fields: respond ok (op: 19, reqid: 0, code: 0, count: 0) -# multi insert -update fields: respond ok (op: 19, reqid: 0, code: 0, count: 0) -# insert before next to last field -update fields: respond ok (op: 19, reqid: 0, code: 0, count: 0) -# insert before next to last field -update fields: respond ok (op: 19, reqid: 0, code: 0, count: 0) -# insert second tuple -insert: respond ok (op: 13, reqid: 0, code: 0, count: 1) -(0 (0x00000000), 'one', 11 (0x0000000b)) -# multi insert -update fields: respond ok (op: 19, reqid: 0, code: 0, count: 1) -(0 (0x00000000), 9 (0x00000009), 8 (0x00000008), 7 (0x00000007), 6 (0x00000006), 11 (0x0000000b), 4 (0x00000004), 15 (0x0000000f), 2 (0x00000002), 3 (0x00000003), -10 (0xfffffff6), 11 (0x0000000b)) -# insert before invalid field number -update fields: respond ok (op: 19, reqid: 0, code: 0, count: 0) - *** test_insert_field: done *** - *** test_boundary_args *** -# insert tuple -insert: respond ok (op: 13, reqid: 0, code: 0, count: 1) -(0 (0x00000000), 1 (0x00000001)) -# test: try to do update w/o operations -update fields: respond ok (op: 19, reqid: 0, code: 514, count: 0) -# test: update w/ maximal allowed opearions count -update fields: respond ok (op: 19, reqid: 0, code: 0, count: 1) -(0 (0x00000000), 4001 (0x00000fa1)) -# test: update w/ grater than maximal allowed opearions count -update fields: respond ok (op: 19, reqid: 0, code: 514, count: 0) - *** test_boundary_args: done *** - box.space[0]:drop() ---- -... diff --git a/test/connector_c/update.test.py b/test/connector_c/update.test.py deleted file mode 100644 index 991105195dd41128b8569596cdcd108eea5676e1..0000000000000000000000000000000000000000 --- a/test/connector_c/update.test.py +++ /dev/null @@ -1,20 +0,0 @@ -import subprocess -import sys -import os - -admin("box.insert(box.schema.SPACE_ID, 0, 0, 'tweedledum')") -admin("box.insert(box.schema.INDEX_ID, 0, 0, 'primary', 'hash', 1, 1, 0, 'str')") - -p = subprocess.Popen([ os.path.join(builddir, "test/connector_c/update") ], stdout=subprocess.PIPE) -p.wait() -for line in p.stdout.readlines(): - sys.stdout.write(line) - -# resore default suite -#server.stop() -#server.deploy(self.suite_ini["config"]) -#server.start() - -admin("box.space[0]:drop()") - -# vim: syntax=python diff --git a/test/connector_c/xlog_rpl.result b/test/connector_c/xlog_rpl.result deleted file mode 100644 index 890faaeabe641e0f98f7ef2e874ad1a28787dfe9..0000000000000000000000000000000000000000 --- a/test/connector_c/xlog_rpl.result +++ /dev/null @@ -1,2401 +0,0 @@ -Insert lsn: 2, time: 1338903440.187947, len: 68 -Insert lsn: 3, time: 1338903440.190419, len: 68 -Insert lsn: 4, time: 1338903440.190539, len: 68 -Insert lsn: 5, time: 1338903440.190582, len: 68 -Insert lsn: 6, time: 1338903440.190608, len: 68 -Insert lsn: 7, time: 1338903440.190633, len: 68 -Insert lsn: 8, time: 1338903440.190657, len: 68 -Insert lsn: 9, time: 1338903440.190681, len: 68 -Insert lsn: 10, time: 1338903440.190712, len: 68 -Insert lsn: 11, time: 1338903440.190736, len: 68 -Insert lsn: 12, time: 1338903440.190762, len: 69 -Insert lsn: 13, time: 1338903440.190785, len: 69 -Insert lsn: 14, time: 1338903440.190810, len: 69 -Insert lsn: 15, time: 1338903440.190834, len: 69 -Insert lsn: 16, time: 1338903440.190858, len: 69 -Insert lsn: 17, time: 1338903440.190883, len: 69 -Insert lsn: 18, time: 1338903440.190908, len: 69 -Insert lsn: 19, time: 1338903440.190942, len: 69 -Insert lsn: 20, time: 1338903440.190967, len: 69 -Insert lsn: 21, time: 1338903440.190992, len: 69 -Insert lsn: 22, time: 1338903440.191015, len: 69 -Insert lsn: 23, time: 1338903440.191040, len: 69 -Insert lsn: 24, time: 1338903440.191064, len: 69 -Insert lsn: 25, time: 1338903440.191088, len: 69 -Insert lsn: 26, time: 1338903440.191112, len: 69 -Insert lsn: 27, time: 1338903440.191138, len: 69 -Insert lsn: 28, time: 1338903440.191163, len: 69 -Insert lsn: 29, time: 1338903440.191188, len: 69 -Insert lsn: 30, time: 1338903440.191213, len: 69 -Insert lsn: 31, time: 1338903440.191238, len: 69 -Insert lsn: 32, time: 1338903440.191262, len: 69 -Insert lsn: 33, time: 1338903440.191284, len: 69 -Insert lsn: 34, time: 1338903440.191319, len: 69 -Insert lsn: 35, time: 1338903440.191344, len: 69 -Insert lsn: 36, time: 1338903440.191369, len: 69 -Insert lsn: 37, time: 1338903440.191393, len: 69 -Insert lsn: 38, time: 1338903440.191417, len: 69 -Insert lsn: 39, time: 1338903440.191441, len: 69 -Insert lsn: 40, time: 1338903440.191479, len: 69 -Insert lsn: 41, time: 1338903440.191503, len: 69 -Insert lsn: 42, time: 1338903440.191526, len: 69 -Insert lsn: 43, time: 1338903440.191603, len: 69 -Insert lsn: 44, time: 1338903440.191632, len: 69 -Insert lsn: 45, time: 1338903440.191655, len: 69 -Insert lsn: 46, time: 1338903440.191681, len: 69 -Insert lsn: 47, time: 1338903440.191704, len: 69 -Insert lsn: 48, time: 1338903440.191727, len: 69 -Insert lsn: 49, time: 1338903440.191750, len: 69 -Insert lsn: 50, time: 1338903440.191774, len: 69 -Insert lsn: 51, time: 1338903440.191797, len: 69 -Insert lsn: 52, time: 1338903440.191820, len: 69 -Insert lsn: 53, time: 1338903440.191844, len: 69 -Insert lsn: 54, time: 1338903440.191874, len: 69 -Insert lsn: 55, time: 1338903440.191897, len: 69 -Insert lsn: 56, time: 1338903440.191921, len: 69 -Insert lsn: 57, time: 1338903440.191944, len: 69 -Insert lsn: 58, time: 1338903440.191967, len: 69 -Insert lsn: 59, time: 1338903440.191992, len: 69 -Insert lsn: 60, time: 1338903440.192016, len: 69 -Insert lsn: 61, time: 1338903440.192039, len: 69 -Insert lsn: 62, time: 1338903440.192063, len: 69 -Insert lsn: 63, time: 1338903440.192086, len: 69 -Insert lsn: 64, time: 1338903440.192111, len: 69 -Insert lsn: 65, time: 1338903440.192134, len: 69 -Insert lsn: 66, time: 1338903440.192164, len: 69 -Insert lsn: 67, time: 1338903440.192188, len: 69 -Insert lsn: 68, time: 1338903440.192212, len: 69 -Insert lsn: 69, time: 1338903440.192235, len: 69 -Insert lsn: 70, time: 1338903440.192278, len: 69 -Insert lsn: 71, time: 1338903440.192302, len: 69 -Insert lsn: 72, time: 1338903440.192327, len: 69 -Insert lsn: 73, time: 1338903440.192351, len: 69 -Insert lsn: 74, time: 1338903440.192376, len: 69 -Insert lsn: 75, time: 1338903440.192401, len: 69 -Insert lsn: 76, time: 1338903440.192424, len: 69 -Insert lsn: 77, time: 1338903440.192449, len: 69 -Insert lsn: 78, time: 1338903440.192473, len: 69 -Insert lsn: 79, time: 1338903440.192497, len: 69 -Insert lsn: 80, time: 1338903440.192521, len: 69 -Insert lsn: 81, time: 1338903440.192545, len: 69 -Insert lsn: 82, time: 1338903440.192569, len: 69 -Insert lsn: 83, time: 1338903440.192593, len: 69 -Insert lsn: 84, time: 1338903440.192642, len: 69 -Insert lsn: 85, time: 1338903440.192670, len: 69 -Insert lsn: 86, time: 1338903440.192701, len: 69 -Insert lsn: 87, time: 1338903440.192726, len: 69 -Insert lsn: 88, time: 1338903440.192749, len: 69 -Insert lsn: 89, time: 1338903440.192773, len: 69 -Insert lsn: 90, time: 1338903440.192798, len: 69 -Insert lsn: 91, time: 1338903440.192822, len: 69 -Insert lsn: 92, time: 1338903440.192846, len: 69 -Insert lsn: 93, time: 1338903440.192871, len: 69 -Insert lsn: 94, time: 1338903440.192896, len: 69 -Insert lsn: 95, time: 1338903440.192921, len: 69 -Insert lsn: 96, time: 1338903440.192946, len: 69 -Insert lsn: 97, time: 1338903440.192970, len: 69 -Insert lsn: 98, time: 1338903440.192993, len: 69 -Insert lsn: 99, time: 1338903440.193017, len: 69 -Insert lsn: 100, time: 1338903440.193042, len: 69 -Insert lsn: 101, time: 1338903440.193065, len: 69 -Insert lsn: 102, time: 1338903440.193547, len: 100 -Insert lsn: 103, time: 1338903440.207494, len: 100 -Insert lsn: 104, time: 1338903440.207539, len: 100 -Insert lsn: 105, time: 1338903440.207564, len: 100 -Insert lsn: 106, time: 1338903440.207613, len: 100 -Insert lsn: 107, time: 1338903440.207639, len: 100 -Insert lsn: 108, time: 1338903440.207665, len: 100 -Insert lsn: 109, time: 1338903440.207690, len: 100 -Insert lsn: 110, time: 1338903440.207717, len: 100 -Insert lsn: 111, time: 1338903440.207745, len: 100 -Insert lsn: 112, time: 1338903440.207770, len: 101 -Insert lsn: 113, time: 1338903440.207795, len: 101 -Insert lsn: 114, time: 1338903440.207819, len: 101 -Insert lsn: 115, time: 1338903440.207844, len: 101 -Insert lsn: 116, time: 1338903440.207870, len: 101 -Insert lsn: 117, time: 1338903440.207895, len: 101 -Insert lsn: 118, time: 1338903440.207918, len: 101 -Insert lsn: 119, time: 1338903440.207976, len: 101 -Insert lsn: 120, time: 1338903440.208004, len: 101 -Insert lsn: 121, time: 1338903440.208029, len: 101 -Insert lsn: 122, time: 1338903440.208054, len: 101 -Insert lsn: 123, time: 1338903440.208078, len: 101 -Insert lsn: 124, time: 1338903440.208119, len: 101 -Insert lsn: 125, time: 1338903440.208144, len: 101 -Insert lsn: 126, time: 1338903440.208168, len: 101 -Insert lsn: 127, time: 1338903440.208193, len: 101 -Insert lsn: 128, time: 1338903440.208218, len: 101 -Insert lsn: 129, time: 1338903440.208291, len: 101 -Insert lsn: 130, time: 1338903440.208318, len: 101 -Insert lsn: 131, time: 1338903440.208343, len: 101 -Insert lsn: 132, time: 1338903440.208370, len: 101 -Insert lsn: 133, time: 1338903440.208396, len: 101 -Insert lsn: 134, time: 1338903440.208422, len: 101 -Insert lsn: 135, time: 1338903440.208447, len: 101 -Insert lsn: 136, time: 1338903440.208473, len: 101 -Insert lsn: 137, time: 1338903440.208499, len: 101 -Insert lsn: 138, time: 1338903440.208561, len: 101 -Insert lsn: 139, time: 1338903440.208586, len: 101 -Insert lsn: 140, time: 1338903440.208610, len: 101 -Insert lsn: 141, time: 1338903440.208634, len: 101 -Insert lsn: 142, time: 1338903440.208664, len: 101 -Insert lsn: 143, time: 1338903440.208688, len: 101 -Insert lsn: 144, time: 1338903440.208712, len: 101 -Insert lsn: 145, time: 1338903440.208735, len: 101 -Insert lsn: 146, time: 1338903440.208760, len: 101 -Insert lsn: 147, time: 1338903440.208783, len: 101 -Insert lsn: 148, time: 1338903440.208807, len: 101 -Insert lsn: 149, time: 1338903440.208831, len: 101 -Insert lsn: 150, time: 1338903440.208875, len: 101 -Insert lsn: 151, time: 1338903440.208900, len: 101 -Insert lsn: 152, time: 1338903440.208924, len: 101 -Insert lsn: 153, time: 1338903440.208947, len: 101 -Insert lsn: 154, time: 1338903440.208971, len: 101 -Insert lsn: 155, time: 1338903440.208994, len: 101 -Insert lsn: 156, time: 1338903440.209018, len: 101 -Insert lsn: 157, time: 1338903440.209043, len: 101 -Insert lsn: 158, time: 1338903440.209066, len: 101 -Insert lsn: 159, time: 1338903440.209090, len: 101 -Insert lsn: 160, time: 1338903440.209126, len: 101 -Insert lsn: 161, time: 1338903440.209151, len: 101 -Insert lsn: 162, time: 1338903440.209175, len: 101 -Insert lsn: 163, time: 1338903440.209199, len: 101 -Insert lsn: 164, time: 1338903440.209223, len: 101 -Insert lsn: 165, time: 1338903440.209247, len: 101 -Insert lsn: 166, time: 1338903440.209296, len: 101 -Insert lsn: 167, time: 1338903440.209320, len: 101 -Insert lsn: 168, time: 1338903440.209344, len: 101 -Insert lsn: 169, time: 1338903440.209367, len: 101 -Insert lsn: 170, time: 1338903440.209390, len: 101 -Insert lsn: 171, time: 1338903440.209414, len: 101 -Insert lsn: 172, time: 1338903440.209438, len: 101 -Insert lsn: 173, time: 1338903440.209461, len: 101 -Insert lsn: 174, time: 1338903440.209485, len: 101 -Insert lsn: 175, time: 1338903440.209509, len: 101 -Insert lsn: 176, time: 1338903440.209533, len: 101 -Insert lsn: 177, time: 1338903440.209564, len: 101 -Insert lsn: 178, time: 1338903440.209589, len: 101 -Insert lsn: 179, time: 1338903440.209613, len: 101 -Insert lsn: 180, time: 1338903440.209637, len: 101 -Insert lsn: 181, time: 1338903440.209678, len: 101 -Insert lsn: 182, time: 1338903440.209703, len: 101 -Insert lsn: 183, time: 1338903440.209745, len: 101 -Insert lsn: 184, time: 1338903440.209770, len: 101 -Insert lsn: 185, time: 1338903440.209794, len: 101 -Insert lsn: 186, time: 1338903440.209819, len: 101 -Insert lsn: 187, time: 1338903440.209842, len: 101 -Insert lsn: 188, time: 1338903440.209866, len: 101 -Insert lsn: 189, time: 1338903440.209889, len: 101 -Insert lsn: 190, time: 1338903440.209913, len: 101 -Insert lsn: 191, time: 1338903440.209937, len: 101 -Insert lsn: 192, time: 1338903440.209961, len: 101 -Insert lsn: 193, time: 1338903440.209985, len: 101 -Insert lsn: 194, time: 1338903440.210010, len: 101 -Insert lsn: 195, time: 1338903440.210041, len: 101 -Insert lsn: 196, time: 1338903440.210065, len: 101 -Insert lsn: 197, time: 1338903440.210088, len: 101 -Insert lsn: 198, time: 1338903440.210112, len: 101 -Insert lsn: 199, time: 1338903440.210135, len: 101 -Insert lsn: 200, time: 1338903440.210160, len: 101 -Insert lsn: 201, time: 1338903440.210183, len: 101 -Insert lsn: 202, time: 1338903440.210887, len: 166 -Insert lsn: 203, time: 1338903440.213901, len: 166 -Insert lsn: 204, time: 1338903440.213959, len: 166 -Insert lsn: 205, time: 1338903440.213986, len: 166 -Insert lsn: 206, time: 1338903440.214033, len: 166 -Insert lsn: 207, time: 1338903440.214060, len: 166 -Insert lsn: 208, time: 1338903440.214119, len: 166 -Insert lsn: 209, time: 1338903440.214145, len: 166 -Insert lsn: 210, time: 1338903440.214170, len: 166 -Insert lsn: 211, time: 1338903440.214196, len: 166 -Insert lsn: 212, time: 1338903440.214221, len: 167 -Insert lsn: 213, time: 1338903440.214246, len: 167 -Insert lsn: 214, time: 1338903440.214271, len: 167 -Insert lsn: 215, time: 1338903440.214297, len: 167 -Insert lsn: 216, time: 1338903440.214322, len: 167 -Insert lsn: 217, time: 1338903440.214347, len: 167 -Insert lsn: 218, time: 1338903440.214373, len: 167 -Insert lsn: 219, time: 1338903440.214398, len: 167 -Insert lsn: 220, time: 1338903440.214430, len: 167 -Insert lsn: 221, time: 1338903440.214456, len: 167 -Insert lsn: 222, time: 1338903440.214482, len: 167 -Insert lsn: 223, time: 1338903440.214507, len: 167 -Insert lsn: 224, time: 1338903440.214531, len: 167 -Insert lsn: 225, time: 1338903440.214556, len: 167 -Insert lsn: 226, time: 1338903440.214580, len: 167 -Insert lsn: 227, time: 1338903440.214604, len: 167 -Insert lsn: 228, time: 1338903440.214628, len: 167 -Insert lsn: 229, time: 1338903440.214673, len: 167 -Insert lsn: 230, time: 1338903440.214703, len: 167 -Insert lsn: 231, time: 1338903440.214729, len: 167 -Insert lsn: 232, time: 1338903440.214753, len: 167 -Insert lsn: 233, time: 1338903440.214778, len: 167 -Insert lsn: 234, time: 1338903440.214828, len: 167 -Insert lsn: 235, time: 1338903440.214853, len: 167 -Insert lsn: 236, time: 1338903440.214878, len: 167 -Insert lsn: 237, time: 1338903440.214927, len: 167 -Insert lsn: 238, time: 1338903440.214953, len: 167 -Insert lsn: 239, time: 1338903440.214980, len: 167 -Insert lsn: 240, time: 1338903440.215005, len: 167 -Insert lsn: 241, time: 1338903440.215030, len: 167 -Insert lsn: 242, time: 1338903440.215055, len: 167 -Insert lsn: 243, time: 1338903440.215080, len: 167 -Insert lsn: 244, time: 1338903440.215105, len: 167 -Insert lsn: 245, time: 1338903440.215131, len: 167 -Insert lsn: 246, time: 1338903440.215157, len: 167 -Insert lsn: 247, time: 1338903440.215190, len: 167 -Insert lsn: 248, time: 1338903440.215215, len: 167 -Insert lsn: 249, time: 1338903440.215277, len: 167 -Insert lsn: 250, time: 1338903440.215327, len: 167 -Insert lsn: 251, time: 1338903440.215356, len: 167 -Insert lsn: 252, time: 1338903440.215382, len: 167 -Insert lsn: 253, time: 1338903440.215407, len: 167 -Insert lsn: 254, time: 1338903440.215432, len: 167 -Insert lsn: 255, time: 1338903440.215459, len: 167 -Insert lsn: 256, time: 1338903440.215486, len: 167 -Insert lsn: 257, time: 1338903440.215513, len: 167 -Insert lsn: 258, time: 1338903440.215539, len: 167 -Insert lsn: 259, time: 1338903440.215563, len: 167 -Insert lsn: 260, time: 1338903440.215590, len: 167 -Insert lsn: 261, time: 1338903440.215623, len: 167 -Insert lsn: 262, time: 1338903440.215649, len: 167 -Insert lsn: 263, time: 1338903440.215675, len: 167 -Insert lsn: 264, time: 1338903440.215699, len: 167 -Insert lsn: 265, time: 1338903440.215723, len: 167 -Insert lsn: 266, time: 1338903440.215748, len: 167 -Insert lsn: 267, time: 1338903440.215773, len: 167 -Insert lsn: 268, time: 1338903440.215797, len: 167 -Insert lsn: 269, time: 1338903440.215822, len: 167 -Insert lsn: 270, time: 1338903440.215866, len: 167 -Insert lsn: 271, time: 1338903440.215894, len: 167 -Insert lsn: 272, time: 1338903440.215918, len: 167 -Insert lsn: 273, time: 1338903440.215942, len: 167 -Insert lsn: 274, time: 1338903440.215968, len: 167 -Insert lsn: 275, time: 1338903440.216054, len: 167 -Insert lsn: 276, time: 1338903440.216105, len: 167 -Insert lsn: 277, time: 1338903440.216130, len: 167 -Insert lsn: 278, time: 1338903440.216155, len: 167 -Insert lsn: 279, time: 1338903440.216181, len: 167 -Insert lsn: 280, time: 1338903440.216207, len: 167 -Insert lsn: 281, time: 1338903440.216231, len: 167 -Insert lsn: 282, time: 1338903440.216256, len: 167 -Insert lsn: 283, time: 1338903440.216281, len: 167 -Insert lsn: 284, time: 1338903440.216306, len: 167 -Insert lsn: 285, time: 1338903440.216332, len: 167 -Insert lsn: 286, time: 1338903440.216357, len: 167 -Insert lsn: 287, time: 1338903440.216382, len: 167 -Insert lsn: 288, time: 1338903440.216407, len: 167 -Insert lsn: 289, time: 1338903440.216444, len: 167 -Insert lsn: 290, time: 1338903440.216470, len: 167 -Insert lsn: 291, time: 1338903440.216519, len: 167 -Insert lsn: 292, time: 1338903440.216549, len: 167 -Insert lsn: 293, time: 1338903440.216576, len: 167 -Insert lsn: 294, time: 1338903440.216602, len: 167 -Insert lsn: 295, time: 1338903440.216627, len: 167 -Insert lsn: 296, time: 1338903440.216652, len: 167 -Insert lsn: 297, time: 1338903440.216677, len: 167 -Insert lsn: 298, time: 1338903440.216701, len: 167 -Insert lsn: 299, time: 1338903440.216725, len: 167 -Insert lsn: 300, time: 1338903440.216749, len: 167 -Insert lsn: 301, time: 1338903440.216774, len: 167 -Insert lsn: 302, time: 1338903440.217291, len: 68 -Insert lsn: 303, time: 1338903440.217376, len: 68 -Insert lsn: 304, time: 1338903440.217406, len: 68 -Insert lsn: 305, time: 1338903440.217431, len: 68 -Insert lsn: 306, time: 1338903440.217458, len: 68 -Insert lsn: 307, time: 1338903440.217483, len: 68 -Insert lsn: 308, time: 1338903440.217508, len: 68 -Insert lsn: 309, time: 1338903440.217533, len: 68 -Insert lsn: 310, time: 1338903440.217565, len: 68 -Insert lsn: 311, time: 1338903440.217591, len: 68 -Insert lsn: 312, time: 1338903440.217618, len: 69 -Insert lsn: 313, time: 1338903440.217644, len: 69 -Insert lsn: 314, time: 1338903440.217670, len: 69 -Insert lsn: 315, time: 1338903440.217697, len: 69 -Insert lsn: 316, time: 1338903440.217722, len: 69 -Insert lsn: 317, time: 1338903440.217749, len: 69 -Insert lsn: 318, time: 1338903440.217776, len: 69 -Insert lsn: 319, time: 1338903440.217801, len: 69 -Insert lsn: 320, time: 1338903440.217865, len: 69 -Insert lsn: 321, time: 1338903440.217896, len: 69 -Insert lsn: 322, time: 1338903440.217923, len: 69 -Insert lsn: 323, time: 1338903440.217949, len: 69 -Insert lsn: 324, time: 1338903440.217974, len: 69 -Insert lsn: 325, time: 1338903440.218000, len: 69 -Insert lsn: 326, time: 1338903440.218045, len: 69 -Insert lsn: 327, time: 1338903440.218071, len: 69 -Insert lsn: 328, time: 1338903440.218097, len: 69 -Insert lsn: 329, time: 1338903440.218124, len: 69 -Insert lsn: 330, time: 1338903440.218150, len: 69 -Insert lsn: 331, time: 1338903440.218176, len: 69 -Insert lsn: 332, time: 1338903440.218203, len: 69 -Insert lsn: 333, time: 1338903440.218246, len: 69 -Insert lsn: 334, time: 1338903440.218277, len: 69 -Insert lsn: 335, time: 1338903440.218303, len: 69 -Insert lsn: 336, time: 1338903440.218329, len: 69 -Insert lsn: 337, time: 1338903440.218354, len: 69 -Insert lsn: 338, time: 1338903440.218380, len: 69 -Insert lsn: 339, time: 1338903440.218406, len: 69 -Insert lsn: 340, time: 1338903440.218431, len: 69 -Insert lsn: 341, time: 1338903440.218456, len: 69 -Insert lsn: 342, time: 1338903440.218491, len: 69 -Insert lsn: 343, time: 1338903440.218516, len: 69 -Insert lsn: 344, time: 1338903440.218542, len: 69 -Insert lsn: 345, time: 1338903440.218567, len: 69 -Insert lsn: 346, time: 1338903440.218592, len: 69 -Insert lsn: 347, time: 1338903440.218617, len: 69 -Insert lsn: 348, time: 1338903440.218643, len: 69 -Insert lsn: 349, time: 1338903440.218669, len: 69 -Insert lsn: 350, time: 1338903440.218695, len: 69 -Insert lsn: 351, time: 1338903440.218721, len: 69 -Insert lsn: 352, time: 1338903440.218748, len: 69 -Insert lsn: 353, time: 1338903440.218773, len: 69 -Insert lsn: 354, time: 1338903440.218798, len: 69 -Insert lsn: 355, time: 1338903440.218824, len: 69 -Insert lsn: 356, time: 1338903440.218851, len: 69 -Insert lsn: 357, time: 1338903440.218877, len: 69 -Insert lsn: 358, time: 1338903440.218915, len: 69 -Insert lsn: 359, time: 1338903440.218943, len: 69 -Insert lsn: 360, time: 1338903440.218969, len: 69 -Insert lsn: 361, time: 1338903440.219052, len: 69 -Insert lsn: 362, time: 1338903440.219089, len: 69 -Insert lsn: 363, time: 1338903440.219114, len: 69 -Insert lsn: 364, time: 1338903440.219139, len: 69 -Insert lsn: 365, time: 1338903440.219164, len: 69 -Insert lsn: 366, time: 1338903440.219190, len: 69 -Insert lsn: 367, time: 1338903440.219216, len: 69 -Insert lsn: 368, time: 1338903440.219241, len: 69 -Insert lsn: 369, time: 1338903440.219266, len: 69 -Insert lsn: 370, time: 1338903440.219291, len: 69 -Insert lsn: 371, time: 1338903440.219316, len: 69 -Insert lsn: 372, time: 1338903440.219342, len: 69 -Insert lsn: 373, time: 1338903440.219367, len: 69 -Insert lsn: 374, time: 1338903440.219391, len: 69 -Insert lsn: 375, time: 1338903440.219422, len: 69 -Insert lsn: 376, time: 1338903440.219448, len: 69 -Insert lsn: 377, time: 1338903440.219478, len: 69 -Insert lsn: 378, time: 1338903440.219503, len: 69 -Insert lsn: 379, time: 1338903440.219528, len: 69 -Insert lsn: 380, time: 1338903440.219552, len: 69 -Insert lsn: 381, time: 1338903440.219577, len: 69 -Insert lsn: 382, time: 1338903440.219601, len: 69 -Insert lsn: 383, time: 1338903440.219625, len: 69 -Insert lsn: 384, time: 1338903440.219650, len: 69 -Insert lsn: 385, time: 1338903440.219675, len: 69 -Insert lsn: 386, time: 1338903440.219700, len: 69 -Insert lsn: 387, time: 1338903440.219725, len: 69 -Insert lsn: 388, time: 1338903440.219749, len: 69 -Insert lsn: 389, time: 1338903440.219774, len: 69 -Insert lsn: 390, time: 1338903440.219798, len: 69 -Insert lsn: 391, time: 1338903440.219823, len: 69 -Insert lsn: 392, time: 1338903440.219847, len: 69 -Insert lsn: 393, time: 1338903440.219882, len: 69 -Insert lsn: 394, time: 1338903440.219907, len: 69 -Insert lsn: 395, time: 1338903440.219932, len: 69 -Insert lsn: 396, time: 1338903440.219957, len: 69 -Insert lsn: 397, time: 1338903440.219981, len: 69 -Insert lsn: 398, time: 1338903440.220006, len: 69 -Insert lsn: 399, time: 1338903440.220031, len: 69 -Insert lsn: 400, time: 1338903440.220055, len: 69 -Insert lsn: 401, time: 1338903440.220099, len: 69 -Insert lsn: 402, time: 1338903440.220698, len: 100 -Insert lsn: 403, time: 1338903440.220780, len: 100 -Insert lsn: 404, time: 1338903440.220809, len: 100 -Insert lsn: 405, time: 1338903440.220836, len: 100 -Insert lsn: 406, time: 1338903440.220861, len: 100 -Insert lsn: 407, time: 1338903440.220887, len: 100 -Insert lsn: 408, time: 1338903440.220913, len: 100 -Insert lsn: 409, time: 1338903440.220939, len: 100 -Insert lsn: 410, time: 1338903440.220966, len: 100 -Insert lsn: 411, time: 1338903440.220993, len: 100 -Insert lsn: 412, time: 1338903440.221020, len: 101 -Insert lsn: 413, time: 1338903440.221047, len: 101 -Insert lsn: 414, time: 1338903440.221074, len: 101 -Insert lsn: 415, time: 1338903440.221101, len: 101 -Insert lsn: 416, time: 1338903440.221127, len: 101 -Insert lsn: 417, time: 1338903440.221155, len: 101 -Insert lsn: 418, time: 1338903440.221181, len: 101 -Insert lsn: 419, time: 1338903440.221207, len: 101 -Insert lsn: 420, time: 1338903440.221233, len: 101 -Insert lsn: 421, time: 1338903440.221260, len: 101 -Insert lsn: 422, time: 1338903440.221287, len: 101 -Insert lsn: 423, time: 1338903440.221313, len: 101 -Insert lsn: 424, time: 1338903440.221339, len: 101 -Insert lsn: 425, time: 1338903440.221366, len: 101 -Insert lsn: 426, time: 1338903440.221393, len: 101 -Insert lsn: 427, time: 1338903440.221418, len: 101 -Insert lsn: 428, time: 1338903440.221443, len: 101 -Insert lsn: 429, time: 1338903440.221468, len: 101 -Insert lsn: 430, time: 1338903440.221493, len: 101 -Insert lsn: 431, time: 1338903440.221518, len: 101 -Insert lsn: 432, time: 1338903440.221605, len: 101 -Insert lsn: 433, time: 1338903440.221638, len: 101 -Insert lsn: 434, time: 1338903440.221663, len: 101 -Insert lsn: 435, time: 1338903440.221688, len: 101 -Insert lsn: 436, time: 1338903440.221714, len: 101 -Insert lsn: 437, time: 1338903440.221739, len: 101 -Insert lsn: 438, time: 1338903440.221764, len: 101 -Insert lsn: 439, time: 1338903440.221788, len: 101 -Insert lsn: 440, time: 1338903440.221814, len: 101 -Insert lsn: 441, time: 1338903440.221840, len: 101 -Insert lsn: 442, time: 1338903440.221865, len: 101 -Insert lsn: 443, time: 1338903440.221889, len: 101 -Insert lsn: 444, time: 1338903440.221914, len: 101 -Insert lsn: 445, time: 1338903440.221939, len: 101 -Insert lsn: 446, time: 1338903440.221964, len: 101 -Insert lsn: 447, time: 1338903440.221988, len: 101 -Insert lsn: 448, time: 1338903440.222013, len: 101 -Insert lsn: 449, time: 1338903440.222038, len: 101 -Insert lsn: 450, time: 1338903440.222062, len: 101 -Insert lsn: 451, time: 1338903440.222087, len: 101 -Insert lsn: 452, time: 1338903440.222111, len: 101 -Insert lsn: 453, time: 1338903440.222136, len: 101 -Insert lsn: 454, time: 1338903440.222160, len: 101 -Insert lsn: 455, time: 1338903440.222184, len: 101 -Insert lsn: 456, time: 1338903440.222211, len: 101 -Insert lsn: 457, time: 1338903440.222237, len: 101 -Insert lsn: 458, time: 1338903440.222264, len: 101 -Insert lsn: 459, time: 1338903440.222289, len: 101 -Insert lsn: 460, time: 1338903440.222314, len: 101 -Insert lsn: 461, time: 1338903440.222339, len: 101 -Insert lsn: 462, time: 1338903440.222366, len: 101 -Insert lsn: 463, time: 1338903440.222422, len: 101 -Insert lsn: 464, time: 1338903440.222450, len: 101 -Insert lsn: 465, time: 1338903440.222475, len: 101 -Insert lsn: 466, time: 1338903440.222500, len: 101 -Insert lsn: 467, time: 1338903440.222526, len: 101 -Insert lsn: 468, time: 1338903440.222562, len: 101 -Insert lsn: 469, time: 1338903440.222588, len: 101 -Insert lsn: 470, time: 1338903440.222614, len: 101 -Insert lsn: 471, time: 1338903440.222639, len: 101 -Insert lsn: 472, time: 1338903440.222664, len: 101 -Insert lsn: 473, time: 1338903440.222691, len: 101 -Insert lsn: 474, time: 1338903440.222717, len: 101 -Insert lsn: 475, time: 1338903440.222742, len: 101 -Insert lsn: 476, time: 1338903440.222767, len: 101 -Insert lsn: 477, time: 1338903440.222800, len: 101 -Insert lsn: 478, time: 1338903440.222826, len: 101 -Insert lsn: 479, time: 1338903440.222851, len: 101 -Insert lsn: 480, time: 1338903440.222876, len: 101 -Insert lsn: 481, time: 1338903440.222901, len: 101 -Insert lsn: 482, time: 1338903440.222926, len: 101 -Insert lsn: 483, time: 1338903440.222951, len: 101 -Insert lsn: 484, time: 1338903440.222976, len: 101 -Insert lsn: 485, time: 1338903440.223000, len: 101 -Insert lsn: 486, time: 1338903440.223025, len: 101 -Insert lsn: 487, time: 1338903440.223049, len: 101 -Insert lsn: 488, time: 1338903440.223074, len: 101 -Insert lsn: 489, time: 1338903440.223100, len: 101 -Insert lsn: 490, time: 1338903440.223125, len: 101 -Insert lsn: 491, time: 1338903440.223149, len: 101 -Insert lsn: 492, time: 1338903440.223174, len: 101 -Insert lsn: 493, time: 1338903440.223199, len: 101 -Insert lsn: 494, time: 1338903440.223256, len: 101 -Insert lsn: 495, time: 1338903440.223284, len: 101 -Insert lsn: 496, time: 1338903440.223311, len: 101 -Insert lsn: 497, time: 1338903440.223336, len: 101 -Insert lsn: 498, time: 1338903440.223361, len: 101 -Insert lsn: 499, time: 1338903440.223386, len: 101 -Insert lsn: 500, time: 1338903440.223410, len: 101 -Insert lsn: 501, time: 1338903440.223435, len: 101 -Insert lsn: 502, time: 1338903440.224114, len: 166 -Insert lsn: 503, time: 1338903440.224227, len: 166 -Insert lsn: 504, time: 1338903440.224259, len: 166 -Insert lsn: 505, time: 1338903440.224284, len: 166 -Insert lsn: 506, time: 1338903440.224311, len: 166 -Insert lsn: 507, time: 1338903440.224339, len: 166 -Insert lsn: 508, time: 1338903440.224365, len: 166 -Insert lsn: 509, time: 1338903440.224391, len: 166 -Insert lsn: 510, time: 1338903440.224418, len: 166 -Insert lsn: 511, time: 1338903440.224444, len: 166 -Insert lsn: 512, time: 1338903440.224471, len: 167 -Insert lsn: 513, time: 1338903440.224497, len: 167 -Insert lsn: 514, time: 1338903440.224523, len: 167 -Insert lsn: 515, time: 1338903440.224550, len: 167 -Insert lsn: 516, time: 1338903440.224576, len: 167 -Insert lsn: 517, time: 1338903440.224639, len: 167 -Insert lsn: 518, time: 1338903440.224671, len: 167 -Insert lsn: 519, time: 1338903440.224698, len: 167 -Insert lsn: 520, time: 1338903440.224725, len: 167 -Insert lsn: 521, time: 1338903440.224753, len: 167 -Insert lsn: 522, time: 1338903440.224780, len: 167 -Insert lsn: 523, time: 1338903440.224806, len: 167 -Insert lsn: 524, time: 1338903440.224833, len: 167 -Insert lsn: 525, time: 1338903440.224860, len: 167 -Insert lsn: 526, time: 1338903440.224888, len: 167 -Insert lsn: 527, time: 1338903440.224938, len: 167 -Insert lsn: 528, time: 1338903440.224967, len: 167 -Insert lsn: 529, time: 1338903440.224994, len: 167 -Insert lsn: 530, time: 1338903440.225020, len: 167 -Insert lsn: 531, time: 1338903440.225047, len: 167 -Insert lsn: 532, time: 1338903440.225073, len: 167 -Insert lsn: 533, time: 1338903440.225100, len: 167 -Insert lsn: 534, time: 1338903440.225126, len: 167 -Insert lsn: 535, time: 1338903440.225152, len: 167 -Insert lsn: 536, time: 1338903440.225180, len: 167 -Insert lsn: 537, time: 1338903440.225206, len: 167 -Insert lsn: 538, time: 1338903440.225260, len: 167 -Insert lsn: 539, time: 1338903440.225290, len: 167 -Insert lsn: 540, time: 1338903440.225316, len: 167 -Insert lsn: 541, time: 1338903440.225343, len: 167 -Insert lsn: 542, time: 1338903440.225369, len: 167 -Insert lsn: 543, time: 1338903440.225395, len: 167 -Insert lsn: 544, time: 1338903440.225421, len: 167 -Insert lsn: 545, time: 1338903440.225448, len: 167 -Insert lsn: 546, time: 1338903440.225474, len: 167 -Insert lsn: 547, time: 1338903440.225500, len: 167 -Insert lsn: 548, time: 1338903440.225527, len: 167 -Insert lsn: 549, time: 1338903440.225554, len: 167 -Insert lsn: 550, time: 1338903440.225580, len: 167 -Insert lsn: 551, time: 1338903440.225605, len: 167 -Insert lsn: 552, time: 1338903440.225631, len: 167 -Insert lsn: 553, time: 1338903440.225658, len: 167 -Insert lsn: 554, time: 1338903440.225685, len: 167 -Insert lsn: 555, time: 1338903440.225711, len: 167 -Insert lsn: 556, time: 1338903440.225738, len: 167 -Insert lsn: 557, time: 1338903440.225765, len: 167 -Insert lsn: 558, time: 1338903440.225792, len: 167 -Insert lsn: 559, time: 1338903440.225836, len: 167 -Insert lsn: 560, time: 1338903440.225865, len: 167 -Insert lsn: 561, time: 1338903440.225892, len: 167 -Insert lsn: 562, time: 1338903440.225919, len: 167 -Insert lsn: 563, time: 1338903440.225945, len: 167 -Insert lsn: 564, time: 1338903440.225971, len: 167 -Insert lsn: 565, time: 1338903440.225997, len: 167 -Insert lsn: 566, time: 1338903440.226024, len: 167 -Insert lsn: 567, time: 1338903440.226051, len: 167 -Insert lsn: 568, time: 1338903440.226080, len: 167 -Insert lsn: 569, time: 1338903440.226107, len: 167 -Insert lsn: 570, time: 1338903440.226134, len: 167 -Insert lsn: 571, time: 1338903440.226162, len: 167 -Insert lsn: 572, time: 1338903440.226190, len: 167 -Insert lsn: 573, time: 1338903440.226217, len: 167 -Insert lsn: 574, time: 1338903440.226244, len: 167 -Insert lsn: 575, time: 1338903440.226271, len: 167 -Insert lsn: 576, time: 1338903440.226296, len: 167 -Insert lsn: 577, time: 1338903440.226322, len: 167 -Insert lsn: 578, time: 1338903440.226348, len: 167 -Insert lsn: 579, time: 1338903440.226392, len: 167 -Insert lsn: 580, time: 1338903440.226420, len: 167 -Insert lsn: 581, time: 1338903440.226446, len: 167 -Insert lsn: 582, time: 1338903440.226471, len: 167 -Insert lsn: 583, time: 1338903440.226496, len: 167 -Insert lsn: 584, time: 1338903440.226521, len: 167 -Insert lsn: 585, time: 1338903440.226546, len: 167 -Insert lsn: 586, time: 1338903440.226571, len: 167 -Insert lsn: 587, time: 1338903440.226596, len: 167 -Insert lsn: 588, time: 1338903440.226622, len: 167 -Insert lsn: 589, time: 1338903440.226648, len: 167 -Insert lsn: 590, time: 1338903440.226674, len: 167 -Insert lsn: 591, time: 1338903440.226699, len: 167 -Insert lsn: 592, time: 1338903440.226724, len: 167 -Insert lsn: 593, time: 1338903440.226749, len: 167 -Insert lsn: 594, time: 1338903440.226774, len: 167 -Insert lsn: 595, time: 1338903440.226799, len: 167 -Insert lsn: 596, time: 1338903440.226825, len: 167 -Insert lsn: 597, time: 1338903440.226850, len: 167 -Insert lsn: 598, time: 1338903440.226882, len: 167 -Insert lsn: 599, time: 1338903440.226907, len: 167 -Insert lsn: 600, time: 1338903440.226949, len: 167 -Insert lsn: 601, time: 1338903440.226978, len: 167 -Update lsn: 602, time: 1338903440.227788, len: 77 -Update lsn: 603, time: 1338903440.227901, len: 77 -Update lsn: 604, time: 1338903440.227932, len: 77 -Update lsn: 605, time: 1338903440.227961, len: 77 -Update lsn: 606, time: 1338903440.227988, len: 77 -Update lsn: 607, time: 1338903440.228014, len: 77 -Update lsn: 608, time: 1338903440.228041, len: 77 -Update lsn: 609, time: 1338903440.228069, len: 77 -Update lsn: 610, time: 1338903440.228096, len: 77 -Update lsn: 611, time: 1338903440.228123, len: 77 -Update lsn: 612, time: 1338903440.228150, len: 78 -Update lsn: 613, time: 1338903440.228177, len: 78 -Update lsn: 614, time: 1338903440.228204, len: 78 -Update lsn: 615, time: 1338903440.228250, len: 78 -Update lsn: 616, time: 1338903440.228283, len: 78 -Update lsn: 617, time: 1338903440.228311, len: 78 -Update lsn: 618, time: 1338903440.228338, len: 78 -Update lsn: 619, time: 1338903440.228365, len: 78 -Update lsn: 620, time: 1338903440.228393, len: 78 -Update lsn: 621, time: 1338903440.228421, len: 78 -Update lsn: 622, time: 1338903440.228448, len: 78 -Update lsn: 623, time: 1338903440.228475, len: 78 -Update lsn: 624, time: 1338903440.228502, len: 78 -Update lsn: 625, time: 1338903440.228530, len: 78 -Update lsn: 626, time: 1338903440.228556, len: 78 -Update lsn: 627, time: 1338903440.228583, len: 78 -Update lsn: 628, time: 1338903440.228611, len: 78 -Update lsn: 629, time: 1338903440.228639, len: 78 -Update lsn: 630, time: 1338903440.228668, len: 78 -Update lsn: 631, time: 1338903440.228695, len: 78 -Update lsn: 632, time: 1338903440.228723, len: 78 -Update lsn: 633, time: 1338903440.228751, len: 78 -Update lsn: 634, time: 1338903440.228778, len: 78 -Update lsn: 635, time: 1338903440.228838, len: 78 -Update lsn: 636, time: 1338903440.228867, len: 78 -Update lsn: 637, time: 1338903440.228892, len: 78 -Update lsn: 638, time: 1338903440.228918, len: 78 -Update lsn: 639, time: 1338903440.228944, len: 78 -Update lsn: 640, time: 1338903440.228969, len: 78 -Update lsn: 641, time: 1338903440.228995, len: 78 -Update lsn: 642, time: 1338903440.229021, len: 78 -Update lsn: 643, time: 1338903440.229047, len: 78 -Update lsn: 644, time: 1338903440.229073, len: 78 -Update lsn: 645, time: 1338903440.229099, len: 78 -Update lsn: 646, time: 1338903440.229125, len: 78 -Update lsn: 647, time: 1338903440.229150, len: 78 -Update lsn: 648, time: 1338903440.229176, len: 78 -Update lsn: 649, time: 1338903440.229201, len: 78 -Update lsn: 650, time: 1338903440.229228, len: 78 -Update lsn: 651, time: 1338903440.229254, len: 78 -Update lsn: 652, time: 1338903440.229281, len: 78 -Update lsn: 653, time: 1338903440.229307, len: 78 -Update lsn: 654, time: 1338903440.229333, len: 78 -Update lsn: 655, time: 1338903440.229360, len: 78 -Update lsn: 656, time: 1338903440.229386, len: 78 -Update lsn: 657, time: 1338903440.229412, len: 78 -Update lsn: 658, time: 1338903440.229439, len: 78 -Update lsn: 659, time: 1338903440.229465, len: 78 -Update lsn: 660, time: 1338903440.229491, len: 78 -Update lsn: 661, time: 1338903440.229517, len: 78 -Update lsn: 662, time: 1338903440.229544, len: 78 -Update lsn: 663, time: 1338903440.229584, len: 78 -Update lsn: 664, time: 1338903440.229612, len: 78 -Update lsn: 665, time: 1338903440.229639, len: 78 -Update lsn: 666, time: 1338903440.229666, len: 78 -Update lsn: 667, time: 1338903440.229694, len: 78 -Update lsn: 668, time: 1338903440.229723, len: 78 -Update lsn: 669, time: 1338903440.229752, len: 78 -Update lsn: 670, time: 1338903440.229779, len: 78 -Update lsn: 671, time: 1338903440.229808, len: 78 -Update lsn: 672, time: 1338903440.229862, len: 78 -Update lsn: 673, time: 1338903440.229892, len: 78 -Update lsn: 674, time: 1338903440.229933, len: 78 -Update lsn: 675, time: 1338903440.229961, len: 78 -Update lsn: 676, time: 1338903440.229988, len: 78 -Update lsn: 677, time: 1338903440.230015, len: 78 -Update lsn: 678, time: 1338903440.230042, len: 78 -Update lsn: 679, time: 1338903440.230069, len: 78 -Update lsn: 680, time: 1338903440.230096, len: 78 -Update lsn: 681, time: 1338903440.230124, len: 78 -Update lsn: 682, time: 1338903440.230153, len: 78 -Update lsn: 683, time: 1338903440.230180, len: 78 -Update lsn: 684, time: 1338903440.230210, len: 78 -Update lsn: 685, time: 1338903440.230248, len: 78 -Update lsn: 686, time: 1338903440.230274, len: 78 -Update lsn: 687, time: 1338903440.230300, len: 78 -Update lsn: 688, time: 1338903440.230326, len: 78 -Update lsn: 689, time: 1338903440.230352, len: 78 -Update lsn: 690, time: 1338903440.230380, len: 78 -Update lsn: 691, time: 1338903440.230408, len: 78 -Update lsn: 692, time: 1338903440.230434, len: 78 -Update lsn: 693, time: 1338903440.230462, len: 78 -Update lsn: 694, time: 1338903440.230488, len: 78 -Update lsn: 695, time: 1338903440.230515, len: 78 -Update lsn: 696, time: 1338903440.230541, len: 78 -Update lsn: 697, time: 1338903440.230567, len: 78 -Update lsn: 698, time: 1338903440.230593, len: 78 -Update lsn: 699, time: 1338903440.230619, len: 78 -Update lsn: 700, time: 1338903440.230645, len: 78 -Update lsn: 701, time: 1338903440.230670, len: 78 -Update lsn: 702, time: 1338903440.231167, len: 109 -Update lsn: 703, time: 1338903440.231248, len: 109 -Update lsn: 704, time: 1338903440.231279, len: 109 -Update lsn: 705, time: 1338903440.231308, len: 109 -Update lsn: 706, time: 1338903440.231335, len: 109 -Update lsn: 707, time: 1338903440.231362, len: 109 -Update lsn: 708, time: 1338903440.231420, len: 109 -Update lsn: 709, time: 1338903440.231452, len: 109 -Update lsn: 710, time: 1338903440.231482, len: 109 -Update lsn: 711, time: 1338903440.231512, len: 109 -Update lsn: 712, time: 1338903440.231540, len: 110 -Update lsn: 713, time: 1338903440.231589, len: 110 -Update lsn: 714, time: 1338903440.231620, len: 110 -Update lsn: 715, time: 1338903440.231647, len: 110 -Update lsn: 716, time: 1338903440.231674, len: 110 -Update lsn: 717, time: 1338903440.231703, len: 110 -Update lsn: 718, time: 1338903440.231731, len: 110 -Update lsn: 719, time: 1338903440.231761, len: 110 -Update lsn: 720, time: 1338903440.231789, len: 110 -Update lsn: 721, time: 1338903440.231818, len: 110 -Update lsn: 722, time: 1338903440.231847, len: 110 -Update lsn: 723, time: 1338903440.231874, len: 110 -Update lsn: 724, time: 1338903440.231900, len: 110 -Update lsn: 725, time: 1338903440.231927, len: 110 -Update lsn: 726, time: 1338903440.231954, len: 110 -Update lsn: 727, time: 1338903440.231981, len: 110 -Update lsn: 728, time: 1338903440.232007, len: 110 -Update lsn: 729, time: 1338903440.232034, len: 110 -Update lsn: 730, time: 1338903440.232061, len: 110 -Update lsn: 731, time: 1338903440.232088, len: 110 -Update lsn: 732, time: 1338903440.232114, len: 110 -Update lsn: 733, time: 1338903440.232140, len: 110 -Update lsn: 734, time: 1338903440.232166, len: 110 -Update lsn: 735, time: 1338903440.232192, len: 110 -Update lsn: 736, time: 1338903440.232217, len: 110 -Update lsn: 737, time: 1338903440.232270, len: 110 -Update lsn: 738, time: 1338903440.232300, len: 110 -Update lsn: 739, time: 1338903440.232326, len: 110 -Update lsn: 740, time: 1338903440.232352, len: 110 -Update lsn: 741, time: 1338903440.232377, len: 110 -Update lsn: 742, time: 1338903440.232403, len: 110 -Update lsn: 743, time: 1338903440.232429, len: 110 -Update lsn: 744, time: 1338903440.232456, len: 110 -Update lsn: 745, time: 1338903440.232483, len: 110 -Update lsn: 746, time: 1338903440.232509, len: 110 -Update lsn: 747, time: 1338903440.232537, len: 110 -Update lsn: 748, time: 1338903440.232564, len: 110 -Update lsn: 749, time: 1338903440.232590, len: 110 -Update lsn: 750, time: 1338903440.232617, len: 110 -Update lsn: 751, time: 1338903440.232643, len: 110 -Update lsn: 752, time: 1338903440.232670, len: 110 -Update lsn: 753, time: 1338903440.232697, len: 110 -Update lsn: 754, time: 1338903440.232724, len: 110 -Update lsn: 755, time: 1338903440.232750, len: 110 -Update lsn: 756, time: 1338903440.232777, len: 110 -Update lsn: 757, time: 1338903440.232803, len: 110 -Update lsn: 758, time: 1338903440.232829, len: 110 -Update lsn: 759, time: 1338903440.232856, len: 110 -Update lsn: 760, time: 1338903440.232883, len: 110 -Update lsn: 761, time: 1338903440.232909, len: 110 -Update lsn: 762, time: 1338903440.232936, len: 110 -Update lsn: 763, time: 1338903440.232962, len: 110 -Update lsn: 764, time: 1338903440.232989, len: 110 -Update lsn: 765, time: 1338903440.233016, len: 110 -Update lsn: 766, time: 1338903440.233063, len: 110 -Update lsn: 767, time: 1338903440.233091, len: 110 -Update lsn: 768, time: 1338903440.233117, len: 110 -Update lsn: 769, time: 1338903440.233144, len: 110 -Update lsn: 770, time: 1338903440.233170, len: 110 -Update lsn: 771, time: 1338903440.233196, len: 110 -Update lsn: 772, time: 1338903440.233221, len: 110 -Update lsn: 773, time: 1338903440.233247, len: 110 -Update lsn: 774, time: 1338903440.233274, len: 110 -Update lsn: 775, time: 1338903440.233300, len: 110 -Update lsn: 776, time: 1338903440.233327, len: 110 -Update lsn: 777, time: 1338903440.233354, len: 110 -Update lsn: 778, time: 1338903440.233381, len: 110 -Update lsn: 779, time: 1338903440.233407, len: 110 -Update lsn: 780, time: 1338903440.233434, len: 110 -Update lsn: 781, time: 1338903440.233461, len: 110 -Update lsn: 782, time: 1338903440.233488, len: 110 -Update lsn: 783, time: 1338903440.233515, len: 110 -Update lsn: 784, time: 1338903440.233542, len: 110 -Update lsn: 785, time: 1338903440.233568, len: 110 -Update lsn: 786, time: 1338903440.233595, len: 110 -Update lsn: 787, time: 1338903440.233622, len: 110 -Update lsn: 788, time: 1338903440.233649, len: 110 -Update lsn: 789, time: 1338903440.233677, len: 110 -Update lsn: 790, time: 1338903440.233704, len: 110 -Update lsn: 791, time: 1338903440.233730, len: 110 -Update lsn: 792, time: 1338903440.233757, len: 110 -Update lsn: 793, time: 1338903440.233784, len: 110 -Update lsn: 794, time: 1338903440.233827, len: 110 -Update lsn: 795, time: 1338903440.233855, len: 110 -Update lsn: 796, time: 1338903440.233882, len: 110 -Update lsn: 797, time: 1338903440.233909, len: 110 -Update lsn: 798, time: 1338903440.233936, len: 110 -Update lsn: 799, time: 1338903440.233963, len: 110 -Update lsn: 800, time: 1338903440.233989, len: 110 -Update lsn: 801, time: 1338903440.234015, len: 110 -Update lsn: 802, time: 1338903440.234573, len: 175 -Update lsn: 803, time: 1338903440.234678, len: 175 -Update lsn: 804, time: 1338903440.234710, len: 175 -Update lsn: 805, time: 1338903440.234738, len: 175 -Update lsn: 806, time: 1338903440.234767, len: 175 -Update lsn: 807, time: 1338903440.234796, len: 175 -Update lsn: 808, time: 1338903440.234823, len: 175 -Update lsn: 809, time: 1338903440.234851, len: 175 -Update lsn: 810, time: 1338903440.234878, len: 175 -Update lsn: 811, time: 1338903440.234923, len: 175 -Update lsn: 812, time: 1338903440.234954, len: 176 -Update lsn: 813, time: 1338903440.234984, len: 176 -Update lsn: 814, time: 1338903440.235012, len: 176 -Update lsn: 815, time: 1338903440.235040, len: 176 -Update lsn: 816, time: 1338903440.235068, len: 176 -Update lsn: 817, time: 1338903440.235132, len: 176 -Update lsn: 818, time: 1338903440.235167, len: 176 -Update lsn: 819, time: 1338903440.235196, len: 176 -Update lsn: 820, time: 1338903440.235224, len: 176 -Update lsn: 821, time: 1338903440.235254, len: 176 -Update lsn: 822, time: 1338903440.235282, len: 176 -Update lsn: 823, time: 1338903440.235310, len: 176 -Update lsn: 824, time: 1338903440.235339, len: 176 -Update lsn: 825, time: 1338903440.235368, len: 176 -Update lsn: 826, time: 1338903440.235395, len: 176 -Update lsn: 827, time: 1338903440.235422, len: 176 -Update lsn: 828, time: 1338903440.235449, len: 176 -Update lsn: 829, time: 1338903440.235476, len: 176 -Update lsn: 830, time: 1338903440.235503, len: 176 -Update lsn: 831, time: 1338903440.235530, len: 176 -Update lsn: 832, time: 1338903440.235556, len: 176 -Update lsn: 833, time: 1338903440.235583, len: 176 -Update lsn: 834, time: 1338903440.235609, len: 176 -Update lsn: 835, time: 1338903440.235635, len: 176 -Update lsn: 836, time: 1338903440.235682, len: 176 -Update lsn: 837, time: 1338903440.235711, len: 176 -Update lsn: 838, time: 1338903440.235738, len: 176 -Update lsn: 839, time: 1338903440.235764, len: 176 -Update lsn: 840, time: 1338903440.235790, len: 176 -Update lsn: 841, time: 1338903440.235817, len: 176 -Update lsn: 842, time: 1338903440.235843, len: 176 -Update lsn: 843, time: 1338903440.235869, len: 176 -Update lsn: 844, time: 1338903440.235896, len: 176 -Update lsn: 845, time: 1338903440.235923, len: 176 -Update lsn: 846, time: 1338903440.235949, len: 176 -Update lsn: 847, time: 1338903440.235977, len: 176 -Update lsn: 848, time: 1338903440.236004, len: 176 -Update lsn: 849, time: 1338903440.236031, len: 176 -Update lsn: 850, time: 1338903440.236057, len: 176 -Update lsn: 851, time: 1338903440.236084, len: 176 -Update lsn: 852, time: 1338903440.236110, len: 176 -Update lsn: 853, time: 1338903440.236136, len: 176 -Update lsn: 854, time: 1338903440.236163, len: 176 -Update lsn: 855, time: 1338903440.236189, len: 176 -Update lsn: 856, time: 1338903440.236233, len: 176 -Update lsn: 857, time: 1338903440.236262, len: 176 -Update lsn: 858, time: 1338903440.236289, len: 176 -Update lsn: 859, time: 1338903440.236315, len: 176 -Update lsn: 860, time: 1338903440.236341, len: 176 -Update lsn: 861, time: 1338903440.236368, len: 176 -Update lsn: 862, time: 1338903440.236394, len: 176 -Update lsn: 863, time: 1338903440.236421, len: 176 -Update lsn: 864, time: 1338903440.236448, len: 176 -Update lsn: 865, time: 1338903440.236475, len: 176 -Update lsn: 866, time: 1338903440.236501, len: 176 -Update lsn: 867, time: 1338903440.236527, len: 176 -Update lsn: 868, time: 1338903440.236554, len: 176 -Update lsn: 869, time: 1338903440.236581, len: 176 -Update lsn: 870, time: 1338903440.236608, len: 176 -Update lsn: 871, time: 1338903440.236634, len: 176 -Update lsn: 872, time: 1338903440.236660, len: 176 -Update lsn: 873, time: 1338903440.236687, len: 176 -Update lsn: 874, time: 1338903440.236713, len: 176 -Update lsn: 875, time: 1338903440.236739, len: 176 -Update lsn: 876, time: 1338903440.236782, len: 176 -Update lsn: 877, time: 1338903440.236810, len: 176 -Update lsn: 878, time: 1338903440.236837, len: 176 -Update lsn: 879, time: 1338903440.236864, len: 176 -Update lsn: 880, time: 1338903440.236892, len: 176 -Update lsn: 881, time: 1338903440.236919, len: 176 -Update lsn: 882, time: 1338903440.236945, len: 176 -Update lsn: 883, time: 1338903440.236972, len: 176 -Update lsn: 884, time: 1338903440.236998, len: 176 -Update lsn: 885, time: 1338903440.237024, len: 176 -Update lsn: 886, time: 1338903440.237050, len: 176 -Update lsn: 887, time: 1338903440.237077, len: 176 -Update lsn: 888, time: 1338903440.237103, len: 176 -Update lsn: 889, time: 1338903440.237131, len: 176 -Update lsn: 890, time: 1338903440.237158, len: 176 -Update lsn: 891, time: 1338903440.237184, len: 176 -Update lsn: 892, time: 1338903440.237211, len: 176 -Update lsn: 893, time: 1338903440.237236, len: 176 -Update lsn: 894, time: 1338903440.237262, len: 176 -Update lsn: 895, time: 1338903440.237289, len: 176 -Update lsn: 896, time: 1338903440.237339, len: 176 -Update lsn: 897, time: 1338903440.237368, len: 176 -Update lsn: 898, time: 1338903440.237395, len: 176 -Update lsn: 899, time: 1338903440.237421, len: 176 -Update lsn: 900, time: 1338903440.237448, len: 176 -Update lsn: 901, time: 1338903440.237475, len: 176 -Update lsn: 902, time: 1338903440.238040, len: 77 -Update lsn: 903, time: 1338903440.238124, len: 77 -Update lsn: 904, time: 1338903440.238156, len: 77 -Update lsn: 905, time: 1338903440.238183, len: 77 -Update lsn: 906, time: 1338903440.238212, len: 77 -Update lsn: 907, time: 1338903440.238899, len: 77 -Update lsn: 908, time: 1338903440.238960, len: 77 -Update lsn: 909, time: 1338903440.238989, len: 77 -Update lsn: 910, time: 1338903440.239016, len: 77 -Update lsn: 911, time: 1338903440.239043, len: 77 -Update lsn: 912, time: 1338903440.239070, len: 78 -Update lsn: 913, time: 1338903440.239097, len: 78 -Update lsn: 914, time: 1338903440.239125, len: 78 -Update lsn: 915, time: 1338903440.239153, len: 78 -Update lsn: 916, time: 1338903440.239180, len: 78 -Update lsn: 917, time: 1338903440.239207, len: 78 -Update lsn: 918, time: 1338903440.239234, len: 78 -Update lsn: 919, time: 1338903440.239261, len: 78 -Update lsn: 920, time: 1338903440.239290, len: 78 -Update lsn: 921, time: 1338903440.240279, len: 78 -Update lsn: 922, time: 1338903440.240328, len: 78 -Update lsn: 923, time: 1338903440.240355, len: 78 -Update lsn: 924, time: 1338903440.240382, len: 78 -Update lsn: 925, time: 1338903440.240409, len: 78 -Update lsn: 926, time: 1338903440.240436, len: 78 -Update lsn: 927, time: 1338903440.240494, len: 78 -Update lsn: 928, time: 1338903440.240522, len: 78 -Update lsn: 929, time: 1338903440.240548, len: 78 -Update lsn: 930, time: 1338903440.240575, len: 78 -Update lsn: 931, time: 1338903440.240604, len: 78 -Update lsn: 932, time: 1338903440.240632, len: 78 -Update lsn: 933, time: 1338903440.240660, len: 78 -Update lsn: 934, time: 1338903440.240687, len: 78 -Update lsn: 935, time: 1338903440.240714, len: 78 -Update lsn: 936, time: 1338903440.240742, len: 78 -Update lsn: 937, time: 1338903440.240770, len: 78 -Update lsn: 938, time: 1338903440.240797, len: 78 -Update lsn: 939, time: 1338903440.240823, len: 78 -Update lsn: 940, time: 1338903440.240851, len: 78 -Update lsn: 941, time: 1338903440.240879, len: 78 -Update lsn: 942, time: 1338903440.240906, len: 78 -Update lsn: 943, time: 1338903440.240934, len: 78 -Update lsn: 944, time: 1338903440.240961, len: 78 -Update lsn: 945, time: 1338903440.240988, len: 78 -Update lsn: 946, time: 1338903440.241016, len: 78 -Update lsn: 947, time: 1338903440.241044, len: 78 -Update lsn: 948, time: 1338903440.241071, len: 78 -Update lsn: 949, time: 1338903440.241097, len: 78 -Update lsn: 950, time: 1338903440.241124, len: 78 -Update lsn: 951, time: 1338903440.241152, len: 78 -Update lsn: 952, time: 1338903440.241179, len: 78 -Update lsn: 953, time: 1338903440.241206, len: 78 -Update lsn: 954, time: 1338903440.241233, len: 78 -Update lsn: 955, time: 1338903440.241260, len: 78 -Update lsn: 956, time: 1338903440.241287, len: 78 -Update lsn: 957, time: 1338903440.241314, len: 78 -Update lsn: 958, time: 1338903440.241341, len: 78 -Update lsn: 959, time: 1338903440.241369, len: 78 -Update lsn: 960, time: 1338903440.241396, len: 78 -Update lsn: 961, time: 1338903440.241424, len: 78 -Update lsn: 962, time: 1338903440.241451, len: 78 -Update lsn: 963, time: 1338903440.241478, len: 78 -Update lsn: 964, time: 1338903440.241524, len: 78 -Update lsn: 965, time: 1338903440.241552, len: 78 -Update lsn: 966, time: 1338903440.241604, len: 78 -Update lsn: 967, time: 1338903440.241632, len: 78 -Update lsn: 968, time: 1338903440.241661, len: 78 -Update lsn: 969, time: 1338903440.241688, len: 78 -Update lsn: 970, time: 1338903440.241715, len: 78 -Update lsn: 971, time: 1338903440.241741, len: 78 -Update lsn: 972, time: 1338903440.241769, len: 78 -Update lsn: 973, time: 1338903440.241796, len: 78 -Update lsn: 974, time: 1338903440.241823, len: 78 -Update lsn: 975, time: 1338903440.241851, len: 78 -Update lsn: 976, time: 1338903440.241879, len: 78 -Update lsn: 977, time: 1338903440.241909, len: 78 -Update lsn: 978, time: 1338903440.241935, len: 78 -Update lsn: 979, time: 1338903440.241962, len: 78 -Update lsn: 980, time: 1338903440.241990, len: 78 -Update lsn: 981, time: 1338903440.242017, len: 78 -Update lsn: 982, time: 1338903440.242044, len: 78 -Update lsn: 983, time: 1338903440.242071, len: 78 -Update lsn: 984, time: 1338903440.242099, len: 78 -Update lsn: 985, time: 1338903440.242126, len: 78 -Update lsn: 986, time: 1338903440.242154, len: 78 -Update lsn: 987, time: 1338903440.242181, len: 78 -Update lsn: 988, time: 1338903440.242208, len: 78 -Update lsn: 989, time: 1338903440.242236, len: 78 -Update lsn: 990, time: 1338903440.242263, len: 78 -Update lsn: 991, time: 1338903440.242290, len: 78 -Update lsn: 992, time: 1338903440.242317, len: 78 -Update lsn: 993, time: 1338903440.242343, len: 78 -Update lsn: 994, time: 1338903440.242370, len: 78 -Update lsn: 995, time: 1338903440.242398, len: 78 -Update lsn: 996, time: 1338903440.242425, len: 78 -Update lsn: 997, time: 1338903440.242452, len: 78 -Update lsn: 998, time: 1338903440.242479, len: 78 -Update lsn: 999, time: 1338903440.242506, len: 78 -Update lsn: 1000, time: 1338903440.242534, len: 78 -Update lsn: 1001, time: 1338903440.242582, len: 78 -Update lsn: 1002, time: 1338903440.243265, len: 109 -Update lsn: 1003, time: 1338903440.243367, len: 109 -Update lsn: 1004, time: 1338903440.243399, len: 109 -Update lsn: 1005, time: 1338903440.243427, len: 109 -Update lsn: 1006, time: 1338903440.243455, len: 109 -Update lsn: 1007, time: 1338903440.243484, len: 109 -Update lsn: 1008, time: 1338903440.243512, len: 109 -Update lsn: 1009, time: 1338903440.243540, len: 109 -Update lsn: 1010, time: 1338903440.243569, len: 109 -Update lsn: 1011, time: 1338903440.243598, len: 109 -Update lsn: 1012, time: 1338903440.243626, len: 110 -Update lsn: 1013, time: 1338903440.243654, len: 110 -Update lsn: 1014, time: 1338903440.243681, len: 110 -Update lsn: 1015, time: 1338903440.243710, len: 110 -Update lsn: 1016, time: 1338903440.243738, len: 110 -Update lsn: 1017, time: 1338903440.243767, len: 110 -Update lsn: 1018, time: 1338903440.243796, len: 110 -Update lsn: 1019, time: 1338903440.243826, len: 110 -Update lsn: 1020, time: 1338903440.243855, len: 110 -Update lsn: 1021, time: 1338903440.243883, len: 110 -Update lsn: 1022, time: 1338903440.243913, len: 110 -Update lsn: 1023, time: 1338903440.243941, len: 110 -Update lsn: 1024, time: 1338903440.243968, len: 110 -Update lsn: 1025, time: 1338903440.243996, len: 110 -Update lsn: 1026, time: 1338903440.244023, len: 110 -Update lsn: 1027, time: 1338903440.244049, len: 110 -Update lsn: 1028, time: 1338903440.244076, len: 110 -Update lsn: 1029, time: 1338903440.244103, len: 110 -Update lsn: 1030, time: 1338903440.244164, len: 110 -Update lsn: 1031, time: 1338903440.244193, len: 110 -Update lsn: 1032, time: 1338903440.244220, len: 110 -Update lsn: 1033, time: 1338903440.244246, len: 110 -Update lsn: 1034, time: 1338903440.244272, len: 110 -Update lsn: 1035, time: 1338903440.244299, len: 110 -Update lsn: 1036, time: 1338903440.244325, len: 110 -Update lsn: 1037, time: 1338903440.244351, len: 110 -Update lsn: 1038, time: 1338903440.244378, len: 110 -Update lsn: 1039, time: 1338903440.244404, len: 110 -Update lsn: 1040, time: 1338903440.244431, len: 110 -Update lsn: 1041, time: 1338903440.244457, len: 110 -Update lsn: 1042, time: 1338903440.244483, len: 110 -Update lsn: 1043, time: 1338903440.244509, len: 110 -Update lsn: 1044, time: 1338903440.244535, len: 110 -Update lsn: 1045, time: 1338903440.244561, len: 110 -Update lsn: 1046, time: 1338903440.244587, len: 110 -Update lsn: 1047, time: 1338903440.244613, len: 110 -Update lsn: 1048, time: 1338903440.244640, len: 110 -Update lsn: 1049, time: 1338903440.244666, len: 110 -Update lsn: 1050, time: 1338903440.244692, len: 110 -Update lsn: 1051, time: 1338903440.244718, len: 110 -Update lsn: 1052, time: 1338903440.244744, len: 110 -Update lsn: 1053, time: 1338903440.244771, len: 110 -Update lsn: 1054, time: 1338903440.244798, len: 110 -Update lsn: 1055, time: 1338903440.244827, len: 110 -Update lsn: 1056, time: 1338903440.244854, len: 110 -Update lsn: 1057, time: 1338903440.244881, len: 110 -Update lsn: 1058, time: 1338903440.244936, len: 110 -Update lsn: 1059, time: 1338903440.244995, len: 110 -Update lsn: 1060, time: 1338903440.245028, len: 110 -Update lsn: 1061, time: 1338903440.245057, len: 110 -Update lsn: 1062, time: 1338903440.245086, len: 110 -Update lsn: 1063, time: 1338903440.245115, len: 110 -Update lsn: 1064, time: 1338903440.245142, len: 110 -Update lsn: 1065, time: 1338903440.245169, len: 110 -Update lsn: 1066, time: 1338903440.245196, len: 110 -Update lsn: 1067, time: 1338903440.245222, len: 110 -Update lsn: 1068, time: 1338903440.245248, len: 110 -Update lsn: 1069, time: 1338903440.245275, len: 110 -Update lsn: 1070, time: 1338903440.245302, len: 110 -Update lsn: 1071, time: 1338903440.245329, len: 110 -Update lsn: 1072, time: 1338903440.245355, len: 110 -Update lsn: 1073, time: 1338903440.245382, len: 110 -Update lsn: 1074, time: 1338903440.245408, len: 110 -Update lsn: 1075, time: 1338903440.245435, len: 110 -Update lsn: 1076, time: 1338903440.245462, len: 110 -Update lsn: 1077, time: 1338903440.245491, len: 110 -Update lsn: 1078, time: 1338903440.245518, len: 110 -Update lsn: 1079, time: 1338903440.245545, len: 110 -Update lsn: 1080, time: 1338903440.245572, len: 110 -Update lsn: 1081, time: 1338903440.245600, len: 110 -Update lsn: 1082, time: 1338903440.245628, len: 110 -Update lsn: 1083, time: 1338903440.245656, len: 110 -Update lsn: 1084, time: 1338903440.245683, len: 110 -Update lsn: 1085, time: 1338903440.245709, len: 110 -Update lsn: 1086, time: 1338903440.245736, len: 110 -Update lsn: 1087, time: 1338903440.245763, len: 110 -Update lsn: 1088, time: 1338903440.245815, len: 110 -Update lsn: 1089, time: 1338903440.245847, len: 110 -Update lsn: 1090, time: 1338903440.245874, len: 110 -Update lsn: 1091, time: 1338903440.245900, len: 110 -Update lsn: 1092, time: 1338903440.245928, len: 110 -Update lsn: 1093, time: 1338903440.245955, len: 110 -Update lsn: 1094, time: 1338903440.245983, len: 110 -Update lsn: 1095, time: 1338903440.246011, len: 110 -Update lsn: 1096, time: 1338903440.246040, len: 110 -Update lsn: 1097, time: 1338903440.246068, len: 110 -Update lsn: 1098, time: 1338903440.246097, len: 110 -Update lsn: 1099, time: 1338903440.246124, len: 110 -Update lsn: 1100, time: 1338903440.246151, len: 110 -Update lsn: 1101, time: 1338903440.246177, len: 110 -Update lsn: 1102, time: 1338903440.246866, len: 175 -Update lsn: 1103, time: 1338903440.246967, len: 175 -Update lsn: 1104, time: 1338903440.247000, len: 175 -Update lsn: 1105, time: 1338903440.247028, len: 175 -Update lsn: 1106, time: 1338903440.247058, len: 175 -Update lsn: 1107, time: 1338903440.247086, len: 175 -Update lsn: 1108, time: 1338903440.247115, len: 175 -Update lsn: 1109, time: 1338903440.247144, len: 175 -Update lsn: 1110, time: 1338903440.247173, len: 175 -Update lsn: 1111, time: 1338903440.247202, len: 175 -Update lsn: 1112, time: 1338903440.247263, len: 176 -Update lsn: 1113, time: 1338903440.247297, len: 176 -Update lsn: 1114, time: 1338903440.247326, len: 176 -Update lsn: 1115, time: 1338903440.247355, len: 176 -Update lsn: 1116, time: 1338903440.247384, len: 176 -Update lsn: 1117, time: 1338903440.247415, len: 176 -Update lsn: 1118, time: 1338903440.247444, len: 176 -Update lsn: 1119, time: 1338903440.247473, len: 176 -Update lsn: 1120, time: 1338903440.247503, len: 176 -Update lsn: 1121, time: 1338903440.247531, len: 176 -Update lsn: 1122, time: 1338903440.247559, len: 176 -Update lsn: 1123, time: 1338903440.247586, len: 176 -Update lsn: 1124, time: 1338903440.247614, len: 176 -Update lsn: 1125, time: 1338903440.247641, len: 176 -Update lsn: 1126, time: 1338903440.247668, len: 176 -Update lsn: 1127, time: 1338903440.247695, len: 176 -Update lsn: 1128, time: 1338903440.247722, len: 176 -Update lsn: 1129, time: 1338903440.247749, len: 176 -Update lsn: 1130, time: 1338903440.247775, len: 176 -Update lsn: 1131, time: 1338903440.247801, len: 176 -Update lsn: 1132, time: 1338903440.247851, len: 176 -Update lsn: 1133, time: 1338903440.247880, len: 176 -Update lsn: 1134, time: 1338903440.247906, len: 176 -Update lsn: 1135, time: 1338903440.247932, len: 176 -Update lsn: 1136, time: 1338903440.247960, len: 176 -Update lsn: 1137, time: 1338903440.247986, len: 176 -Update lsn: 1138, time: 1338903440.248012, len: 176 -Update lsn: 1139, time: 1338903440.248039, len: 176 -Update lsn: 1140, time: 1338903440.248065, len: 176 -Update lsn: 1141, time: 1338903440.248092, len: 176 -Update lsn: 1142, time: 1338903440.248118, len: 176 -Update lsn: 1143, time: 1338903440.248146, len: 176 -Update lsn: 1144, time: 1338903440.248173, len: 176 -Update lsn: 1145, time: 1338903440.248201, len: 176 -Update lsn: 1146, time: 1338903440.248250, len: 176 -Update lsn: 1147, time: 1338903440.248282, len: 176 -Update lsn: 1148, time: 1338903440.248311, len: 176 -Update lsn: 1149, time: 1338903440.248339, len: 176 -Update lsn: 1150, time: 1338903440.248367, len: 176 -Update lsn: 1151, time: 1338903440.248394, len: 176 -Update lsn: 1152, time: 1338903440.248443, len: 176 -Update lsn: 1153, time: 1338903440.248471, len: 176 -Update lsn: 1154, time: 1338903440.248498, len: 176 -Update lsn: 1155, time: 1338903440.248525, len: 176 -Update lsn: 1156, time: 1338903440.248553, len: 176 -Update lsn: 1157, time: 1338903440.248579, len: 176 -Update lsn: 1158, time: 1338903440.248606, len: 176 -Update lsn: 1159, time: 1338903440.248633, len: 176 -Update lsn: 1160, time: 1338903440.248659, len: 176 -Update lsn: 1161, time: 1338903440.248686, len: 176 -Update lsn: 1162, time: 1338903440.248713, len: 176 -Update lsn: 1163, time: 1338903440.248740, len: 176 -Update lsn: 1164, time: 1338903440.248767, len: 176 -Update lsn: 1165, time: 1338903440.248794, len: 176 -Update lsn: 1166, time: 1338903440.248821, len: 176 -Update lsn: 1167, time: 1338903440.248849, len: 176 -Update lsn: 1168, time: 1338903440.248876, len: 176 -Update lsn: 1169, time: 1338903440.248904, len: 176 -Update lsn: 1170, time: 1338903440.248932, len: 176 -Update lsn: 1171, time: 1338903440.248982, len: 176 -Update lsn: 1172, time: 1338903440.249012, len: 176 -Update lsn: 1173, time: 1338903440.249038, len: 176 -Update lsn: 1174, time: 1338903440.249064, len: 176 -Update lsn: 1175, time: 1338903440.249091, len: 176 -Update lsn: 1176, time: 1338903440.249120, len: 176 -Update lsn: 1177, time: 1338903440.249149, len: 176 -Update lsn: 1178, time: 1338903440.249179, len: 176 -Update lsn: 1179, time: 1338903440.249208, len: 176 -Update lsn: 1180, time: 1338903440.249237, len: 176 -Update lsn: 1181, time: 1338903440.249265, len: 176 -Update lsn: 1182, time: 1338903440.249292, len: 176 -Update lsn: 1183, time: 1338903440.249320, len: 176 -Update lsn: 1184, time: 1338903440.249347, len: 176 -Update lsn: 1185, time: 1338903440.249375, len: 176 -Update lsn: 1186, time: 1338903440.249404, len: 176 -Update lsn: 1187, time: 1338903440.249431, len: 176 -Update lsn: 1188, time: 1338903440.249460, len: 176 -Update lsn: 1189, time: 1338903440.249490, len: 176 -Update lsn: 1190, time: 1338903440.249517, len: 176 -Update lsn: 1191, time: 1338903440.249563, len: 176 -Update lsn: 1192, time: 1338903440.249593, len: 176 -Update lsn: 1193, time: 1338903440.249621, len: 176 -Update lsn: 1194, time: 1338903440.249648, len: 176 -Update lsn: 1195, time: 1338903440.249676, len: 176 -Update lsn: 1196, time: 1338903440.249705, len: 176 -Update lsn: 1197, time: 1338903440.249733, len: 176 -Update lsn: 1198, time: 1338903440.249761, len: 176 -Update lsn: 1199, time: 1338903440.249789, len: 176 -Update lsn: 1200, time: 1338903440.249816, len: 176 -Update lsn: 1201, time: 1338903440.249846, len: 176 - -Insert lsn: 2, time: 1338903440.187947, len: 68 -Insert lsn: 3, time: 1338903440.190419, len: 68 -Insert lsn: 4, time: 1338903440.190539, len: 68 -Insert lsn: 5, time: 1338903440.190582, len: 68 -Insert lsn: 6, time: 1338903440.190608, len: 68 -Insert lsn: 7, time: 1338903440.190633, len: 68 -Insert lsn: 8, time: 1338903440.190657, len: 68 -Insert lsn: 9, time: 1338903440.190681, len: 68 -Insert lsn: 10, time: 1338903440.190712, len: 68 -Insert lsn: 11, time: 1338903440.190736, len: 68 -Insert lsn: 12, time: 1338903440.190762, len: 69 -Insert lsn: 13, time: 1338903440.190785, len: 69 -Insert lsn: 14, time: 1338903440.190810, len: 69 -Insert lsn: 15, time: 1338903440.190834, len: 69 -Insert lsn: 16, time: 1338903440.190858, len: 69 -Insert lsn: 17, time: 1338903440.190883, len: 69 -Insert lsn: 18, time: 1338903440.190908, len: 69 -Insert lsn: 19, time: 1338903440.190942, len: 69 -Insert lsn: 20, time: 1338903440.190967, len: 69 -Insert lsn: 21, time: 1338903440.190992, len: 69 -Insert lsn: 22, time: 1338903440.191015, len: 69 -Insert lsn: 23, time: 1338903440.191040, len: 69 -Insert lsn: 24, time: 1338903440.191064, len: 69 -Insert lsn: 25, time: 1338903440.191088, len: 69 -Insert lsn: 26, time: 1338903440.191112, len: 69 -Insert lsn: 27, time: 1338903440.191138, len: 69 -Insert lsn: 28, time: 1338903440.191163, len: 69 -Insert lsn: 29, time: 1338903440.191188, len: 69 -Insert lsn: 30, time: 1338903440.191213, len: 69 -Insert lsn: 31, time: 1338903440.191238, len: 69 -Insert lsn: 32, time: 1338903440.191262, len: 69 -Insert lsn: 33, time: 1338903440.191284, len: 69 -Insert lsn: 34, time: 1338903440.191319, len: 69 -Insert lsn: 35, time: 1338903440.191344, len: 69 -Insert lsn: 36, time: 1338903440.191369, len: 69 -Insert lsn: 37, time: 1338903440.191393, len: 69 -Insert lsn: 38, time: 1338903440.191417, len: 69 -Insert lsn: 39, time: 1338903440.191441, len: 69 -Insert lsn: 40, time: 1338903440.191479, len: 69 -Insert lsn: 41, time: 1338903440.191503, len: 69 -Insert lsn: 42, time: 1338903440.191526, len: 69 -Insert lsn: 43, time: 1338903440.191603, len: 69 -Insert lsn: 44, time: 1338903440.191632, len: 69 -Insert lsn: 45, time: 1338903440.191655, len: 69 -Insert lsn: 46, time: 1338903440.191681, len: 69 -Insert lsn: 47, time: 1338903440.191704, len: 69 -Insert lsn: 48, time: 1338903440.191727, len: 69 -Insert lsn: 49, time: 1338903440.191750, len: 69 -Insert lsn: 50, time: 1338903440.191774, len: 69 -Insert lsn: 51, time: 1338903440.191797, len: 69 -Insert lsn: 52, time: 1338903440.191820, len: 69 -Insert lsn: 53, time: 1338903440.191844, len: 69 -Insert lsn: 54, time: 1338903440.191874, len: 69 -Insert lsn: 55, time: 1338903440.191897, len: 69 -Insert lsn: 56, time: 1338903440.191921, len: 69 -Insert lsn: 57, time: 1338903440.191944, len: 69 -Insert lsn: 58, time: 1338903440.191967, len: 69 -Insert lsn: 59, time: 1338903440.191992, len: 69 -Insert lsn: 60, time: 1338903440.192016, len: 69 -Insert lsn: 61, time: 1338903440.192039, len: 69 -Insert lsn: 62, time: 1338903440.192063, len: 69 -Insert lsn: 63, time: 1338903440.192086, len: 69 -Insert lsn: 64, time: 1338903440.192111, len: 69 -Insert lsn: 65, time: 1338903440.192134, len: 69 -Insert lsn: 66, time: 1338903440.192164, len: 69 -Insert lsn: 67, time: 1338903440.192188, len: 69 -Insert lsn: 68, time: 1338903440.192212, len: 69 -Insert lsn: 69, time: 1338903440.192235, len: 69 -Insert lsn: 70, time: 1338903440.192278, len: 69 -Insert lsn: 71, time: 1338903440.192302, len: 69 -Insert lsn: 72, time: 1338903440.192327, len: 69 -Insert lsn: 73, time: 1338903440.192351, len: 69 -Insert lsn: 74, time: 1338903440.192376, len: 69 -Insert lsn: 75, time: 1338903440.192401, len: 69 -Insert lsn: 76, time: 1338903440.192424, len: 69 -Insert lsn: 77, time: 1338903440.192449, len: 69 -Insert lsn: 78, time: 1338903440.192473, len: 69 -Insert lsn: 79, time: 1338903440.192497, len: 69 -Insert lsn: 80, time: 1338903440.192521, len: 69 -Insert lsn: 81, time: 1338903440.192545, len: 69 -Insert lsn: 82, time: 1338903440.192569, len: 69 -Insert lsn: 83, time: 1338903440.192593, len: 69 -Insert lsn: 84, time: 1338903440.192642, len: 69 -Insert lsn: 85, time: 1338903440.192670, len: 69 -Insert lsn: 86, time: 1338903440.192701, len: 69 -Insert lsn: 87, time: 1338903440.192726, len: 69 -Insert lsn: 88, time: 1338903440.192749, len: 69 -Insert lsn: 89, time: 1338903440.192773, len: 69 -Insert lsn: 90, time: 1338903440.192798, len: 69 -Insert lsn: 91, time: 1338903440.192822, len: 69 -Insert lsn: 92, time: 1338903440.192846, len: 69 -Insert lsn: 93, time: 1338903440.192871, len: 69 -Insert lsn: 94, time: 1338903440.192896, len: 69 -Insert lsn: 95, time: 1338903440.192921, len: 69 -Insert lsn: 96, time: 1338903440.192946, len: 69 -Insert lsn: 97, time: 1338903440.192970, len: 69 -Insert lsn: 98, time: 1338903440.192993, len: 69 -Insert lsn: 99, time: 1338903440.193017, len: 69 -Insert lsn: 100, time: 1338903440.193042, len: 69 -Insert lsn: 101, time: 1338903440.193065, len: 69 -Insert lsn: 102, time: 1338903440.193547, len: 100 -Insert lsn: 103, time: 1338903440.207494, len: 100 -Insert lsn: 104, time: 1338903440.207539, len: 100 -Insert lsn: 105, time: 1338903440.207564, len: 100 -Insert lsn: 106, time: 1338903440.207613, len: 100 -Insert lsn: 107, time: 1338903440.207639, len: 100 -Insert lsn: 108, time: 1338903440.207665, len: 100 -Insert lsn: 109, time: 1338903440.207690, len: 100 -Insert lsn: 110, time: 1338903440.207717, len: 100 -Insert lsn: 111, time: 1338903440.207745, len: 100 -Insert lsn: 112, time: 1338903440.207770, len: 101 -Insert lsn: 113, time: 1338903440.207795, len: 101 -Insert lsn: 114, time: 1338903440.207819, len: 101 -Insert lsn: 115, time: 1338903440.207844, len: 101 -Insert lsn: 116, time: 1338903440.207870, len: 101 -Insert lsn: 117, time: 1338903440.207895, len: 101 -Insert lsn: 118, time: 1338903440.207918, len: 101 -Insert lsn: 119, time: 1338903440.207976, len: 101 -Insert lsn: 120, time: 1338903440.208004, len: 101 -Insert lsn: 121, time: 1338903440.208029, len: 101 -Insert lsn: 122, time: 1338903440.208054, len: 101 -Insert lsn: 123, time: 1338903440.208078, len: 101 -Insert lsn: 124, time: 1338903440.208119, len: 101 -Insert lsn: 125, time: 1338903440.208144, len: 101 -Insert lsn: 126, time: 1338903440.208168, len: 101 -Insert lsn: 127, time: 1338903440.208193, len: 101 -Insert lsn: 128, time: 1338903440.208218, len: 101 -Insert lsn: 129, time: 1338903440.208291, len: 101 -Insert lsn: 130, time: 1338903440.208318, len: 101 -Insert lsn: 131, time: 1338903440.208343, len: 101 -Insert lsn: 132, time: 1338903440.208370, len: 101 -Insert lsn: 133, time: 1338903440.208396, len: 101 -Insert lsn: 134, time: 1338903440.208422, len: 101 -Insert lsn: 135, time: 1338903440.208447, len: 101 -Insert lsn: 136, time: 1338903440.208473, len: 101 -Insert lsn: 137, time: 1338903440.208499, len: 101 -Insert lsn: 138, time: 1338903440.208561, len: 101 -Insert lsn: 139, time: 1338903440.208586, len: 101 -Insert lsn: 140, time: 1338903440.208610, len: 101 -Insert lsn: 141, time: 1338903440.208634, len: 101 -Insert lsn: 142, time: 1338903440.208664, len: 101 -Insert lsn: 143, time: 1338903440.208688, len: 101 -Insert lsn: 144, time: 1338903440.208712, len: 101 -Insert lsn: 145, time: 1338903440.208735, len: 101 -Insert lsn: 146, time: 1338903440.208760, len: 101 -Insert lsn: 147, time: 1338903440.208783, len: 101 -Insert lsn: 148, time: 1338903440.208807, len: 101 -Insert lsn: 149, time: 1338903440.208831, len: 101 -Insert lsn: 150, time: 1338903440.208875, len: 101 -Insert lsn: 151, time: 1338903440.208900, len: 101 -Insert lsn: 152, time: 1338903440.208924, len: 101 -Insert lsn: 153, time: 1338903440.208947, len: 101 -Insert lsn: 154, time: 1338903440.208971, len: 101 -Insert lsn: 155, time: 1338903440.208994, len: 101 -Insert lsn: 156, time: 1338903440.209018, len: 101 -Insert lsn: 157, time: 1338903440.209043, len: 101 -Insert lsn: 158, time: 1338903440.209066, len: 101 -Insert lsn: 159, time: 1338903440.209090, len: 101 -Insert lsn: 160, time: 1338903440.209126, len: 101 -Insert lsn: 161, time: 1338903440.209151, len: 101 -Insert lsn: 162, time: 1338903440.209175, len: 101 -Insert lsn: 163, time: 1338903440.209199, len: 101 -Insert lsn: 164, time: 1338903440.209223, len: 101 -Insert lsn: 165, time: 1338903440.209247, len: 101 -Insert lsn: 166, time: 1338903440.209296, len: 101 -Insert lsn: 167, time: 1338903440.209320, len: 101 -Insert lsn: 168, time: 1338903440.209344, len: 101 -Insert lsn: 169, time: 1338903440.209367, len: 101 -Insert lsn: 170, time: 1338903440.209390, len: 101 -Insert lsn: 171, time: 1338903440.209414, len: 101 -Insert lsn: 172, time: 1338903440.209438, len: 101 -Insert lsn: 173, time: 1338903440.209461, len: 101 -Insert lsn: 174, time: 1338903440.209485, len: 101 -Insert lsn: 175, time: 1338903440.209509, len: 101 -Insert lsn: 176, time: 1338903440.209533, len: 101 -Insert lsn: 177, time: 1338903440.209564, len: 101 -Insert lsn: 178, time: 1338903440.209589, len: 101 -Insert lsn: 179, time: 1338903440.209613, len: 101 -Insert lsn: 180, time: 1338903440.209637, len: 101 -Insert lsn: 181, time: 1338903440.209678, len: 101 -Insert lsn: 182, time: 1338903440.209703, len: 101 -Insert lsn: 183, time: 1338903440.209745, len: 101 -Insert lsn: 184, time: 1338903440.209770, len: 101 -Insert lsn: 185, time: 1338903440.209794, len: 101 -Insert lsn: 186, time: 1338903440.209819, len: 101 -Insert lsn: 187, time: 1338903440.209842, len: 101 -Insert lsn: 188, time: 1338903440.209866, len: 101 -Insert lsn: 189, time: 1338903440.209889, len: 101 -Insert lsn: 190, time: 1338903440.209913, len: 101 -Insert lsn: 191, time: 1338903440.209937, len: 101 -Insert lsn: 192, time: 1338903440.209961, len: 101 -Insert lsn: 193, time: 1338903440.209985, len: 101 -Insert lsn: 194, time: 1338903440.210010, len: 101 -Insert lsn: 195, time: 1338903440.210041, len: 101 -Insert lsn: 196, time: 1338903440.210065, len: 101 -Insert lsn: 197, time: 1338903440.210088, len: 101 -Insert lsn: 198, time: 1338903440.210112, len: 101 -Insert lsn: 199, time: 1338903440.210135, len: 101 -Insert lsn: 200, time: 1338903440.210160, len: 101 -Insert lsn: 201, time: 1338903440.210183, len: 101 -Insert lsn: 202, time: 1338903440.210887, len: 166 -Insert lsn: 203, time: 1338903440.213901, len: 166 -Insert lsn: 204, time: 1338903440.213959, len: 166 -Insert lsn: 205, time: 1338903440.213986, len: 166 -Insert lsn: 206, time: 1338903440.214033, len: 166 -Insert lsn: 207, time: 1338903440.214060, len: 166 -Insert lsn: 208, time: 1338903440.214119, len: 166 -Insert lsn: 209, time: 1338903440.214145, len: 166 -Insert lsn: 210, time: 1338903440.214170, len: 166 -Insert lsn: 211, time: 1338903440.214196, len: 166 -Insert lsn: 212, time: 1338903440.214221, len: 167 -Insert lsn: 213, time: 1338903440.214246, len: 167 -Insert lsn: 214, time: 1338903440.214271, len: 167 -Insert lsn: 215, time: 1338903440.214297, len: 167 -Insert lsn: 216, time: 1338903440.214322, len: 167 -Insert lsn: 217, time: 1338903440.214347, len: 167 -Insert lsn: 218, time: 1338903440.214373, len: 167 -Insert lsn: 219, time: 1338903440.214398, len: 167 -Insert lsn: 220, time: 1338903440.214430, len: 167 -Insert lsn: 221, time: 1338903440.214456, len: 167 -Insert lsn: 222, time: 1338903440.214482, len: 167 -Insert lsn: 223, time: 1338903440.214507, len: 167 -Insert lsn: 224, time: 1338903440.214531, len: 167 -Insert lsn: 225, time: 1338903440.214556, len: 167 -Insert lsn: 226, time: 1338903440.214580, len: 167 -Insert lsn: 227, time: 1338903440.214604, len: 167 -Insert lsn: 228, time: 1338903440.214628, len: 167 -Insert lsn: 229, time: 1338903440.214673, len: 167 -Insert lsn: 230, time: 1338903440.214703, len: 167 -Insert lsn: 231, time: 1338903440.214729, len: 167 -Insert lsn: 232, time: 1338903440.214753, len: 167 -Insert lsn: 233, time: 1338903440.214778, len: 167 -Insert lsn: 234, time: 1338903440.214828, len: 167 -Insert lsn: 235, time: 1338903440.214853, len: 167 -Insert lsn: 236, time: 1338903440.214878, len: 167 -Insert lsn: 237, time: 1338903440.214927, len: 167 -Insert lsn: 238, time: 1338903440.214953, len: 167 -Insert lsn: 239, time: 1338903440.214980, len: 167 -Insert lsn: 240, time: 1338903440.215005, len: 167 -Insert lsn: 241, time: 1338903440.215030, len: 167 -Insert lsn: 242, time: 1338903440.215055, len: 167 -Insert lsn: 243, time: 1338903440.215080, len: 167 -Insert lsn: 244, time: 1338903440.215105, len: 167 -Insert lsn: 245, time: 1338903440.215131, len: 167 -Insert lsn: 246, time: 1338903440.215157, len: 167 -Insert lsn: 247, time: 1338903440.215190, len: 167 -Insert lsn: 248, time: 1338903440.215215, len: 167 -Insert lsn: 249, time: 1338903440.215277, len: 167 -Insert lsn: 250, time: 1338903440.215327, len: 167 -Insert lsn: 251, time: 1338903440.215356, len: 167 -Insert lsn: 252, time: 1338903440.215382, len: 167 -Insert lsn: 253, time: 1338903440.215407, len: 167 -Insert lsn: 254, time: 1338903440.215432, len: 167 -Insert lsn: 255, time: 1338903440.215459, len: 167 -Insert lsn: 256, time: 1338903440.215486, len: 167 -Insert lsn: 257, time: 1338903440.215513, len: 167 -Insert lsn: 258, time: 1338903440.215539, len: 167 -Insert lsn: 259, time: 1338903440.215563, len: 167 -Insert lsn: 260, time: 1338903440.215590, len: 167 -Insert lsn: 261, time: 1338903440.215623, len: 167 -Insert lsn: 262, time: 1338903440.215649, len: 167 -Insert lsn: 263, time: 1338903440.215675, len: 167 -Insert lsn: 264, time: 1338903440.215699, len: 167 -Insert lsn: 265, time: 1338903440.215723, len: 167 -Insert lsn: 266, time: 1338903440.215748, len: 167 -Insert lsn: 267, time: 1338903440.215773, len: 167 -Insert lsn: 268, time: 1338903440.215797, len: 167 -Insert lsn: 269, time: 1338903440.215822, len: 167 -Insert lsn: 270, time: 1338903440.215866, len: 167 -Insert lsn: 271, time: 1338903440.215894, len: 167 -Insert lsn: 272, time: 1338903440.215918, len: 167 -Insert lsn: 273, time: 1338903440.215942, len: 167 -Insert lsn: 274, time: 1338903440.215968, len: 167 -Insert lsn: 275, time: 1338903440.216054, len: 167 -Insert lsn: 276, time: 1338903440.216105, len: 167 -Insert lsn: 277, time: 1338903440.216130, len: 167 -Insert lsn: 278, time: 1338903440.216155, len: 167 -Insert lsn: 279, time: 1338903440.216181, len: 167 -Insert lsn: 280, time: 1338903440.216207, len: 167 -Insert lsn: 281, time: 1338903440.216231, len: 167 -Insert lsn: 282, time: 1338903440.216256, len: 167 -Insert lsn: 283, time: 1338903440.216281, len: 167 -Insert lsn: 284, time: 1338903440.216306, len: 167 -Insert lsn: 285, time: 1338903440.216332, len: 167 -Insert lsn: 286, time: 1338903440.216357, len: 167 -Insert lsn: 287, time: 1338903440.216382, len: 167 -Insert lsn: 288, time: 1338903440.216407, len: 167 -Insert lsn: 289, time: 1338903440.216444, len: 167 -Insert lsn: 290, time: 1338903440.216470, len: 167 -Insert lsn: 291, time: 1338903440.216519, len: 167 -Insert lsn: 292, time: 1338903440.216549, len: 167 -Insert lsn: 293, time: 1338903440.216576, len: 167 -Insert lsn: 294, time: 1338903440.216602, len: 167 -Insert lsn: 295, time: 1338903440.216627, len: 167 -Insert lsn: 296, time: 1338903440.216652, len: 167 -Insert lsn: 297, time: 1338903440.216677, len: 167 -Insert lsn: 298, time: 1338903440.216701, len: 167 -Insert lsn: 299, time: 1338903440.216725, len: 167 -Insert lsn: 300, time: 1338903440.216749, len: 167 -Insert lsn: 301, time: 1338903440.216774, len: 167 -Insert lsn: 302, time: 1338903440.217291, len: 68 -Insert lsn: 303, time: 1338903440.217376, len: 68 -Insert lsn: 304, time: 1338903440.217406, len: 68 -Insert lsn: 305, time: 1338903440.217431, len: 68 -Insert lsn: 306, time: 1338903440.217458, len: 68 -Insert lsn: 307, time: 1338903440.217483, len: 68 -Insert lsn: 308, time: 1338903440.217508, len: 68 -Insert lsn: 309, time: 1338903440.217533, len: 68 -Insert lsn: 310, time: 1338903440.217565, len: 68 -Insert lsn: 311, time: 1338903440.217591, len: 68 -Insert lsn: 312, time: 1338903440.217618, len: 69 -Insert lsn: 313, time: 1338903440.217644, len: 69 -Insert lsn: 314, time: 1338903440.217670, len: 69 -Insert lsn: 315, time: 1338903440.217697, len: 69 -Insert lsn: 316, time: 1338903440.217722, len: 69 -Insert lsn: 317, time: 1338903440.217749, len: 69 -Insert lsn: 318, time: 1338903440.217776, len: 69 -Insert lsn: 319, time: 1338903440.217801, len: 69 -Insert lsn: 320, time: 1338903440.217865, len: 69 -Insert lsn: 321, time: 1338903440.217896, len: 69 -Insert lsn: 322, time: 1338903440.217923, len: 69 -Insert lsn: 323, time: 1338903440.217949, len: 69 -Insert lsn: 324, time: 1338903440.217974, len: 69 -Insert lsn: 325, time: 1338903440.218000, len: 69 -Insert lsn: 326, time: 1338903440.218045, len: 69 -Insert lsn: 327, time: 1338903440.218071, len: 69 -Insert lsn: 328, time: 1338903440.218097, len: 69 -Insert lsn: 329, time: 1338903440.218124, len: 69 -Insert lsn: 330, time: 1338903440.218150, len: 69 -Insert lsn: 331, time: 1338903440.218176, len: 69 -Insert lsn: 332, time: 1338903440.218203, len: 69 -Insert lsn: 333, time: 1338903440.218246, len: 69 -Insert lsn: 334, time: 1338903440.218277, len: 69 -Insert lsn: 335, time: 1338903440.218303, len: 69 -Insert lsn: 336, time: 1338903440.218329, len: 69 -Insert lsn: 337, time: 1338903440.218354, len: 69 -Insert lsn: 338, time: 1338903440.218380, len: 69 -Insert lsn: 339, time: 1338903440.218406, len: 69 -Insert lsn: 340, time: 1338903440.218431, len: 69 -Insert lsn: 341, time: 1338903440.218456, len: 69 -Insert lsn: 342, time: 1338903440.218491, len: 69 -Insert lsn: 343, time: 1338903440.218516, len: 69 -Insert lsn: 344, time: 1338903440.218542, len: 69 -Insert lsn: 345, time: 1338903440.218567, len: 69 -Insert lsn: 346, time: 1338903440.218592, len: 69 -Insert lsn: 347, time: 1338903440.218617, len: 69 -Insert lsn: 348, time: 1338903440.218643, len: 69 -Insert lsn: 349, time: 1338903440.218669, len: 69 -Insert lsn: 350, time: 1338903440.218695, len: 69 -Insert lsn: 351, time: 1338903440.218721, len: 69 -Insert lsn: 352, time: 1338903440.218748, len: 69 -Insert lsn: 353, time: 1338903440.218773, len: 69 -Insert lsn: 354, time: 1338903440.218798, len: 69 -Insert lsn: 355, time: 1338903440.218824, len: 69 -Insert lsn: 356, time: 1338903440.218851, len: 69 -Insert lsn: 357, time: 1338903440.218877, len: 69 -Insert lsn: 358, time: 1338903440.218915, len: 69 -Insert lsn: 359, time: 1338903440.218943, len: 69 -Insert lsn: 360, time: 1338903440.218969, len: 69 -Insert lsn: 361, time: 1338903440.219052, len: 69 -Insert lsn: 362, time: 1338903440.219089, len: 69 -Insert lsn: 363, time: 1338903440.219114, len: 69 -Insert lsn: 364, time: 1338903440.219139, len: 69 -Insert lsn: 365, time: 1338903440.219164, len: 69 -Insert lsn: 366, time: 1338903440.219190, len: 69 -Insert lsn: 367, time: 1338903440.219216, len: 69 -Insert lsn: 368, time: 1338903440.219241, len: 69 -Insert lsn: 369, time: 1338903440.219266, len: 69 -Insert lsn: 370, time: 1338903440.219291, len: 69 -Insert lsn: 371, time: 1338903440.219316, len: 69 -Insert lsn: 372, time: 1338903440.219342, len: 69 -Insert lsn: 373, time: 1338903440.219367, len: 69 -Insert lsn: 374, time: 1338903440.219391, len: 69 -Insert lsn: 375, time: 1338903440.219422, len: 69 -Insert lsn: 376, time: 1338903440.219448, len: 69 -Insert lsn: 377, time: 1338903440.219478, len: 69 -Insert lsn: 378, time: 1338903440.219503, len: 69 -Insert lsn: 379, time: 1338903440.219528, len: 69 -Insert lsn: 380, time: 1338903440.219552, len: 69 -Insert lsn: 381, time: 1338903440.219577, len: 69 -Insert lsn: 382, time: 1338903440.219601, len: 69 -Insert lsn: 383, time: 1338903440.219625, len: 69 -Insert lsn: 384, time: 1338903440.219650, len: 69 -Insert lsn: 385, time: 1338903440.219675, len: 69 -Insert lsn: 386, time: 1338903440.219700, len: 69 -Insert lsn: 387, time: 1338903440.219725, len: 69 -Insert lsn: 388, time: 1338903440.219749, len: 69 -Insert lsn: 389, time: 1338903440.219774, len: 69 -Insert lsn: 390, time: 1338903440.219798, len: 69 -Insert lsn: 391, time: 1338903440.219823, len: 69 -Insert lsn: 392, time: 1338903440.219847, len: 69 -Insert lsn: 393, time: 1338903440.219882, len: 69 -Insert lsn: 394, time: 1338903440.219907, len: 69 -Insert lsn: 395, time: 1338903440.219932, len: 69 -Insert lsn: 396, time: 1338903440.219957, len: 69 -Insert lsn: 397, time: 1338903440.219981, len: 69 -Insert lsn: 398, time: 1338903440.220006, len: 69 -Insert lsn: 399, time: 1338903440.220031, len: 69 -Insert lsn: 400, time: 1338903440.220055, len: 69 -Insert lsn: 401, time: 1338903440.220099, len: 69 -Insert lsn: 402, time: 1338903440.220698, len: 100 -Insert lsn: 403, time: 1338903440.220780, len: 100 -Insert lsn: 404, time: 1338903440.220809, len: 100 -Insert lsn: 405, time: 1338903440.220836, len: 100 -Insert lsn: 406, time: 1338903440.220861, len: 100 -Insert lsn: 407, time: 1338903440.220887, len: 100 -Insert lsn: 408, time: 1338903440.220913, len: 100 -Insert lsn: 409, time: 1338903440.220939, len: 100 -Insert lsn: 410, time: 1338903440.220966, len: 100 -Insert lsn: 411, time: 1338903440.220993, len: 100 -Insert lsn: 412, time: 1338903440.221020, len: 101 -Insert lsn: 413, time: 1338903440.221047, len: 101 -Insert lsn: 414, time: 1338903440.221074, len: 101 -Insert lsn: 415, time: 1338903440.221101, len: 101 -Insert lsn: 416, time: 1338903440.221127, len: 101 -Insert lsn: 417, time: 1338903440.221155, len: 101 -Insert lsn: 418, time: 1338903440.221181, len: 101 -Insert lsn: 419, time: 1338903440.221207, len: 101 -Insert lsn: 420, time: 1338903440.221233, len: 101 -Insert lsn: 421, time: 1338903440.221260, len: 101 -Insert lsn: 422, time: 1338903440.221287, len: 101 -Insert lsn: 423, time: 1338903440.221313, len: 101 -Insert lsn: 424, time: 1338903440.221339, len: 101 -Insert lsn: 425, time: 1338903440.221366, len: 101 -Insert lsn: 426, time: 1338903440.221393, len: 101 -Insert lsn: 427, time: 1338903440.221418, len: 101 -Insert lsn: 428, time: 1338903440.221443, len: 101 -Insert lsn: 429, time: 1338903440.221468, len: 101 -Insert lsn: 430, time: 1338903440.221493, len: 101 -Insert lsn: 431, time: 1338903440.221518, len: 101 -Insert lsn: 432, time: 1338903440.221605, len: 101 -Insert lsn: 433, time: 1338903440.221638, len: 101 -Insert lsn: 434, time: 1338903440.221663, len: 101 -Insert lsn: 435, time: 1338903440.221688, len: 101 -Insert lsn: 436, time: 1338903440.221714, len: 101 -Insert lsn: 437, time: 1338903440.221739, len: 101 -Insert lsn: 438, time: 1338903440.221764, len: 101 -Insert lsn: 439, time: 1338903440.221788, len: 101 -Insert lsn: 440, time: 1338903440.221814, len: 101 -Insert lsn: 441, time: 1338903440.221840, len: 101 -Insert lsn: 442, time: 1338903440.221865, len: 101 -Insert lsn: 443, time: 1338903440.221889, len: 101 -Insert lsn: 444, time: 1338903440.221914, len: 101 -Insert lsn: 445, time: 1338903440.221939, len: 101 -Insert lsn: 446, time: 1338903440.221964, len: 101 -Insert lsn: 447, time: 1338903440.221988, len: 101 -Insert lsn: 448, time: 1338903440.222013, len: 101 -Insert lsn: 449, time: 1338903440.222038, len: 101 -Insert lsn: 450, time: 1338903440.222062, len: 101 -Insert lsn: 451, time: 1338903440.222087, len: 101 -Insert lsn: 452, time: 1338903440.222111, len: 101 -Insert lsn: 453, time: 1338903440.222136, len: 101 -Insert lsn: 454, time: 1338903440.222160, len: 101 -Insert lsn: 455, time: 1338903440.222184, len: 101 -Insert lsn: 456, time: 1338903440.222211, len: 101 -Insert lsn: 457, time: 1338903440.222237, len: 101 -Insert lsn: 458, time: 1338903440.222264, len: 101 -Insert lsn: 459, time: 1338903440.222289, len: 101 -Insert lsn: 460, time: 1338903440.222314, len: 101 -Insert lsn: 461, time: 1338903440.222339, len: 101 -Insert lsn: 462, time: 1338903440.222366, len: 101 -Insert lsn: 463, time: 1338903440.222422, len: 101 -Insert lsn: 464, time: 1338903440.222450, len: 101 -Insert lsn: 465, time: 1338903440.222475, len: 101 -Insert lsn: 466, time: 1338903440.222500, len: 101 -Insert lsn: 467, time: 1338903440.222526, len: 101 -Insert lsn: 468, time: 1338903440.222562, len: 101 -Insert lsn: 469, time: 1338903440.222588, len: 101 -Insert lsn: 470, time: 1338903440.222614, len: 101 -Insert lsn: 471, time: 1338903440.222639, len: 101 -Insert lsn: 472, time: 1338903440.222664, len: 101 -Insert lsn: 473, time: 1338903440.222691, len: 101 -Insert lsn: 474, time: 1338903440.222717, len: 101 -Insert lsn: 475, time: 1338903440.222742, len: 101 -Insert lsn: 476, time: 1338903440.222767, len: 101 -Insert lsn: 477, time: 1338903440.222800, len: 101 -Insert lsn: 478, time: 1338903440.222826, len: 101 -Insert lsn: 479, time: 1338903440.222851, len: 101 -Insert lsn: 480, time: 1338903440.222876, len: 101 -Insert lsn: 481, time: 1338903440.222901, len: 101 -Insert lsn: 482, time: 1338903440.222926, len: 101 -Insert lsn: 483, time: 1338903440.222951, len: 101 -Insert lsn: 484, time: 1338903440.222976, len: 101 -Insert lsn: 485, time: 1338903440.223000, len: 101 -Insert lsn: 486, time: 1338903440.223025, len: 101 -Insert lsn: 487, time: 1338903440.223049, len: 101 -Insert lsn: 488, time: 1338903440.223074, len: 101 -Insert lsn: 489, time: 1338903440.223100, len: 101 -Insert lsn: 490, time: 1338903440.223125, len: 101 -Insert lsn: 491, time: 1338903440.223149, len: 101 -Insert lsn: 492, time: 1338903440.223174, len: 101 -Insert lsn: 493, time: 1338903440.223199, len: 101 -Insert lsn: 494, time: 1338903440.223256, len: 101 -Insert lsn: 495, time: 1338903440.223284, len: 101 -Insert lsn: 496, time: 1338903440.223311, len: 101 -Insert lsn: 497, time: 1338903440.223336, len: 101 -Insert lsn: 498, time: 1338903440.223361, len: 101 -Insert lsn: 499, time: 1338903440.223386, len: 101 -Insert lsn: 500, time: 1338903440.223410, len: 101 -Insert lsn: 501, time: 1338903440.223435, len: 101 -Insert lsn: 502, time: 1338903440.224114, len: 166 -Insert lsn: 503, time: 1338903440.224227, len: 166 -Insert lsn: 504, time: 1338903440.224259, len: 166 -Insert lsn: 505, time: 1338903440.224284, len: 166 -Insert lsn: 506, time: 1338903440.224311, len: 166 -Insert lsn: 507, time: 1338903440.224339, len: 166 -Insert lsn: 508, time: 1338903440.224365, len: 166 -Insert lsn: 509, time: 1338903440.224391, len: 166 -Insert lsn: 510, time: 1338903440.224418, len: 166 -Insert lsn: 511, time: 1338903440.224444, len: 166 -Insert lsn: 512, time: 1338903440.224471, len: 167 -Insert lsn: 513, time: 1338903440.224497, len: 167 -Insert lsn: 514, time: 1338903440.224523, len: 167 -Insert lsn: 515, time: 1338903440.224550, len: 167 -Insert lsn: 516, time: 1338903440.224576, len: 167 -Insert lsn: 517, time: 1338903440.224639, len: 167 -Insert lsn: 518, time: 1338903440.224671, len: 167 -Insert lsn: 519, time: 1338903440.224698, len: 167 -Insert lsn: 520, time: 1338903440.224725, len: 167 -Insert lsn: 521, time: 1338903440.224753, len: 167 -Insert lsn: 522, time: 1338903440.224780, len: 167 -Insert lsn: 523, time: 1338903440.224806, len: 167 -Insert lsn: 524, time: 1338903440.224833, len: 167 -Insert lsn: 525, time: 1338903440.224860, len: 167 -Insert lsn: 526, time: 1338903440.224888, len: 167 -Insert lsn: 527, time: 1338903440.224938, len: 167 -Insert lsn: 528, time: 1338903440.224967, len: 167 -Insert lsn: 529, time: 1338903440.224994, len: 167 -Insert lsn: 530, time: 1338903440.225020, len: 167 -Insert lsn: 531, time: 1338903440.225047, len: 167 -Insert lsn: 532, time: 1338903440.225073, len: 167 -Insert lsn: 533, time: 1338903440.225100, len: 167 -Insert lsn: 534, time: 1338903440.225126, len: 167 -Insert lsn: 535, time: 1338903440.225152, len: 167 -Insert lsn: 536, time: 1338903440.225180, len: 167 -Insert lsn: 537, time: 1338903440.225206, len: 167 -Insert lsn: 538, time: 1338903440.225260, len: 167 -Insert lsn: 539, time: 1338903440.225290, len: 167 -Insert lsn: 540, time: 1338903440.225316, len: 167 -Insert lsn: 541, time: 1338903440.225343, len: 167 -Insert lsn: 542, time: 1338903440.225369, len: 167 -Insert lsn: 543, time: 1338903440.225395, len: 167 -Insert lsn: 544, time: 1338903440.225421, len: 167 -Insert lsn: 545, time: 1338903440.225448, len: 167 -Insert lsn: 546, time: 1338903440.225474, len: 167 -Insert lsn: 547, time: 1338903440.225500, len: 167 -Insert lsn: 548, time: 1338903440.225527, len: 167 -Insert lsn: 549, time: 1338903440.225554, len: 167 -Insert lsn: 550, time: 1338903440.225580, len: 167 -Insert lsn: 551, time: 1338903440.225605, len: 167 -Insert lsn: 552, time: 1338903440.225631, len: 167 -Insert lsn: 553, time: 1338903440.225658, len: 167 -Insert lsn: 554, time: 1338903440.225685, len: 167 -Insert lsn: 555, time: 1338903440.225711, len: 167 -Insert lsn: 556, time: 1338903440.225738, len: 167 -Insert lsn: 557, time: 1338903440.225765, len: 167 -Insert lsn: 558, time: 1338903440.225792, len: 167 -Insert lsn: 559, time: 1338903440.225836, len: 167 -Insert lsn: 560, time: 1338903440.225865, len: 167 -Insert lsn: 561, time: 1338903440.225892, len: 167 -Insert lsn: 562, time: 1338903440.225919, len: 167 -Insert lsn: 563, time: 1338903440.225945, len: 167 -Insert lsn: 564, time: 1338903440.225971, len: 167 -Insert lsn: 565, time: 1338903440.225997, len: 167 -Insert lsn: 566, time: 1338903440.226024, len: 167 -Insert lsn: 567, time: 1338903440.226051, len: 167 -Insert lsn: 568, time: 1338903440.226080, len: 167 -Insert lsn: 569, time: 1338903440.226107, len: 167 -Insert lsn: 570, time: 1338903440.226134, len: 167 -Insert lsn: 571, time: 1338903440.226162, len: 167 -Insert lsn: 572, time: 1338903440.226190, len: 167 -Insert lsn: 573, time: 1338903440.226217, len: 167 -Insert lsn: 574, time: 1338903440.226244, len: 167 -Insert lsn: 575, time: 1338903440.226271, len: 167 -Insert lsn: 576, time: 1338903440.226296, len: 167 -Insert lsn: 577, time: 1338903440.226322, len: 167 -Insert lsn: 578, time: 1338903440.226348, len: 167 -Insert lsn: 579, time: 1338903440.226392, len: 167 -Insert lsn: 580, time: 1338903440.226420, len: 167 -Insert lsn: 581, time: 1338903440.226446, len: 167 -Insert lsn: 582, time: 1338903440.226471, len: 167 -Insert lsn: 583, time: 1338903440.226496, len: 167 -Insert lsn: 584, time: 1338903440.226521, len: 167 -Insert lsn: 585, time: 1338903440.226546, len: 167 -Insert lsn: 586, time: 1338903440.226571, len: 167 -Insert lsn: 587, time: 1338903440.226596, len: 167 -Insert lsn: 588, time: 1338903440.226622, len: 167 -Insert lsn: 589, time: 1338903440.226648, len: 167 -Insert lsn: 590, time: 1338903440.226674, len: 167 -Insert lsn: 591, time: 1338903440.226699, len: 167 -Insert lsn: 592, time: 1338903440.226724, len: 167 -Insert lsn: 593, time: 1338903440.226749, len: 167 -Insert lsn: 594, time: 1338903440.226774, len: 167 -Insert lsn: 595, time: 1338903440.226799, len: 167 -Insert lsn: 596, time: 1338903440.226825, len: 167 -Insert lsn: 597, time: 1338903440.226850, len: 167 -Insert lsn: 598, time: 1338903440.226882, len: 167 -Insert lsn: 599, time: 1338903440.226907, len: 167 -Insert lsn: 600, time: 1338903440.226949, len: 167 -Insert lsn: 601, time: 1338903440.226978, len: 167 -Update lsn: 602, time: 1338903440.227788, len: 77 -Update lsn: 603, time: 1338903440.227901, len: 77 -Update lsn: 604, time: 1338903440.227932, len: 77 -Update lsn: 605, time: 1338903440.227961, len: 77 -Update lsn: 606, time: 1338903440.227988, len: 77 -Update lsn: 607, time: 1338903440.228014, len: 77 -Update lsn: 608, time: 1338903440.228041, len: 77 -Update lsn: 609, time: 1338903440.228069, len: 77 -Update lsn: 610, time: 1338903440.228096, len: 77 -Update lsn: 611, time: 1338903440.228123, len: 77 -Update lsn: 612, time: 1338903440.228150, len: 78 -Update lsn: 613, time: 1338903440.228177, len: 78 -Update lsn: 614, time: 1338903440.228204, len: 78 -Update lsn: 615, time: 1338903440.228250, len: 78 -Update lsn: 616, time: 1338903440.228283, len: 78 -Update lsn: 617, time: 1338903440.228311, len: 78 -Update lsn: 618, time: 1338903440.228338, len: 78 -Update lsn: 619, time: 1338903440.228365, len: 78 -Update lsn: 620, time: 1338903440.228393, len: 78 -Update lsn: 621, time: 1338903440.228421, len: 78 -Update lsn: 622, time: 1338903440.228448, len: 78 -Update lsn: 623, time: 1338903440.228475, len: 78 -Update lsn: 624, time: 1338903440.228502, len: 78 -Update lsn: 625, time: 1338903440.228530, len: 78 -Update lsn: 626, time: 1338903440.228556, len: 78 -Update lsn: 627, time: 1338903440.228583, len: 78 -Update lsn: 628, time: 1338903440.228611, len: 78 -Update lsn: 629, time: 1338903440.228639, len: 78 -Update lsn: 630, time: 1338903440.228668, len: 78 -Update lsn: 631, time: 1338903440.228695, len: 78 -Update lsn: 632, time: 1338903440.228723, len: 78 -Update lsn: 633, time: 1338903440.228751, len: 78 -Update lsn: 634, time: 1338903440.228778, len: 78 -Update lsn: 635, time: 1338903440.228838, len: 78 -Update lsn: 636, time: 1338903440.228867, len: 78 -Update lsn: 637, time: 1338903440.228892, len: 78 -Update lsn: 638, time: 1338903440.228918, len: 78 -Update lsn: 639, time: 1338903440.228944, len: 78 -Update lsn: 640, time: 1338903440.228969, len: 78 -Update lsn: 641, time: 1338903440.228995, len: 78 -Update lsn: 642, time: 1338903440.229021, len: 78 -Update lsn: 643, time: 1338903440.229047, len: 78 -Update lsn: 644, time: 1338903440.229073, len: 78 -Update lsn: 645, time: 1338903440.229099, len: 78 -Update lsn: 646, time: 1338903440.229125, len: 78 -Update lsn: 647, time: 1338903440.229150, len: 78 -Update lsn: 648, time: 1338903440.229176, len: 78 -Update lsn: 649, time: 1338903440.229201, len: 78 -Update lsn: 650, time: 1338903440.229228, len: 78 -Update lsn: 651, time: 1338903440.229254, len: 78 -Update lsn: 652, time: 1338903440.229281, len: 78 -Update lsn: 653, time: 1338903440.229307, len: 78 -Update lsn: 654, time: 1338903440.229333, len: 78 -Update lsn: 655, time: 1338903440.229360, len: 78 -Update lsn: 656, time: 1338903440.229386, len: 78 -Update lsn: 657, time: 1338903440.229412, len: 78 -Update lsn: 658, time: 1338903440.229439, len: 78 -Update lsn: 659, time: 1338903440.229465, len: 78 -Update lsn: 660, time: 1338903440.229491, len: 78 -Update lsn: 661, time: 1338903440.229517, len: 78 -Update lsn: 662, time: 1338903440.229544, len: 78 -Update lsn: 663, time: 1338903440.229584, len: 78 -Update lsn: 664, time: 1338903440.229612, len: 78 -Update lsn: 665, time: 1338903440.229639, len: 78 -Update lsn: 666, time: 1338903440.229666, len: 78 -Update lsn: 667, time: 1338903440.229694, len: 78 -Update lsn: 668, time: 1338903440.229723, len: 78 -Update lsn: 669, time: 1338903440.229752, len: 78 -Update lsn: 670, time: 1338903440.229779, len: 78 -Update lsn: 671, time: 1338903440.229808, len: 78 -Update lsn: 672, time: 1338903440.229862, len: 78 -Update lsn: 673, time: 1338903440.229892, len: 78 -Update lsn: 674, time: 1338903440.229933, len: 78 -Update lsn: 675, time: 1338903440.229961, len: 78 -Update lsn: 676, time: 1338903440.229988, len: 78 -Update lsn: 677, time: 1338903440.230015, len: 78 -Update lsn: 678, time: 1338903440.230042, len: 78 -Update lsn: 679, time: 1338903440.230069, len: 78 -Update lsn: 680, time: 1338903440.230096, len: 78 -Update lsn: 681, time: 1338903440.230124, len: 78 -Update lsn: 682, time: 1338903440.230153, len: 78 -Update lsn: 683, time: 1338903440.230180, len: 78 -Update lsn: 684, time: 1338903440.230210, len: 78 -Update lsn: 685, time: 1338903440.230248, len: 78 -Update lsn: 686, time: 1338903440.230274, len: 78 -Update lsn: 687, time: 1338903440.230300, len: 78 -Update lsn: 688, time: 1338903440.230326, len: 78 -Update lsn: 689, time: 1338903440.230352, len: 78 -Update lsn: 690, time: 1338903440.230380, len: 78 -Update lsn: 691, time: 1338903440.230408, len: 78 -Update lsn: 692, time: 1338903440.230434, len: 78 -Update lsn: 693, time: 1338903440.230462, len: 78 -Update lsn: 694, time: 1338903440.230488, len: 78 -Update lsn: 695, time: 1338903440.230515, len: 78 -Update lsn: 696, time: 1338903440.230541, len: 78 -Update lsn: 697, time: 1338903440.230567, len: 78 -Update lsn: 698, time: 1338903440.230593, len: 78 -Update lsn: 699, time: 1338903440.230619, len: 78 -Update lsn: 700, time: 1338903440.230645, len: 78 -Update lsn: 701, time: 1338903440.230670, len: 78 -Update lsn: 702, time: 1338903440.231167, len: 109 -Update lsn: 703, time: 1338903440.231248, len: 109 -Update lsn: 704, time: 1338903440.231279, len: 109 -Update lsn: 705, time: 1338903440.231308, len: 109 -Update lsn: 706, time: 1338903440.231335, len: 109 -Update lsn: 707, time: 1338903440.231362, len: 109 -Update lsn: 708, time: 1338903440.231420, len: 109 -Update lsn: 709, time: 1338903440.231452, len: 109 -Update lsn: 710, time: 1338903440.231482, len: 109 -Update lsn: 711, time: 1338903440.231512, len: 109 -Update lsn: 712, time: 1338903440.231540, len: 110 -Update lsn: 713, time: 1338903440.231589, len: 110 -Update lsn: 714, time: 1338903440.231620, len: 110 -Update lsn: 715, time: 1338903440.231647, len: 110 -Update lsn: 716, time: 1338903440.231674, len: 110 -Update lsn: 717, time: 1338903440.231703, len: 110 -Update lsn: 718, time: 1338903440.231731, len: 110 -Update lsn: 719, time: 1338903440.231761, len: 110 -Update lsn: 720, time: 1338903440.231789, len: 110 -Update lsn: 721, time: 1338903440.231818, len: 110 -Update lsn: 722, time: 1338903440.231847, len: 110 -Update lsn: 723, time: 1338903440.231874, len: 110 -Update lsn: 724, time: 1338903440.231900, len: 110 -Update lsn: 725, time: 1338903440.231927, len: 110 -Update lsn: 726, time: 1338903440.231954, len: 110 -Update lsn: 727, time: 1338903440.231981, len: 110 -Update lsn: 728, time: 1338903440.232007, len: 110 -Update lsn: 729, time: 1338903440.232034, len: 110 -Update lsn: 730, time: 1338903440.232061, len: 110 -Update lsn: 731, time: 1338903440.232088, len: 110 -Update lsn: 732, time: 1338903440.232114, len: 110 -Update lsn: 733, time: 1338903440.232140, len: 110 -Update lsn: 734, time: 1338903440.232166, len: 110 -Update lsn: 735, time: 1338903440.232192, len: 110 -Update lsn: 736, time: 1338903440.232217, len: 110 -Update lsn: 737, time: 1338903440.232270, len: 110 -Update lsn: 738, time: 1338903440.232300, len: 110 -Update lsn: 739, time: 1338903440.232326, len: 110 -Update lsn: 740, time: 1338903440.232352, len: 110 -Update lsn: 741, time: 1338903440.232377, len: 110 -Update lsn: 742, time: 1338903440.232403, len: 110 -Update lsn: 743, time: 1338903440.232429, len: 110 -Update lsn: 744, time: 1338903440.232456, len: 110 -Update lsn: 745, time: 1338903440.232483, len: 110 -Update lsn: 746, time: 1338903440.232509, len: 110 -Update lsn: 747, time: 1338903440.232537, len: 110 -Update lsn: 748, time: 1338903440.232564, len: 110 -Update lsn: 749, time: 1338903440.232590, len: 110 -Update lsn: 750, time: 1338903440.232617, len: 110 -Update lsn: 751, time: 1338903440.232643, len: 110 -Update lsn: 752, time: 1338903440.232670, len: 110 -Update lsn: 753, time: 1338903440.232697, len: 110 -Update lsn: 754, time: 1338903440.232724, len: 110 -Update lsn: 755, time: 1338903440.232750, len: 110 -Update lsn: 756, time: 1338903440.232777, len: 110 -Update lsn: 757, time: 1338903440.232803, len: 110 -Update lsn: 758, time: 1338903440.232829, len: 110 -Update lsn: 759, time: 1338903440.232856, len: 110 -Update lsn: 760, time: 1338903440.232883, len: 110 -Update lsn: 761, time: 1338903440.232909, len: 110 -Update lsn: 762, time: 1338903440.232936, len: 110 -Update lsn: 763, time: 1338903440.232962, len: 110 -Update lsn: 764, time: 1338903440.232989, len: 110 -Update lsn: 765, time: 1338903440.233016, len: 110 -Update lsn: 766, time: 1338903440.233063, len: 110 -Update lsn: 767, time: 1338903440.233091, len: 110 -Update lsn: 768, time: 1338903440.233117, len: 110 -Update lsn: 769, time: 1338903440.233144, len: 110 -Update lsn: 770, time: 1338903440.233170, len: 110 -Update lsn: 771, time: 1338903440.233196, len: 110 -Update lsn: 772, time: 1338903440.233221, len: 110 -Update lsn: 773, time: 1338903440.233247, len: 110 -Update lsn: 774, time: 1338903440.233274, len: 110 -Update lsn: 775, time: 1338903440.233300, len: 110 -Update lsn: 776, time: 1338903440.233327, len: 110 -Update lsn: 777, time: 1338903440.233354, len: 110 -Update lsn: 778, time: 1338903440.233381, len: 110 -Update lsn: 779, time: 1338903440.233407, len: 110 -Update lsn: 780, time: 1338903440.233434, len: 110 -Update lsn: 781, time: 1338903440.233461, len: 110 -Update lsn: 782, time: 1338903440.233488, len: 110 -Update lsn: 783, time: 1338903440.233515, len: 110 -Update lsn: 784, time: 1338903440.233542, len: 110 -Update lsn: 785, time: 1338903440.233568, len: 110 -Update lsn: 786, time: 1338903440.233595, len: 110 -Update lsn: 787, time: 1338903440.233622, len: 110 -Update lsn: 788, time: 1338903440.233649, len: 110 -Update lsn: 789, time: 1338903440.233677, len: 110 -Update lsn: 790, time: 1338903440.233704, len: 110 -Update lsn: 791, time: 1338903440.233730, len: 110 -Update lsn: 792, time: 1338903440.233757, len: 110 -Update lsn: 793, time: 1338903440.233784, len: 110 -Update lsn: 794, time: 1338903440.233827, len: 110 -Update lsn: 795, time: 1338903440.233855, len: 110 -Update lsn: 796, time: 1338903440.233882, len: 110 -Update lsn: 797, time: 1338903440.233909, len: 110 -Update lsn: 798, time: 1338903440.233936, len: 110 -Update lsn: 799, time: 1338903440.233963, len: 110 -Update lsn: 800, time: 1338903440.233989, len: 110 -Update lsn: 801, time: 1338903440.234015, len: 110 -Update lsn: 802, time: 1338903440.234573, len: 175 -Update lsn: 803, time: 1338903440.234678, len: 175 -Update lsn: 804, time: 1338903440.234710, len: 175 -Update lsn: 805, time: 1338903440.234738, len: 175 -Update lsn: 806, time: 1338903440.234767, len: 175 -Update lsn: 807, time: 1338903440.234796, len: 175 -Update lsn: 808, time: 1338903440.234823, len: 175 -Update lsn: 809, time: 1338903440.234851, len: 175 -Update lsn: 810, time: 1338903440.234878, len: 175 -Update lsn: 811, time: 1338903440.234923, len: 175 -Update lsn: 812, time: 1338903440.234954, len: 176 -Update lsn: 813, time: 1338903440.234984, len: 176 -Update lsn: 814, time: 1338903440.235012, len: 176 -Update lsn: 815, time: 1338903440.235040, len: 176 -Update lsn: 816, time: 1338903440.235068, len: 176 -Update lsn: 817, time: 1338903440.235132, len: 176 -Update lsn: 818, time: 1338903440.235167, len: 176 -Update lsn: 819, time: 1338903440.235196, len: 176 -Update lsn: 820, time: 1338903440.235224, len: 176 -Update lsn: 821, time: 1338903440.235254, len: 176 -Update lsn: 822, time: 1338903440.235282, len: 176 -Update lsn: 823, time: 1338903440.235310, len: 176 -Update lsn: 824, time: 1338903440.235339, len: 176 -Update lsn: 825, time: 1338903440.235368, len: 176 -Update lsn: 826, time: 1338903440.235395, len: 176 -Update lsn: 827, time: 1338903440.235422, len: 176 -Update lsn: 828, time: 1338903440.235449, len: 176 -Update lsn: 829, time: 1338903440.235476, len: 176 -Update lsn: 830, time: 1338903440.235503, len: 176 -Update lsn: 831, time: 1338903440.235530, len: 176 -Update lsn: 832, time: 1338903440.235556, len: 176 -Update lsn: 833, time: 1338903440.235583, len: 176 -Update lsn: 834, time: 1338903440.235609, len: 176 -Update lsn: 835, time: 1338903440.235635, len: 176 -Update lsn: 836, time: 1338903440.235682, len: 176 -Update lsn: 837, time: 1338903440.235711, len: 176 -Update lsn: 838, time: 1338903440.235738, len: 176 -Update lsn: 839, time: 1338903440.235764, len: 176 -Update lsn: 840, time: 1338903440.235790, len: 176 -Update lsn: 841, time: 1338903440.235817, len: 176 -Update lsn: 842, time: 1338903440.235843, len: 176 -Update lsn: 843, time: 1338903440.235869, len: 176 -Update lsn: 844, time: 1338903440.235896, len: 176 -Update lsn: 845, time: 1338903440.235923, len: 176 -Update lsn: 846, time: 1338903440.235949, len: 176 -Update lsn: 847, time: 1338903440.235977, len: 176 -Update lsn: 848, time: 1338903440.236004, len: 176 -Update lsn: 849, time: 1338903440.236031, len: 176 -Update lsn: 850, time: 1338903440.236057, len: 176 -Update lsn: 851, time: 1338903440.236084, len: 176 -Update lsn: 852, time: 1338903440.236110, len: 176 -Update lsn: 853, time: 1338903440.236136, len: 176 -Update lsn: 854, time: 1338903440.236163, len: 176 -Update lsn: 855, time: 1338903440.236189, len: 176 -Update lsn: 856, time: 1338903440.236233, len: 176 -Update lsn: 857, time: 1338903440.236262, len: 176 -Update lsn: 858, time: 1338903440.236289, len: 176 -Update lsn: 859, time: 1338903440.236315, len: 176 -Update lsn: 860, time: 1338903440.236341, len: 176 -Update lsn: 861, time: 1338903440.236368, len: 176 -Update lsn: 862, time: 1338903440.236394, len: 176 -Update lsn: 863, time: 1338903440.236421, len: 176 -Update lsn: 864, time: 1338903440.236448, len: 176 -Update lsn: 865, time: 1338903440.236475, len: 176 -Update lsn: 866, time: 1338903440.236501, len: 176 -Update lsn: 867, time: 1338903440.236527, len: 176 -Update lsn: 868, time: 1338903440.236554, len: 176 -Update lsn: 869, time: 1338903440.236581, len: 176 -Update lsn: 870, time: 1338903440.236608, len: 176 -Update lsn: 871, time: 1338903440.236634, len: 176 -Update lsn: 872, time: 1338903440.236660, len: 176 -Update lsn: 873, time: 1338903440.236687, len: 176 -Update lsn: 874, time: 1338903440.236713, len: 176 -Update lsn: 875, time: 1338903440.236739, len: 176 -Update lsn: 876, time: 1338903440.236782, len: 176 -Update lsn: 877, time: 1338903440.236810, len: 176 -Update lsn: 878, time: 1338903440.236837, len: 176 -Update lsn: 879, time: 1338903440.236864, len: 176 -Update lsn: 880, time: 1338903440.236892, len: 176 -Update lsn: 881, time: 1338903440.236919, len: 176 -Update lsn: 882, time: 1338903440.236945, len: 176 -Update lsn: 883, time: 1338903440.236972, len: 176 -Update lsn: 884, time: 1338903440.236998, len: 176 -Update lsn: 885, time: 1338903440.237024, len: 176 -Update lsn: 886, time: 1338903440.237050, len: 176 -Update lsn: 887, time: 1338903440.237077, len: 176 -Update lsn: 888, time: 1338903440.237103, len: 176 -Update lsn: 889, time: 1338903440.237131, len: 176 -Update lsn: 890, time: 1338903440.237158, len: 176 -Update lsn: 891, time: 1338903440.237184, len: 176 -Update lsn: 892, time: 1338903440.237211, len: 176 -Update lsn: 893, time: 1338903440.237236, len: 176 -Update lsn: 894, time: 1338903440.237262, len: 176 -Update lsn: 895, time: 1338903440.237289, len: 176 -Update lsn: 896, time: 1338903440.237339, len: 176 -Update lsn: 897, time: 1338903440.237368, len: 176 -Update lsn: 898, time: 1338903440.237395, len: 176 -Update lsn: 899, time: 1338903440.237421, len: 176 -Update lsn: 900, time: 1338903440.237448, len: 176 -Update lsn: 901, time: 1338903440.237475, len: 176 -Update lsn: 902, time: 1338903440.238040, len: 77 -Update lsn: 903, time: 1338903440.238124, len: 77 -Update lsn: 904, time: 1338903440.238156, len: 77 -Update lsn: 905, time: 1338903440.238183, len: 77 -Update lsn: 906, time: 1338903440.238212, len: 77 -Update lsn: 907, time: 1338903440.238899, len: 77 -Update lsn: 908, time: 1338903440.238960, len: 77 -Update lsn: 909, time: 1338903440.238989, len: 77 -Update lsn: 910, time: 1338903440.239016, len: 77 -Update lsn: 911, time: 1338903440.239043, len: 77 -Update lsn: 912, time: 1338903440.239070, len: 78 -Update lsn: 913, time: 1338903440.239097, len: 78 -Update lsn: 914, time: 1338903440.239125, len: 78 -Update lsn: 915, time: 1338903440.239153, len: 78 -Update lsn: 916, time: 1338903440.239180, len: 78 -Update lsn: 917, time: 1338903440.239207, len: 78 -Update lsn: 918, time: 1338903440.239234, len: 78 -Update lsn: 919, time: 1338903440.239261, len: 78 -Update lsn: 920, time: 1338903440.239290, len: 78 -Update lsn: 921, time: 1338903440.240279, len: 78 -Update lsn: 922, time: 1338903440.240328, len: 78 -Update lsn: 923, time: 1338903440.240355, len: 78 -Update lsn: 924, time: 1338903440.240382, len: 78 -Update lsn: 925, time: 1338903440.240409, len: 78 -Update lsn: 926, time: 1338903440.240436, len: 78 -Update lsn: 927, time: 1338903440.240494, len: 78 -Update lsn: 928, time: 1338903440.240522, len: 78 -Update lsn: 929, time: 1338903440.240548, len: 78 -Update lsn: 930, time: 1338903440.240575, len: 78 -Update lsn: 931, time: 1338903440.240604, len: 78 -Update lsn: 932, time: 1338903440.240632, len: 78 -Update lsn: 933, time: 1338903440.240660, len: 78 -Update lsn: 934, time: 1338903440.240687, len: 78 -Update lsn: 935, time: 1338903440.240714, len: 78 -Update lsn: 936, time: 1338903440.240742, len: 78 -Update lsn: 937, time: 1338903440.240770, len: 78 -Update lsn: 938, time: 1338903440.240797, len: 78 -Update lsn: 939, time: 1338903440.240823, len: 78 -Update lsn: 940, time: 1338903440.240851, len: 78 -Update lsn: 941, time: 1338903440.240879, len: 78 -Update lsn: 942, time: 1338903440.240906, len: 78 -Update lsn: 943, time: 1338903440.240934, len: 78 -Update lsn: 944, time: 1338903440.240961, len: 78 -Update lsn: 945, time: 1338903440.240988, len: 78 -Update lsn: 946, time: 1338903440.241016, len: 78 -Update lsn: 947, time: 1338903440.241044, len: 78 -Update lsn: 948, time: 1338903440.241071, len: 78 -Update lsn: 949, time: 1338903440.241097, len: 78 -Update lsn: 950, time: 1338903440.241124, len: 78 -Update lsn: 951, time: 1338903440.241152, len: 78 -Update lsn: 952, time: 1338903440.241179, len: 78 -Update lsn: 953, time: 1338903440.241206, len: 78 -Update lsn: 954, time: 1338903440.241233, len: 78 -Update lsn: 955, time: 1338903440.241260, len: 78 -Update lsn: 956, time: 1338903440.241287, len: 78 -Update lsn: 957, time: 1338903440.241314, len: 78 -Update lsn: 958, time: 1338903440.241341, len: 78 -Update lsn: 959, time: 1338903440.241369, len: 78 -Update lsn: 960, time: 1338903440.241396, len: 78 -Update lsn: 961, time: 1338903440.241424, len: 78 -Update lsn: 962, time: 1338903440.241451, len: 78 -Update lsn: 963, time: 1338903440.241478, len: 78 -Update lsn: 964, time: 1338903440.241524, len: 78 -Update lsn: 965, time: 1338903440.241552, len: 78 -Update lsn: 966, time: 1338903440.241604, len: 78 -Update lsn: 967, time: 1338903440.241632, len: 78 -Update lsn: 968, time: 1338903440.241661, len: 78 -Update lsn: 969, time: 1338903440.241688, len: 78 -Update lsn: 970, time: 1338903440.241715, len: 78 -Update lsn: 971, time: 1338903440.241741, len: 78 -Update lsn: 972, time: 1338903440.241769, len: 78 -Update lsn: 973, time: 1338903440.241796, len: 78 -Update lsn: 974, time: 1338903440.241823, len: 78 -Update lsn: 975, time: 1338903440.241851, len: 78 -Update lsn: 976, time: 1338903440.241879, len: 78 -Update lsn: 977, time: 1338903440.241909, len: 78 -Update lsn: 978, time: 1338903440.241935, len: 78 -Update lsn: 979, time: 1338903440.241962, len: 78 -Update lsn: 980, time: 1338903440.241990, len: 78 -Update lsn: 981, time: 1338903440.242017, len: 78 -Update lsn: 982, time: 1338903440.242044, len: 78 -Update lsn: 983, time: 1338903440.242071, len: 78 -Update lsn: 984, time: 1338903440.242099, len: 78 -Update lsn: 985, time: 1338903440.242126, len: 78 -Update lsn: 986, time: 1338903440.242154, len: 78 -Update lsn: 987, time: 1338903440.242181, len: 78 -Update lsn: 988, time: 1338903440.242208, len: 78 -Update lsn: 989, time: 1338903440.242236, len: 78 -Update lsn: 990, time: 1338903440.242263, len: 78 -Update lsn: 991, time: 1338903440.242290, len: 78 -Update lsn: 992, time: 1338903440.242317, len: 78 -Update lsn: 993, time: 1338903440.242343, len: 78 -Update lsn: 994, time: 1338903440.242370, len: 78 -Update lsn: 995, time: 1338903440.242398, len: 78 -Update lsn: 996, time: 1338903440.242425, len: 78 -Update lsn: 997, time: 1338903440.242452, len: 78 -Update lsn: 998, time: 1338903440.242479, len: 78 -Update lsn: 999, time: 1338903440.242506, len: 78 -Update lsn: 1000, time: 1338903440.242534, len: 78 -Update lsn: 1001, time: 1338903440.242582, len: 78 -Update lsn: 1002, time: 1338903440.243265, len: 109 -Update lsn: 1003, time: 1338903440.243367, len: 109 -Update lsn: 1004, time: 1338903440.243399, len: 109 -Update lsn: 1005, time: 1338903440.243427, len: 109 -Update lsn: 1006, time: 1338903440.243455, len: 109 -Update lsn: 1007, time: 1338903440.243484, len: 109 -Update lsn: 1008, time: 1338903440.243512, len: 109 -Update lsn: 1009, time: 1338903440.243540, len: 109 -Update lsn: 1010, time: 1338903440.243569, len: 109 -Update lsn: 1011, time: 1338903440.243598, len: 109 -Update lsn: 1012, time: 1338903440.243626, len: 110 -Update lsn: 1013, time: 1338903440.243654, len: 110 -Update lsn: 1014, time: 1338903440.243681, len: 110 -Update lsn: 1015, time: 1338903440.243710, len: 110 -Update lsn: 1016, time: 1338903440.243738, len: 110 -Update lsn: 1017, time: 1338903440.243767, len: 110 -Update lsn: 1018, time: 1338903440.243796, len: 110 -Update lsn: 1019, time: 1338903440.243826, len: 110 -Update lsn: 1020, time: 1338903440.243855, len: 110 -Update lsn: 1021, time: 1338903440.243883, len: 110 -Update lsn: 1022, time: 1338903440.243913, len: 110 -Update lsn: 1023, time: 1338903440.243941, len: 110 -Update lsn: 1024, time: 1338903440.243968, len: 110 -Update lsn: 1025, time: 1338903440.243996, len: 110 -Update lsn: 1026, time: 1338903440.244023, len: 110 -Update lsn: 1027, time: 1338903440.244049, len: 110 -Update lsn: 1028, time: 1338903440.244076, len: 110 -Update lsn: 1029, time: 1338903440.244103, len: 110 -Update lsn: 1030, time: 1338903440.244164, len: 110 -Update lsn: 1031, time: 1338903440.244193, len: 110 -Update lsn: 1032, time: 1338903440.244220, len: 110 -Update lsn: 1033, time: 1338903440.244246, len: 110 -Update lsn: 1034, time: 1338903440.244272, len: 110 -Update lsn: 1035, time: 1338903440.244299, len: 110 -Update lsn: 1036, time: 1338903440.244325, len: 110 -Update lsn: 1037, time: 1338903440.244351, len: 110 -Update lsn: 1038, time: 1338903440.244378, len: 110 -Update lsn: 1039, time: 1338903440.244404, len: 110 -Update lsn: 1040, time: 1338903440.244431, len: 110 -Update lsn: 1041, time: 1338903440.244457, len: 110 -Update lsn: 1042, time: 1338903440.244483, len: 110 -Update lsn: 1043, time: 1338903440.244509, len: 110 -Update lsn: 1044, time: 1338903440.244535, len: 110 -Update lsn: 1045, time: 1338903440.244561, len: 110 -Update lsn: 1046, time: 1338903440.244587, len: 110 -Update lsn: 1047, time: 1338903440.244613, len: 110 -Update lsn: 1048, time: 1338903440.244640, len: 110 -Update lsn: 1049, time: 1338903440.244666, len: 110 -Update lsn: 1050, time: 1338903440.244692, len: 110 -Update lsn: 1051, time: 1338903440.244718, len: 110 -Update lsn: 1052, time: 1338903440.244744, len: 110 -Update lsn: 1053, time: 1338903440.244771, len: 110 -Update lsn: 1054, time: 1338903440.244798, len: 110 -Update lsn: 1055, time: 1338903440.244827, len: 110 -Update lsn: 1056, time: 1338903440.244854, len: 110 -Update lsn: 1057, time: 1338903440.244881, len: 110 -Update lsn: 1058, time: 1338903440.244936, len: 110 -Update lsn: 1059, time: 1338903440.244995, len: 110 -Update lsn: 1060, time: 1338903440.245028, len: 110 -Update lsn: 1061, time: 1338903440.245057, len: 110 -Update lsn: 1062, time: 1338903440.245086, len: 110 -Update lsn: 1063, time: 1338903440.245115, len: 110 -Update lsn: 1064, time: 1338903440.245142, len: 110 -Update lsn: 1065, time: 1338903440.245169, len: 110 -Update lsn: 1066, time: 1338903440.245196, len: 110 -Update lsn: 1067, time: 1338903440.245222, len: 110 -Update lsn: 1068, time: 1338903440.245248, len: 110 -Update lsn: 1069, time: 1338903440.245275, len: 110 -Update lsn: 1070, time: 1338903440.245302, len: 110 -Update lsn: 1071, time: 1338903440.245329, len: 110 -Update lsn: 1072, time: 1338903440.245355, len: 110 -Update lsn: 1073, time: 1338903440.245382, len: 110 -Update lsn: 1074, time: 1338903440.245408, len: 110 -Update lsn: 1075, time: 1338903440.245435, len: 110 -Update lsn: 1076, time: 1338903440.245462, len: 110 -Update lsn: 1077, time: 1338903440.245491, len: 110 -Update lsn: 1078, time: 1338903440.245518, len: 110 -Update lsn: 1079, time: 1338903440.245545, len: 110 -Update lsn: 1080, time: 1338903440.245572, len: 110 -Update lsn: 1081, time: 1338903440.245600, len: 110 -Update lsn: 1082, time: 1338903440.245628, len: 110 -Update lsn: 1083, time: 1338903440.245656, len: 110 -Update lsn: 1084, time: 1338903440.245683, len: 110 -Update lsn: 1085, time: 1338903440.245709, len: 110 -Update lsn: 1086, time: 1338903440.245736, len: 110 -Update lsn: 1087, time: 1338903440.245763, len: 110 -Update lsn: 1088, time: 1338903440.245815, len: 110 -Update lsn: 1089, time: 1338903440.245847, len: 110 -Update lsn: 1090, time: 1338903440.245874, len: 110 -Update lsn: 1091, time: 1338903440.245900, len: 110 -Update lsn: 1092, time: 1338903440.245928, len: 110 -Update lsn: 1093, time: 1338903440.245955, len: 110 -Update lsn: 1094, time: 1338903440.245983, len: 110 -Update lsn: 1095, time: 1338903440.246011, len: 110 -Update lsn: 1096, time: 1338903440.246040, len: 110 -Update lsn: 1097, time: 1338903440.246068, len: 110 -Update lsn: 1098, time: 1338903440.246097, len: 110 -Update lsn: 1099, time: 1338903440.246124, len: 110 -Update lsn: 1100, time: 1338903440.246151, len: 110 -Update lsn: 1101, time: 1338903440.246177, len: 110 -Update lsn: 1102, time: 1338903440.246866, len: 175 -Update lsn: 1103, time: 1338903440.246967, len: 175 -Update lsn: 1104, time: 1338903440.247000, len: 175 -Update lsn: 1105, time: 1338903440.247028, len: 175 -Update lsn: 1106, time: 1338903440.247058, len: 175 -Update lsn: 1107, time: 1338903440.247086, len: 175 -Update lsn: 1108, time: 1338903440.247115, len: 175 -Update lsn: 1109, time: 1338903440.247144, len: 175 -Update lsn: 1110, time: 1338903440.247173, len: 175 -Update lsn: 1111, time: 1338903440.247202, len: 175 -Update lsn: 1112, time: 1338903440.247263, len: 176 -Update lsn: 1113, time: 1338903440.247297, len: 176 -Update lsn: 1114, time: 1338903440.247326, len: 176 -Update lsn: 1115, time: 1338903440.247355, len: 176 -Update lsn: 1116, time: 1338903440.247384, len: 176 -Update lsn: 1117, time: 1338903440.247415, len: 176 -Update lsn: 1118, time: 1338903440.247444, len: 176 -Update lsn: 1119, time: 1338903440.247473, len: 176 -Update lsn: 1120, time: 1338903440.247503, len: 176 -Update lsn: 1121, time: 1338903440.247531, len: 176 -Update lsn: 1122, time: 1338903440.247559, len: 176 -Update lsn: 1123, time: 1338903440.247586, len: 176 -Update lsn: 1124, time: 1338903440.247614, len: 176 -Update lsn: 1125, time: 1338903440.247641, len: 176 -Update lsn: 1126, time: 1338903440.247668, len: 176 -Update lsn: 1127, time: 1338903440.247695, len: 176 -Update lsn: 1128, time: 1338903440.247722, len: 176 -Update lsn: 1129, time: 1338903440.247749, len: 176 -Update lsn: 1130, time: 1338903440.247775, len: 176 -Update lsn: 1131, time: 1338903440.247801, len: 176 -Update lsn: 1132, time: 1338903440.247851, len: 176 -Update lsn: 1133, time: 1338903440.247880, len: 176 -Update lsn: 1134, time: 1338903440.247906, len: 176 -Update lsn: 1135, time: 1338903440.247932, len: 176 -Update lsn: 1136, time: 1338903440.247960, len: 176 -Update lsn: 1137, time: 1338903440.247986, len: 176 -Update lsn: 1138, time: 1338903440.248012, len: 176 -Update lsn: 1139, time: 1338903440.248039, len: 176 -Update lsn: 1140, time: 1338903440.248065, len: 176 -Update lsn: 1141, time: 1338903440.248092, len: 176 -Update lsn: 1142, time: 1338903440.248118, len: 176 -Update lsn: 1143, time: 1338903440.248146, len: 176 -Update lsn: 1144, time: 1338903440.248173, len: 176 -Update lsn: 1145, time: 1338903440.248201, len: 176 -Update lsn: 1146, time: 1338903440.248250, len: 176 -Update lsn: 1147, time: 1338903440.248282, len: 176 -Update lsn: 1148, time: 1338903440.248311, len: 176 -Update lsn: 1149, time: 1338903440.248339, len: 176 -Update lsn: 1150, time: 1338903440.248367, len: 176 -Update lsn: 1151, time: 1338903440.248394, len: 176 -Update lsn: 1152, time: 1338903440.248443, len: 176 -Update lsn: 1153, time: 1338903440.248471, len: 176 -Update lsn: 1154, time: 1338903440.248498, len: 176 -Update lsn: 1155, time: 1338903440.248525, len: 176 -Update lsn: 1156, time: 1338903440.248553, len: 176 -Update lsn: 1157, time: 1338903440.248579, len: 176 -Update lsn: 1158, time: 1338903440.248606, len: 176 -Update lsn: 1159, time: 1338903440.248633, len: 176 -Update lsn: 1160, time: 1338903440.248659, len: 176 -Update lsn: 1161, time: 1338903440.248686, len: 176 -Update lsn: 1162, time: 1338903440.248713, len: 176 -Update lsn: 1163, time: 1338903440.248740, len: 176 -Update lsn: 1164, time: 1338903440.248767, len: 176 -Update lsn: 1165, time: 1338903440.248794, len: 176 -Update lsn: 1166, time: 1338903440.248821, len: 176 -Update lsn: 1167, time: 1338903440.248849, len: 176 -Update lsn: 1168, time: 1338903440.248876, len: 176 -Update lsn: 1169, time: 1338903440.248904, len: 176 -Update lsn: 1170, time: 1338903440.248932, len: 176 -Update lsn: 1171, time: 1338903440.248982, len: 176 -Update lsn: 1172, time: 1338903440.249012, len: 176 -Update lsn: 1173, time: 1338903440.249038, len: 176 -Update lsn: 1174, time: 1338903440.249064, len: 176 -Update lsn: 1175, time: 1338903440.249091, len: 176 -Update lsn: 1176, time: 1338903440.249120, len: 176 -Update lsn: 1177, time: 1338903440.249149, len: 176 -Update lsn: 1178, time: 1338903440.249179, len: 176 -Update lsn: 1179, time: 1338903440.249208, len: 176 -Update lsn: 1180, time: 1338903440.249237, len: 176 -Update lsn: 1181, time: 1338903440.249265, len: 176 -Update lsn: 1182, time: 1338903440.249292, len: 176 -Update lsn: 1183, time: 1338903440.249320, len: 176 -Update lsn: 1184, time: 1338903440.249347, len: 176 -Update lsn: 1185, time: 1338903440.249375, len: 176 -Update lsn: 1186, time: 1338903440.249404, len: 176 -Update lsn: 1187, time: 1338903440.249431, len: 176 -Update lsn: 1188, time: 1338903440.249460, len: 176 -Update lsn: 1189, time: 1338903440.249490, len: 176 -Update lsn: 1190, time: 1338903440.249517, len: 176 -Update lsn: 1191, time: 1338903440.249563, len: 176 -Update lsn: 1192, time: 1338903440.249593, len: 176 -Update lsn: 1193, time: 1338903440.249621, len: 176 -Update lsn: 1194, time: 1338903440.249648, len: 176 -Update lsn: 1195, time: 1338903440.249676, len: 176 -Update lsn: 1196, time: 1338903440.249705, len: 176 -Update lsn: 1197, time: 1338903440.249733, len: 176 -Update lsn: 1198, time: 1338903440.249761, len: 176 -Update lsn: 1199, time: 1338903440.249789, len: 176 -Update lsn: 1200, time: 1338903440.249816, len: 176 -Update lsn: 1201, time: 1338903440.249846, len: 176 diff --git a/test/connector_c/xlog_rpl.test.py b/test/connector_c/xlog_rpl.test.py deleted file mode 100644 index 5f774f785bc7ec7e841b009056badff89581d3d4..0000000000000000000000000000000000000000 --- a/test/connector_c/xlog_rpl.test.py +++ /dev/null @@ -1,33 +0,0 @@ -import subprocess -import sys -import os - -from lib.tarantool_server import TarantoolServer - -p = subprocess.Popen([os.path.join(builddir, "test/connector_c/xlog"), - os.path.abspath("connector_c/connector.xlog")], - stdout=subprocess.PIPE) -o,e = p.communicate() -sys.stdout.write(o) - -server.stop() -server.deploy("connector_c/cfg/master.cfg") -server.stop() - -current_xlog = os.path.join(vardir, "00000000000000000002.xlog") -os.symlink(os.path.abspath("connector_c/connector.xlog"), current_xlog) - -server.start() - -print "" - -p = subprocess.Popen([os.path.join(builddir, "test/connector_c/rpl"), - "127.0.0.1", "33016", "1200"], - stdout=subprocess.PIPE) -o,e = p.communicate() -sys.stdout.write(o) - -server.stop() -server.deploy() - -# vim: syntax=python diff --git a/test/lib/box_connection.py b/test/lib/box_connection.py index e4bce7ab75a86483b9edf5cfb44b6abb30ba0452..9d318de0da6e840a691062cf8ddf5c957816df84 100644 --- a/test/lib/box_connection.py +++ b/test/lib/box_connection.py @@ -44,6 +44,9 @@ class BoxConnection(TarantoolConnection): def connect(self): self.py_con.connect() + def authenticate(self, user, password): + self.py_con.authenticate(user, password) + def disconnect(self): self.py_con.close() @@ -78,7 +81,7 @@ class BoxConnection(TarantoolConnection): request = statement.pack(self.py_con) with warnings.catch_warnings(): warnings.simplefilter("ignore") - response = self.py_con._send_request(request, False) + response = self.py_con._send_request(request) if not silent: print statement.unpack(response) diff --git a/test/lib/sql_ast.py b/test/lib/sql_ast.py index 5fd61049385740b35e4fccfa1333080b39bbe44b..1887f9aba3c0f984c43b184b8e207261cff3ec38 100644 --- a/test/lib/sql_ast.py +++ b/test/lib/sql_ast.py @@ -128,10 +128,12 @@ class StatementUpdate(Statement): raise RuntimeError("UPDATE can only be made by the" " primary key (#0)") self.value_list = where[1] + if not isinstance(self.value_list, (list, tuple)): + self.value_list = [self.value_list] self.update_list = update_list def pack(self, connection): - return RequestUpdate(connection, self.space_no, self.value_list, self.update_list) + return RequestUpdate(connection, self.space_no, 0, self.value_list, self.update_list) def unpack(self, response): if response.return_code: @@ -146,9 +148,11 @@ class StatementDelete(Statement): raise RuntimeError("DELETE can only be made by the " "primary key (#0)") self.value_list = where[1] + if not isinstance(self.value_list, (list, tuple)): + self.value_list = [self.value_list] def pack(self, connection): - return RequestDelete(connection, self.space_no, self.value_list) + return RequestDelete(connection, self.space_no, 0, self.value_list) def unpack(self, response): if response.return_code: @@ -159,6 +163,8 @@ class StatementSelect(Statement): def __init__(self, table_name, where, limit): self.space_no = table_name (self.index_no, self.key) = where + if not isinstance(self.key, (list, tuple)): + self.key = [self.key] self.offset = 0 self.limit = limit diff --git a/test/lib/tarantool-python b/test/lib/tarantool-python index ef3a3b444b9a4e8a90bb5f631687b13f5890048b..0f9d99ecb770586ca011800a6e3921c3353c7459 160000 --- a/test/lib/tarantool-python +++ b/test/lib/tarantool-python @@ -1 +1 @@ -Subproject commit ef3a3b444b9a4e8a90bb5f631687b13f5890048b +Subproject commit 0f9d99ecb770586ca011800a6e3921c3353c7459 diff --git a/test/lib/tarantool_server.py b/test/lib/tarantool_server.py index a2b158af3754870cee93e807fa5aa4e974883a32..69155ea3f892cd12d673125a640e0cd4256988dd 100644 --- a/test/lib/tarantool_server.py +++ b/test/lib/tarantool_server.py @@ -295,16 +295,6 @@ class TarantoolServer(Server): return self._cfgfile_source = os.path.abspath(path) - @property - def init_lua_source(self): - if not hasattr(self, '_init_lua_source'): self._init_lua_source = None - return self._init_lua_source - @init_lua_source.setter - def init_lua_source(self, val): - if val is None: - return - self._init_lua_source = os.path.abspath(val) - @property def builddir(self): if not hasattr(self, '_builddir'): @@ -429,7 +419,7 @@ class TarantoolServer(Server): 'config': None, 'core': 'tarantool', 'gdb': False, - 'init_lua': None, + 'shebang': None, 'lua_libs': [], 'random_ports': True, 'valgrind': False, @@ -449,7 +439,7 @@ class TarantoolServer(Server): self.cfgfile_source = ini['config'] self.core = ini['core'] self.gdb = ini['gdb'] - self.init_lua_source = ini['init_lua'] + self.shebang = ini['shebang'] self.lua_libs = ini['lua_libs'] self.random_ports = ini['random_ports'] self.valgrind = ini['valgrind'] @@ -470,6 +460,7 @@ class TarantoolServer(Server): exe = os.path.join(_dir, cls.default_tarantool["bin"]) if os.access(exe, os.X_OK): cls.binary = os.path.abspath(exe) + os.environ["PATH"] = os.path.abspath(_dir) + ":" + os.environ["PATH"] return exe raise RuntimeError("Can't find server executable in " + path) @@ -515,7 +506,7 @@ class TarantoolServer(Server): def copy_config(self, rand=True, override = ['all']): override_all = (True if 'all' in override else False) - port = random.randrange(34000, 65535) + port = random.randrange(3300, 9999) for t in self.generate_ports: if not t in self.conf: self.conf[t] = find_port(port) @@ -539,8 +530,6 @@ class TarantoolServer(Server): if self.shebang: shutil.copy(self.shebang, self.init_lua) os.chmod(self.init_lua, 0777) - elif self.init_lua_source: - shutil.copy(self.init_lua_source, self.init_lua) if self.lua_libs: for i in self.lua_libs: source = os.path.join(self.testdir, i) diff --git a/test/lib/test_suite.py b/test/lib/test_suite.py index 96d330f74f79103381dd6462ced64c57e31ac928..5fddeedc4a554f6ecb8f51903b43ea32792c8363 100644 --- a/test/lib/test_suite.py +++ b/test/lib/test_suite.py @@ -53,7 +53,7 @@ class TestSuite: self.ini.update(dict(config.items("default"))) self.ini.update(self.args.__dict__) - for i in ["config", "init_lua"]: + for i in ["config", "shebang"]: self.ini[i] = os.path.join(suite_path, self.ini[i]) if i in self.ini else None for i in ["disabled", "valgrind_disabled", "release_disabled"]: self.ini[i] = dict.fromkeys(self.ini[i].split()) if i in self.ini else dict() diff --git a/test/lib/utils.py b/test/lib/utils.py index 4fcbd7b2fb5d011fc1116efd05496d5b2a7e0130..9287599044c13b87d072e59d1348eb8058c6d6f7 100644 --- a/test/lib/utils.py +++ b/test/lib/utils.py @@ -9,7 +9,7 @@ color_stdout = Colorer() def check_libs(): deps = [ ('msgpack', 'msgpack-python'), - ('tarantool', 'tarantool-python/src') + ('tarantool', 'tarantool-python') ] base_path = os.path.dirname(os.path.abspath(__file__)) diff --git a/test/module/tarantool.cfg b/test/module/tarantool.cfg index 7afb21ed0571ef7cc3bb89cf5617c1001284116b..66a06d4ec41d47846616726553db4413914b6ee3 100644 --- a/test/module/tarantool.cfg +++ b/test/module/tarantool.cfg @@ -22,11 +22,11 @@ logger="cat - >> tarantool.log" # # Read only and read-write port. -primary_port = 33013 +primary_port = 3301 # # The port for administrative commands. # -admin_port = 33015 +admin_port = 3313 # # Each write ahead log contains this many rows. # When the limit is reached, Tarantool closes diff --git a/test/replication/cfg/hot_standby.cfg b/test/replication/cfg/hot_standby.cfg index 586a1f48c5f14770e136ca4f6f1cf6c868d65e50..da870ca32b63be59beb5ce5bb4b9aae6ee999a39 100644 --- a/test/replication/cfg/hot_standby.cfg +++ b/test/replication/cfg/hot_standby.cfg @@ -9,5 +9,5 @@ local_hot_standby=true wal_dir="../" snap_dir="../" -primary_port = 33013 +primary_port = 3301 admin_port = 33025 diff --git a/test/replication/cfg/master.cfg b/test/replication/cfg/master.cfg index 78bc98118cce5fee26213facbc2ce20b2ffdba4c..68248d0be28252ae11a005db66ae34ce191d965b 100644 --- a/test/replication/cfg/master.cfg +++ b/test/replication/cfg/master.cfg @@ -5,5 +5,5 @@ logger="cat - >> tarantool.log" bind_ipaddr="INADDR_ANY" custom_proc_title="master" -primary_port = 33013 -admin_port = 33015 +primary_port = 3301 +admin_port = 3313 diff --git a/test/replication/cfg/master_to_replica.cfg b/test/replication/cfg/master_to_replica.cfg index 75591bc3a6af6d9fa94f63613711c1a4f2a64116..8df6e064e76ed7bf3221a8bd561cde22e3ed3840 100644 --- a/test/replication/cfg/master_to_replica.cfg +++ b/test/replication/cfg/master_to_replica.cfg @@ -5,7 +5,7 @@ logger="cat - >> tarantool.log" bind_ipaddr="INADDR_ANY" custom_proc_title="master" -primary_port = 33013 -admin_port = 33015 +primary_port = 3301 +admin_port = 3313 replication_source = "127.0.0.1:33113" diff --git a/test/replication/cfg/replica.cfg b/test/replication/cfg/replica.cfg index fb44921cbb6e2cb2e6bd87b1d4a72963ea17ec6d..dc670c1a25a655c8855a866042d302e3a4ffe670 100644 --- a/test/replication/cfg/replica.cfg +++ b/test/replication/cfg/replica.cfg @@ -8,4 +8,4 @@ custom_proc_title="replica" primary_port = 33113 admin_port = 33115 -replication_source = 127.0.0.1:33013 +replication_source = 127.0.0.1:3301 diff --git a/test/replication/consistent.result b/test/replication/consistent.result index d3befef6fa3ea9ceda094fe0f5681e1fa2e515f9..739b500885f50b6c3d92dbdb4a670385c2babbf7 100644 --- a/test/replication/consistent.result +++ b/test/replication/consistent.result @@ -1,6 +1,14 @@ --# create server replica with configuration='replication/cfg/replica.cfg', rpl_master=default --# start server replica --# set connection default +box.schema.user.grant('guest', 'read,write,execute', 'universe') +--- +... +-- Wait until the grant reaches the replica +--# set connection replica +while box.space['_priv']:len() < 1 do box.fiber.sleep(0.01) end +--- +... --# setopt delimiter ';' --# set connection default, replica do @@ -24,7 +32,7 @@ do box.fiber.sleep(0.001) end for i = _begin, _end do - table.insert(a, box.space[0]:select{i}) + table.insert(a, box.space[0]:get{i}) end return unpack(a) end @@ -494,3 +502,6 @@ box.space[0]:insert{0, 'replica is RO'} box.space[0]:drop() --- ... +box.schema.user.revoke('guest', 'read,write,execute', 'universe') +--- +... diff --git a/test/replication/consistent.test.lua b/test/replication/consistent.test.lua index e8cf28cb698ba3cdcd17c205dd1ab58a8ecbd7fc..7984339ec3d77370cf1a09a72e989e7cebbaea00 100644 --- a/test/replication/consistent.test.lua +++ b/test/replication/consistent.test.lua @@ -1,7 +1,10 @@ --# create server replica with configuration='replication/cfg/replica.cfg', rpl_master=default --# start server replica --# set connection default - +box.schema.user.grant('guest', 'read,write,execute', 'universe') +-- Wait until the grant reaches the replica +--# set connection replica +while box.space['_priv']:len() < 1 do box.fiber.sleep(0.01) end --# setopt delimiter ';' --# set connection default, replica do @@ -25,7 +28,7 @@ do box.fiber.sleep(0.001) end for i = _begin, _end do - table.insert(a, box.space[0]:select{i}) + table.insert(a, box.space[0]:get{i}) end return unpack(a) end @@ -168,3 +171,4 @@ box.space[0]:insert{0, 'replica is RO'} --# cleanup server replica --# set connection default box.space[0]:drop() +box.schema.user.revoke('guest', 'read,write,execute', 'universe') diff --git a/test/replication/hot_standby.result b/test/replication/hot_standby.result index e49c47c4187e030a2adda8687988627040e140a4..78eefa3a1fd5126c51831f50e406b4377a58329d 100644 --- a/test/replication/hot_standby.result +++ b/test/replication/hot_standby.result @@ -2,8 +2,15 @@ --# create server replica with configuration='replication/cfg/replica.cfg' with rpl_master=default --# start server hot_standby --# start server replica +--# set connection default +box.schema.user.grant('guest', 'read,write,execute', 'universe') +--- +... --# setopt delimiter ';' --# set connection default, hot_standby, replica +while box.space['_priv']:len() < 1 do box.fiber.sleep(0.01) end; +--- +... do begin_lsn = box.info.lsn @@ -26,7 +33,7 @@ do function _select(_begin, _end) local a = {} for i = _begin, _end do - table.insert(a, box.space['tweedledum']:select{i}) + table.insert(a, box.space['tweedledum']:get{i}) end return unpack(a) end diff --git a/test/replication/hot_standby.test.lua b/test/replication/hot_standby.test.lua index c60722fd264084af765b3201621d09cb7e1f2dfb..461fbc8152ec26c707ceca6b290339dd81e5e611 100644 --- a/test/replication/hot_standby.test.lua +++ b/test/replication/hot_standby.test.lua @@ -2,9 +2,12 @@ --# create server replica with configuration='replication/cfg/replica.cfg' with rpl_master=default --# start server hot_standby --# start server replica +--# set connection default +box.schema.user.grant('guest', 'read,write,execute', 'universe') --# setopt delimiter ';' --# set connection default, hot_standby, replica +while box.space['_priv']:len() < 1 do box.fiber.sleep(0.01) end; do begin_lsn = box.info.lsn @@ -27,7 +30,7 @@ do function _select(_begin, _end) local a = {} for i = _begin, _end do - table.insert(a, box.space['tweedledum']:select{i}) + table.insert(a, box.space['tweedledum']:get{i}) end return unpack(a) end diff --git a/test/replication/init_storage.result b/test/replication/init_storage.result index 7e15eb5b1ee8f6cae084dd7809cc7360437a59e6..91321a0d130e981dc5a8c2f6dd66d714176fa542 100644 --- a/test/replication/init_storage.result +++ b/test/replication/init_storage.result @@ -27,79 +27,79 @@ replica test 2 (must be ok) space = box.space.test --- ... -space:select{1} +space:get{1} --- - [1, 1] ... -space:select{2} +space:get{2} --- - [2, 4] ... -space:select{3} +space:get{3} --- - [3, 9] ... -space:select{4} +space:get{4} --- - [4, 16] ... -space:select{5} +space:get{5} --- - [5, 25] ... -space:select{6} +space:get{6} --- - [6, 36] ... -space:select{7} +space:get{7} --- - [7, 49] ... -space:select{8} +space:get{8} --- - [8, 64] ... -space:select{9} +space:get{9} --- - [9, 81] ... -space:select{10} +space:get{10} --- - [10, 1000] ... -space:select{11} +space:get{11} --- - [11, 1331] ... -space:select{12} +space:get{12} --- - [12, 1728] ... -space:select{13} +space:get{13} --- - [13, 2197] ... -space:select{14} +space:get{14} --- - [14, 2744] ... -space:select{15} +space:get{15} --- - [15, 3375] ... -space:select{16} +space:get{16} --- - [16, 4096] ... -space:select{17} +space:get{17} --- - [17, 4913] ... -space:select{18} +space:get{18} --- - [18, 5832] ... -space:select{19} +space:get{19} --- - [19, 6859] ... diff --git a/test/replication/init_storage.test.py b/test/replication/init_storage.test.py index 95d5a53bd425ee20c7b0dd6fdc4e193b82215063..3761a757777b0c2f9fc71f241884e085a1c830df 100644 --- a/test/replication/init_storage.test.py +++ b/test/replication/init_storage.test.py @@ -46,7 +46,7 @@ replica.deploy() replica.admin('space = box.space.test'); replica.wait_lsn(lsn) for i in range(1, 20): - replica.admin('space:select{%d}' % i) + replica.admin('space:get{%d}' % i) replica.stop() replica.cleanup(True) diff --git a/test/replication/swap.result b/test/replication/swap.result index 4b983caf47d198f2e568bd511a14e39990d3f961..9112d58f8467fa9613eb66eb34ed632cc47e81da 100644 --- a/test/replication/swap.result +++ b/test/replication/swap.result @@ -1,3 +1,9 @@ +box.schema.user.grant('guest', 'read,write,execute', 'universe') +--- +... +while box.space['_priv']:len() < 1 do box.fiber.sleep(0.01) end +--- +... s = box.schema.create_space('tweedledum', {id = 0}) --- ... diff --git a/test/replication/swap.test.py b/test/replication/swap.test.py index 7a33ed32bf41efd9fe2e0090c4d212ccd9ab4679..46c591219faed630397985392036fabb45a85c94 100644 --- a/test/replication/swap.test.py +++ b/test/replication/swap.test.py @@ -25,22 +25,8 @@ replica.cfgfile_source = "replication/cfg/replica.cfg" replica.vardir = os.path.join(server.vardir, 'replica') replica.deploy() -schema = { - 0 : { - 'default_type': tarantool.STR, - 'fields' : { - 0 : tarantool.NUM, - 1 : tarantool.STR - }, - 'indexes': { - 0 : [0] # HASH - } - } -} - -master.sql.set_schema(schema) -replica.sql.set_schema(schema) - +master.admin("box.schema.user.grant('guest', 'read,write,execute', 'universe')") +replica.admin("while box.space['_priv']:len() < 1 do box.fiber.sleep(0.01) end") master.admin("s = box.schema.create_space('tweedledum', {id = 0})") master.admin("s:create_index('primary', {type = 'hash'})") id = ID_BEGIN diff --git a/test/share/tarantool.cfg b/test/share/tarantool.cfg index bc707e9897fc47e1cf7cef17a0a215713d1dc5dc..ed55fbe61e5c68fdae275e129794507274d226f4 100644 --- a/test/share/tarantool.cfg +++ b/test/share/tarantool.cfg @@ -19,11 +19,11 @@ logger="cat - >> tarantool.log" # # Read only and read-write port. -primary_port = 33013 +primary_port = 3301 # # The port for administrative commands. -admin_port = 33015 +admin_port = 3313 # # Each write ahead log contains this many rows. diff --git a/test/share/tarantool_dmg.cfg b/test/share/tarantool_dmg.cfg index c1ebffc8fd11d0e8169beb5268a4458701f5009f..fa0809333ee794a055ce978432e5b86a79d7bdaa 100644 --- a/test/share/tarantool_dmg.cfg +++ b/test/share/tarantool_dmg.cfg @@ -15,27 +15,17 @@ pid_file = "/var/run/box.pid" # # Read only and read-write port. -primary_port = 33013 +primary_port = 3301 # # The port for administrative commands. -admin_port = 33015 +admin_port = 3313 # # Each write ahead log contains this many rows. # When the limit is reached, Tarantool closes # the WAL and starts a new one. rows_per_wal = 50000 - -# -# Define a simple space with 1 HASH-based -# primary key. -space[0].enabled = 1 -space[0].index[0].type = "HASH" -space[0].index[0].unique = 1 -space[0].index[0].key_field[0].fieldno = 0 -space[0].index[0].key_field[0].type = "NUM" - # # working directory (daemon will chdir(2) to it) work_dir = "var/lib/tarantool" diff --git a/test/share/tarantool_rpm.cfg b/test/share/tarantool_rpm.cfg index 0da787d4c40301fc55c5c256444958e1692d7b45..7aee2fb142c9ea3f43632aeaac6c70306d6473a1 100644 --- a/test/share/tarantool_rpm.cfg +++ b/test/share/tarantool_rpm.cfg @@ -16,11 +16,11 @@ pid_file = "box.pid" # # Read only and read-write port. -primary_port = 33013 +primary_port = 3301 # # The port for administrative commands. -admin_port = 33015 +admin_port = 3313 # # Each write ahead log contains this many rows. diff --git a/test/share/tarantool_tgz.cfg b/test/share/tarantool_tgz.cfg index 03e25c5faa8e03bff6c8e9624bf1c75acab11112..8162a64deba1d1748aa46bd72452855ebf8a4e8b 100644 --- a/test/share/tarantool_tgz.cfg +++ b/test/share/tarantool_tgz.cfg @@ -19,11 +19,11 @@ pid_file = "box.pid" # # Read only and read-write port. -primary_port = 33013 +primary_port = 3301 # # The port for administrative commands. -admin_port = 33015 +admin_port = 3313 # # Each write ahead log contains this many rows. diff --git a/test/test-run.py b/test/test-run.py index 345891c7731762a8eca509bec151d35251cfc500..47a9743ee30c57d84cce200f06f44800d5b53dcf 100755 --- a/test/test-run.py +++ b/test/test-run.py @@ -137,9 +137,6 @@ def setenv(args): os.path.join(os.getcwd(), '../src/plugin/pg')) ) ) - path = os.path.join(os.path.abspath(args.builddir), "src/box") - path = path + ":" + os.getenv("PATH") - os.environ["PATH"] = path ####################################################################### # Program body diff --git a/test/unit/CMakeLists.txt b/test/unit/CMakeLists.txt index 32c2d7be733d427c3261370927bd8bd71c9f1204..4211e239ab4ce4f0f41dde33940db02d328762a1 100644 --- a/test/unit/CMakeLists.txt +++ b/test/unit/CMakeLists.txt @@ -47,3 +47,9 @@ set_source_files_properties( "-I${MSGPUCK_DIR} -I${MSGPUCK_DIR}/test") target_link_libraries(msgpack.test msgpuck) + +add_executable(scramble.test scramble.c + ${CMAKE_SOURCE_DIR}/src/scramble.c + ${CMAKE_SOURCE_DIR}/third_party/sha1.c + ${CMAKE_SOURCE_DIR}/third_party/base64.c + ${CMAKE_SOURCE_DIR}/src/random.c) diff --git a/test/unit/scramble.c b/test/unit/scramble.c new file mode 100644 index 0000000000000000000000000000000000000000..6d62e57cbabb779d0f8b87d04915b8d6f8b1345a --- /dev/null +++ b/test/unit/scramble.c @@ -0,0 +1,65 @@ +#include "scramble.h" +#include "random.h" +#include "third_party/sha1.h" +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "unit.h" + +void +test_scramble() +{ + int salt[SCRAMBLE_SIZE/sizeof(int)]; + for (int i = 0; i < sizeof(salt)/sizeof(int); i++) + salt[i] = rand(); + + char *password = "lechododilikraskaloh"; + unsigned char hash2[SCRAMBLE_SIZE]; + + SHA1_CTX ctx; + + SHA1Init(&ctx); + SHA1Update(&ctx, (unsigned char *) password, strlen(password)); + SHA1Final(hash2, &ctx); + + SHA1Init(&ctx); + SHA1Update(&ctx, hash2, SCRAMBLE_SIZE); + SHA1Final(hash2, &ctx); + + char scramble[SCRAMBLE_SIZE]; + + scramble_prepare(scramble, salt, password, strlen(password)); + + printf("%d\n", scramble_check(scramble, salt, hash2)); + + password = "wrongpass"; + scramble_prepare(scramble, salt, password, strlen(password)); + + printf("%d\n", scramble_check(scramble, salt, hash2) != 0); + + scramble_prepare(scramble, salt, password, 0); + + printf("%d\n", scramble_check(scramble, salt, hash2) != 0); +} + +void +test_password_prepare() +{ + char buf[SCRAMBLE_BASE64_SIZE * 2]; + int password[5]; + for (int i = 0; i < sizeof(password)/sizeof(int); i++) + password[i] = rand(); + password_prepare((char *) password, sizeof(password), + buf, sizeof(buf)); + fail_unless(strlen(buf) == SCRAMBLE_BASE64_SIZE); +} + +int main() +{ + random_init(); + + test_scramble(); + test_password_prepare(); + + return 0; +} diff --git a/test/unit/scramble.result b/test/unit/scramble.result new file mode 100644 index 0000000000000000000000000000000000000000..986394f7c0fa05e52a94a3d93dee7085ed84cca4 --- /dev/null +++ b/test/unit/scramble.result @@ -0,0 +1,3 @@ +0 +1 +1 diff --git a/test/wal/alter.result b/test/wal/alter.result index 6422a461212e534be93d987b5e00ff48397562c6..d417108da16d0b331d1a027e96a6ddc322039de8 100644 --- a/test/wal/alter.result +++ b/test/wal/alter.result @@ -17,7 +17,7 @@ end; ... #spaces; --- -- 65526 +- 65523 ... -- cleanup for k, v in pairs(spaces) do diff --git a/test/wal/lua.result b/test/wal/lua.result index 46aa6065ab56a23c43d1fe66dd7f24b57d10ae57..ee9912e4e91c3790b71d96ffe3eb673e6b02d5b0 100644 --- a/test/wal/lua.result +++ b/test/wal/lua.result @@ -17,7 +17,7 @@ for i = 1, 1000 do space:insert{tostring(j), os.time(), 1} end count = 0 - for v in space.index[1]:iterator() do + for state, v in space.index[1]:pairs() do count = count + 1 end if count ~= 30 then @@ -37,9 +37,8 @@ space:truncate() for i = 1, 100000, 1 do space:insert{tostring(i), i} end --- ... -local t1 = {space.index['secondary']:select{}} +local t1 = space.index['secondary']:select() --- -- error: stack overflow ... space:drop() --- diff --git a/test/wal/lua.test.lua b/test/wal/lua.test.lua index 6c29dba3b3bf96c88660b2f95a71178b71912d59..91cfbd9b0d654e6f83e6e34ae9fc1fe6f34d34cf 100644 --- a/test/wal/lua.test.lua +++ b/test/wal/lua.test.lua @@ -12,7 +12,7 @@ for i = 1, 1000 do space:insert{tostring(j), os.time(), 1} end count = 0 - for v in space.index[1]:iterator() do + for state, v in space.index[1]:pairs() do count = count + 1 end if count ~= 30 then @@ -27,7 +27,7 @@ space:truncate() -- 5.4 -- for i = 1, 100000, 1 do space:insert{tostring(i), i} end -local t1 = {space.index['secondary']:select{}} +local t1 = space.index['secondary']:select() space:drop() -- diff --git a/test/wal/oom.result b/test/wal/oom.result index 54f21b9a0c843199c3b6d258aaee319e540cd745..0a1c9e08fe99e5a9bd2c786919b463689e699bbf 100644 --- a/test/wal/oom.result +++ b/test/wal/oom.result @@ -50,23 +50,23 @@ space:len() --- - 219 ... -space.index['primary']:select{0} +space.index['primary']:get{0} --- - [0, 'test'] ... -space.index['primary']:select{5} +space.index['primary']:get{5} --- - [5, 'testtesttesttesttesttest'] ... -space.index['primary']:select{9} +space.index['primary']:get{9} --- - [9, 'testtesttesttesttesttesttesttesttesttest'] ... -space.index['primary']:select{11} +space.index['primary']:get{11} --- - [11, 'testtesttesttesttesttesttesttesttesttesttesttest'] ... -space.index['primary']:select{15} +space.index['primary']:get{15} --- - [15, 'testtesttesttesttesttesttesttesttesttesttesttesttesttesttesttest'] ... @@ -78,7 +78,7 @@ t = {} --- ... --# setopt delimiter ';' -for v in space:iterator() do +for state, v in space:pairs() do table.insert(t, v) i = i + 1 if i == 50 then @@ -148,7 +148,7 @@ space:insert{0, 'test'} --- - [0, 'test'] ... -space.index['primary']:select{0} +space.index['primary']:get{0} --- - [0, 'test'] ... diff --git a/test/wal/oom.test.lua b/test/wal/oom.test.lua index 6b30d09d21f5063759a59d1712cfdec870de3f5e..4cbac50b324a1e5bdc50f0cbb8ce3f0c3837d68f 100644 --- a/test/wal/oom.test.lua +++ b/test/wal/oom.test.lua @@ -22,16 +22,16 @@ while true do end; --# setopt delimiter '' space:len() -space.index['primary']:select{0} -space.index['primary']:select{5} -space.index['primary']:select{9} -space.index['primary']:select{11} -space.index['primary']:select{15} +space.index['primary']:get{0} +space.index['primary']:get{5} +space.index['primary']:get{9} +space.index['primary']:get{11} +space.index['primary']:get{15} -- check that iterators work i = 0 t = {} --# setopt delimiter ';' -for v in space:iterator() do +for state, v in space:pairs() do table.insert(t, v) i = i + 1 if i == 50 then @@ -42,5 +42,5 @@ end; t space:truncate() space:insert{0, 'test'} -space.index['primary']:select{0} +space.index['primary']:get{0} space:drop() diff --git a/test/wal/tarantool.cfg b/test/wal/tarantool.cfg index 8654bd80e1eae4972adcd2ace091dddfc5d4992e..3c731f6f5468511e6bdbc009e6f454540d06711d 100644 --- a/test/wal/tarantool.cfg +++ b/test/wal/tarantool.cfg @@ -22,8 +22,8 @@ logger="cat - >> tarantool.log" # # Read only and read-write port. -primary_port = 33013 +primary_port = 3301 # The port for administrative commands. -admin_port = 33015 +admin_port = 3313 wal_mode = none diff --git a/test/wal/wal_mode.result b/test/wal/wal_mode.result index a75bb8c7e103c30ea7454d7cae147cc4d185029c..5e6f49f044e58952f226c02d857723826c26504c 100644 --- a/test/wal/wal_mode.result +++ b/test/wal/wal_mode.result @@ -20,19 +20,19 @@ space:insert{3} --- - [3] ... -space.index['primary']:select(1) +space.index['primary']:get(1) --- - [1] ... -space.index['primary']:select(2) +space.index['primary']:get(2) --- - [2] ... -space.index['primary']:select(3) +space.index['primary']:get(3) --- - [3] ... -space.index['primary']:select(4) +space.index['primary']:get(4) --- ... box.snapshot() diff --git a/test/wal/wal_mode.test.lua b/test/wal/wal_mode.test.lua index f1b6db2297e8a7706552848c1ee536644ebf684c..4fad8a33e751d19b3763591f129db3c7c4c98992 100644 --- a/test/wal/wal_mode.test.lua +++ b/test/wal/wal_mode.test.lua @@ -4,10 +4,10 @@ space:create_index('primary', { type = 'hash' }) space:insert{1} space:insert{2} space:insert{3} -space.index['primary']:select(1) -space.index['primary']:select(2) -space.index['primary']:select(3) -space.index['primary']:select(4) +space.index['primary']:get(1) +space.index['primary']:get(2) +space.index['primary']:get(3) +space.index['primary']:get(4) box.snapshot() box.snapshot() space:truncate() diff --git a/third_party/base64.c b/third_party/base64.c index d2fdc253ab520216e574d7487a1184d8fcdc8729..e2fb9785c43ce65a76c2077455a1e18a0b4126a1 100644 --- a/third_party/base64.c +++ b/third_party/base64.c @@ -153,9 +153,12 @@ base64_encode_blockend(char *out_base64, int out_len, } if (out_pos >= out_end) return out_pos - out_base64; +#if 0 + /* Sometimes the output is useful without a newline. */ *out_pos++ = '\n'; if (out_pos >= out_end) return out_pos - out_base64; +#endif *out_pos = '\0'; return out_pos - out_base64; } @@ -241,7 +244,7 @@ base64_decode_block(const char *in_base64, int in_len, *out_pos = (fragment & 0x03f) << 2; case step_b: do { - if (in_pos == in_end || out_pos + 1 >= out_end) + if (in_pos == in_end || out_pos >= out_end) { state->step = step_b; state->result = *out_pos; @@ -250,10 +253,11 @@ base64_decode_block(const char *in_base64, int in_len, fragment = base64_decode_value(*in_pos++); } while (fragment < 0); *out_pos++ |= (fragment & 0x030) >> 4; - *out_pos = (fragment & 0x00f) << 4; + if (out_pos < out_end) + *out_pos = (fragment & 0x00f) << 4; case step_c: do { - if (in_pos == in_end || out_pos + 1 >= out_end) + if (in_pos == in_end || out_pos >= out_end) { state->step = step_c; state->result = *out_pos; @@ -262,7 +266,8 @@ base64_decode_block(const char *in_base64, int in_len, fragment = base64_decode_value(*in_pos++); } while (fragment < 0); *out_pos++ |= (fragment & 0x03c) >> 2; - *out_pos = (fragment & 0x003) << 6; + if (out_pos < out_end) + *out_pos = (fragment & 0x003) << 6; case step_d: do { if (in_pos == in_end || out_pos >= out_end) diff --git a/third_party/luafun b/third_party/luafun new file mode 160000 index 0000000000000000000000000000000000000000..3d44c0841dbc93b645546bb13868550089bfa076 --- /dev/null +++ b/third_party/luafun @@ -0,0 +1 @@ +Subproject commit 3d44c0841dbc93b645546bb13868550089bfa076 diff --git a/third_party/luajit b/third_party/luajit index 4fba08a9aca4ce99a6a51f5faca2e1e091ad1422..880ca300e8fb7b432b9d25ed377db2102e4cb63d 160000 --- a/third_party/luajit +++ b/third_party/luajit @@ -1 +1 @@ -Subproject commit 4fba08a9aca4ce99a6a51f5faca2e1e091ad1422 +Subproject commit 880ca300e8fb7b432b9d25ed377db2102e4cb63d diff --git a/client/tarantar/sha1.c b/third_party/sha1.c similarity index 100% rename from client/tarantar/sha1.c rename to third_party/sha1.c diff --git a/client/tarantar/sha1.h b/third_party/sha1.h similarity index 100% rename from client/tarantar/sha1.h rename to third_party/sha1.h