From 0f05f6980d58b3f6e611a311576eab1be7e81980 Mon Sep 17 00:00:00 2001 From: Roman Tsisyk <roman@tsisyk.com> Date: Mon, 14 Sep 2015 13:44:29 +0300 Subject: [PATCH] Fix #1007: restore Lua/C version of box.tuple.new() Partially reverts squashed 316d4e3a6ba4ef7d566b42b592efb00594828cac --- src/box/lua/tuple.cc | 40 ++++++++++++++++++++++++++++++++++++++++ src/box/lua/tuple.lua | 33 ++------------------------------- test/big/lua.result | 2 +- test/box/tuple.result | 20 ++++++++++---------- 4 files changed, 53 insertions(+), 42 deletions(-) diff --git a/src/box/lua/tuple.cc b/src/box/lua/tuple.cc index f67e23d59b..00d8856bc9 100644 --- a/src/box/lua/tuple.cc +++ b/src/box/lua/tuple.cc @@ -90,6 +90,39 @@ lua_istuple(struct lua_State *L, int narg) return t; } +static int +lbox_tuple_new(lua_State *L) +{ + int argc = lua_gettop(L); + if (unlikely(argc < 1)) { + lua_newtable(L); /* create an empty tuple */ + ++argc; + } + + struct region *gc = &fiber()->gc; + RegionGuard guard(gc); + struct mpstream stream; + mpstream_init(&stream, gc, region_reserve_cb, region_alloc_cb); + + if (argc == 1 && (lua_istable(L, 1) || lua_istuple(L, 1))) { + /* New format: box.tuple.new({1, 2, 3}) */ + luamp_encode_tuple(L, luaL_msgpack_default, &stream, 1); + } else { + /* Backward-compatible format: box.tuple.new(1, 2, 3). */ + luamp_encode_array(luaL_msgpack_default, &stream, argc); + for (int k = 1; k <= argc; ++k) { + luamp_encode(L, luaL_msgpack_default, &stream, k); + } + } + mpstream_flush(&stream); + + size_t tuple_len = region_used(gc) - guard.used; + const char *data = (char *) region_join(gc, tuple_len); + struct tuple *tuple = tuple_new(tuple_format_ber, data, data + tuple_len); + lbox_pushtuple(L, tuple); + return 1; +} + static int lbox_tuple_gc(struct lua_State *L) { @@ -326,6 +359,11 @@ static const struct luaL_reg lbox_tuple_meta[] = { {NULL, NULL} }; +static const struct luaL_reg lbox_tuplelib[] = { + {"new", lbox_tuple_new}, + {NULL, NULL} +}; + static const struct luaL_reg lbox_tuple_iterator_meta[] = { {NULL, NULL} }; @@ -342,6 +380,8 @@ box_lua_tuple_init(struct lua_State *L) lua_setglobal(L, "cfuncs"); luaL_register_type(L, tuple_iteratorlib_name, lbox_tuple_iterator_meta); + luaL_register_module(L, tuplelib_name, lbox_tuplelib); + lua_pop(L, 1); luamp_set_encode_extension(luamp_encode_extension_box); diff --git a/src/box/lua/tuple.lua b/src/box/lua/tuple.lua index a394abad97..f7dba0df87 100644 --- a/src/box/lua/tuple.lua +++ b/src/box/lua/tuple.lua @@ -85,32 +85,6 @@ local tuple_bless = function(tuple) return ffi.gc(ffi.cast(const_tuple_ref_t, tuple), tuple_gc) end -local format_lua = nil -- cached box_tuple_format -local function tuple_new(...) - if format_lua == nil then - format_lua = builtin.box_tuple_format_default() - end - - local obj = ... - if select('#', ...) > 1 or type(obj) ~= 'table' then - -- Backward-compatible format: box.tuple.new(1, 2, 3). - obj = {} - for i=1,select('#', ...) do - local val = select(i, ...) - if val == nil then - val = msgpackffi.NULL - end - obj[i] = val - end - end - local data, data_end = msgpackffi.encode_tuple(obj) - local tuple = builtin.box_tuple_new(format_lua, data, data_end) - if tuple == nil then - return box.error() - end - return tuple_bless(tuple) -end - local tuple_iterator_t = ffi.typeof('box_tuple_iterator_t') local tuple_iterator_ref_t = ffi.typeof('box_tuple_iterator_t &') @@ -322,8 +296,5 @@ ffi.metatype(tuple_iterator_t, { -- Remove the global variable cfuncs = nil -box.tuple = { - new = tuple_new; - -- internal api for box.select and iterators - bless = tuple_bless; -} +-- internal api for box.select and iterators +box.tuple.bless = tuple_bless diff --git a/test/big/lua.result b/test/big/lua.result index 4274109f5f..bc373b70c2 100644 --- a/test/big/lua.result +++ b/test/big/lua.result @@ -734,7 +734,7 @@ t:find(2, '2') ... t:find(89, '2') --- -- error: '[string "-- tuple.lua (internal file)..."]:151: error: invalid key to ''next''' +- error: '[string "-- tuple.lua (internal file)..."]:125: error: invalid key to ''next''' ... t:findall(4, '3') --- diff --git a/test/box/tuple.result b/test/box/tuple.result index b7eb8ad455..15975979bd 100644 --- a/test/box/tuple.result +++ b/test/box/tuple.result @@ -305,12 +305,12 @@ t:unpack(2, 1) ... t:totable(0) --- -- error: '[string "-- tuple.lua (internal file)..."]:182: tuple.totable: invalid second +- error: '[string "-- tuple.lua (internal file)..."]:156: tuple.totable: invalid second argument' ... t:totable(1, 0) --- -- error: '[string "-- tuple.lua (internal file)..."]:191: tuple.totable: invalid third +- error: '[string "-- tuple.lua (internal file)..."]:165: tuple.totable: invalid third argument' ... -- @@ -443,7 +443,7 @@ t:next(-1) ... t:next("fdsaf") --- -- error: '[string "-- tuple.lua (internal file)..."]:163: bad argument #2 to ''box_tuple_field'' +- error: '[string "-- tuple.lua (internal file)..."]:137: bad argument #2 to ''box_tuple_field'' (cannot convert ''string'' to ''unsigned int'')' ... box.tuple.new({'x', 'y', 'z'}):next() @@ -612,7 +612,7 @@ r = {} ... for _state, val in t:pairs(10) do table.insert(r, val) end --- -- error: '[string "-- tuple.lua (internal file)..."]:151: error: invalid key to ''next''' +- error: '[string "-- tuple.lua (internal file)..."]:125: error: invalid key to ''next''' ... r --- @@ -698,19 +698,19 @@ t:findall(1, 'xxxxx') ... t:find(100, 'a') --- -- error: '[string "-- tuple.lua (internal file)..."]:151: error: invalid key to ''next''' +- error: '[string "-- tuple.lua (internal file)..."]:125: error: invalid key to ''next''' ... t:findall(100, 'a') --- -- error: '[string "-- tuple.lua (internal file)..."]:151: error: invalid key to ''next''' +- error: '[string "-- tuple.lua (internal file)..."]:125: error: invalid key to ''next''' ... t:find(100, 'xxxxx') --- -- error: '[string "-- tuple.lua (internal file)..."]:151: error: invalid key to ''next''' +- error: '[string "-- tuple.lua (internal file)..."]:125: error: invalid key to ''next''' ... t:findall(100, 'xxxxx') --- -- error: '[string "-- tuple.lua (internal file)..."]:151: error: invalid key to ''next''' +- error: '[string "-- tuple.lua (internal file)..."]:125: error: invalid key to ''next''' ... --- -- Lua type coercion @@ -804,12 +804,12 @@ t = box.tuple.new({'a', 'b', 'c', 'd', 'e'}) ... t:update() --- -- error: '[string "-- tuple.lua (internal file)..."]:231: Usage: tuple:update({ { +- error: '[string "-- tuple.lua (internal file)..."]:205: Usage: tuple:update({ { op, field, arg}+ })' ... t:update(10) --- -- error: '[string "-- tuple.lua (internal file)..."]:231: Usage: tuple:update({ { +- error: '[string "-- tuple.lua (internal file)..."]:205: Usage: tuple:update({ { op, field, arg}+ })' ... t:update({}) -- GitLab