diff --git a/src/box/box_lua_space.cc b/src/box/box_lua_space.cc index 1e72c86f72d0b6f9bc1eeb0290ed5a9dbf6f315f..12e2e58efc765c17ad7800cda843b43bc1c7501d 100644 --- a/src/box/box_lua_space.cc +++ b/src/box/box_lua_space.cc @@ -44,33 +44,46 @@ extern "C" { * @return A new table representing a space on top of the Lua * stack. */ -static int -lbox_pushspace(struct lua_State *L, struct space *space) +static void +lbox_fillspace(struct lua_State *L, struct space *space, int i) { - lua_newtable(L); - /* space.arity */ lua_pushstring(L, "arity"); lua_pushnumber(L, space->def.arity); - lua_settable(L, -3); + lua_settable(L, i); /* space.n */ lua_pushstring(L, "n"); lua_pushnumber(L, space_id(space)); - lua_settable(L, -3); + lua_settable(L, i); /* space.name */ lua_pushstring(L, "name"); lua_pushstring(L, space_name(space)); - lua_settable(L, -3); + lua_settable(L, i); lua_pushstring(L, "enabled"); lua_pushboolean(L, space->engine.state != READY_NO_KEYS); - lua_settable(L, -3); + lua_settable(L, i); - /* space.index */ - lua_pushstring(L, "index"); - lua_newtable(L); + lua_getfield(L, i, "index"); + if (lua_isnil(L, -1)) { + lua_pop(L, 1); + /* space.index */ + lua_pushstring(L, "index"); + lua_newtable(L); + lua_settable(L, i); /* push space.index */ + lua_getfield(L, i, "index"); + } else { + /* Empty the table. */ + lua_pushnil(L); /* first key */ + while (lua_next(L, -2) != 0) { + lua_pop(L, 1); /* remove the value. */ + lua_pushnil(L); /* set the key to nil. */ + lua_settable(L, -3); + lua_pushnil(L); /* start over. */ + } + } /* * Fill space.index table with * all defined indexes. @@ -88,7 +101,6 @@ lbox_pushspace(struct lua_State *L, struct space *space) lua_settable(L, -3); lua_pushstring(L, "type"); - lua_pushstring(L, index_type_strs[key_def->type]); lua_settable(L, -3); @@ -111,12 +123,12 @@ lbox_pushspace(struct lua_State *L, struct space *space) lua_settable(L, -3); } - lua_settable(L, -3); /* space[i].key_field */ + lua_settable(L, -3); /* index[i].key_field */ - lua_settable(L, -3); /* space[i] */ + lua_settable(L, -3); /* space.index[i] */ } - lua_settable(L, -3); /* push space.index */ + lua_pop(L, 1); /* pop the index field */ lua_getfield(L, LUA_GLOBALSINDEX, "box"); lua_pushstring(L, "schema"); @@ -126,11 +138,9 @@ lbox_pushspace(struct lua_State *L, struct space *space) lua_pushstring(L, "bless"); lua_gettable(L, -2); - lua_pushvalue(L, -5); /* box, schema, space, bless, space */ + lua_pushvalue(L, i); /* space */ lua_call(L, 1, 0); lua_pop(L, 3); /* cleanup stack - box, schema, space */ - - return 1; } /** Export a space to Lua */ @@ -147,10 +157,20 @@ box_lua_space_new(struct lua_State *L, struct space *space) lua_getfield(L, -1, "space"); } - lbox_pushspace(L, space); - lua_rawseti(L, -2, space_id(space)); + lua_rawgeti(L, -1, space_id(space)); + if (lua_isnil(L, -1)) { + /* + * Important: if the space already exists, + * modify it, rather than create a new one. + */ + lua_pop(L, 1); + lua_newtable(L); + lua_rawseti(L, -2, space_id(space)); + lua_rawgeti(L, -1, space_id(space)); + } + lbox_fillspace(L, space, lua_gettop(L)); lua_pushstring(L, space_name(space)); - lua_rawgeti(L, -2, space_id(space)); + lua_insert(L, -2); lua_rawset(L, -3); lua_pop(L, 2); /* box, space */ diff --git a/src/box/lua/schema.lua b/src/box/lua/schema.lua index c4859c5130fe99702715b3ce9f24224887758e81..774e288a5b46f03b4f50449ed47cb47b14fc7a2b 100644 --- a/src/box/lua/schema.lua +++ b/src/box/lua/schema.lua @@ -58,13 +58,14 @@ box.schema.index.create = function(space_id, name, index_type, options) end local part_count = #options.parts/2 local parts = options.parts - local iid + local iid = 0 -- max local tuple = _index.index[0]:select_reverse_range(1, space_id) if tuple then - iid = box.unpack('i', tuple[1]) + 1 - else - iid = 0 + local id = box.unpack('i', tuple[0]) + if id == space_id then + iid = box.unpack('i', tuple[1]) + 1 + end end if options.id then iid = options.id diff --git a/test/box/errinj.result b/test/box/errinj.result index 344e976039e663982a7e50bd15021edcdbc24d54..f07602205d87e3873ea381d12d3f93a596b7c54a 100644 --- a/test/box/errinj.result +++ b/test/box/errinj.result @@ -1,10 +1,8 @@ -box.insert(box.schema.SPACE_ID, 0, 0, 'tweedledum') +space = box.schema.create_space('tweedledum') --- -- [0, 0, 'tweedledum'] ... -box.insert(box.schema.INDEX_ID, 0, 0, 'primary', 'hash', 1, 1, 0, 'num') +space:create_index('primary', 'hash', { parts = { 0, 'num' }}) --- -- [0, 0, 'primary', 1752392040, 1, 1, 0, 'num'] ... box.errinj.info() --- @@ -25,14 +23,14 @@ box.errinj.set("some-injection") -- check error --- - 'error: can''t find error injection ''some-injection''' ... -box.space[0]:select(0,222444) +space:select(0,222444) --- ... box.errinj.set("ERRINJ_TESTING", true) --- - ok ... -box.space[0]:select(0,222444) +space:select(0,222444) --- - error: Error injection 'ERRINJ_TESTING' ... @@ -45,18 +43,18 @@ box.errinj.set("ERRINJ_WAL_IO", true) --- - ok ... -box.space[0]:insert(1) +space:insert(1) --- - error: Failed to write to disk ... -box.space[0]:select(0,1) +space:select(0,1) --- ... box.errinj.set("ERRINJ_WAL_IO", false) --- - ok ... -box.space[0]:insert(1) +space:insert(1) --- - [1] ... @@ -64,22 +62,22 @@ box.errinj.set("ERRINJ_WAL_IO", true) --- - ok ... -box.space[0]:update(1, '=p', 0, 2) +space:update(1, '=p', 0, 2) --- - error: Failed to write to disk ... -box.space[0]:select(0,1) +space:select(0,1) --- - [1] ... -box.space[0]:select(0,2) +space:select(0,2) --- ... box.errinj.set("ERRINJ_WAL_IO", false) --- - ok ... -box.space[0]:truncate() +space:truncate() --- ... -- Check a failed log rotation @@ -87,18 +85,18 @@ box.errinj.set("ERRINJ_WAL_ROTATE", true) --- - ok ... -box.space[0]:insert(1) +space:insert(1) --- - error: Failed to write to disk ... -box.space[0]:select(0,1) +space:select(0,1) --- ... box.errinj.set("ERRINJ_WAL_ROTATE", false) --- - ok ... -box.space[0]:insert(1) +space:insert(1) --- - [1] ... @@ -106,29 +104,29 @@ box.errinj.set("ERRINJ_WAL_ROTATE", true) --- - ok ... -box.space[0]:update(1, '=p', 0, 2) +space:update(1, '=p', 0, 2) --- - error: Failed to write to disk ... -box.space[0]:select(0,1) +space:select(0,1) --- - [1] ... -box.space[0]:select(0,2) +space:select(0,2) --- ... box.errinj.set("ERRINJ_WAL_ROTATE", false) --- - ok ... -box.space[0]:update(1, '=p', 0, 2) +space:update(1, '=p', 0, 2) --- - [2] ... -box.space[0]:select(0,1) +space:select(0,1) --- ... -box.space[0]:select(0,2) +space:select(0,2) --- - [2] ... @@ -136,7 +134,7 @@ box.errinj.set("ERRINJ_WAL_ROTATE", true) --- - ok ... -box.space[0]:truncate() +space:truncate() --- - error: Failed to write to disk ... @@ -144,9 +142,9 @@ box.errinj.set("ERRINJ_WAL_ROTATE", false) --- - ok ... -box.space[0]:truncate() +space:truncate() --- ... -box.space[0]:drop() +space:drop() --- ... diff --git a/test/box/errinj.test.lua b/test/box/errinj.test.lua index 838c188343ded680c6015170687233d2fb16e5ac..ba5a1d4f99fdcd7df54a660af37d5e707c011530 100644 --- a/test/box/errinj.test.lua +++ b/test/box/errinj.test.lua @@ -1,44 +1,44 @@ -box.insert(box.schema.SPACE_ID, 0, 0, 'tweedledum') -box.insert(box.schema.INDEX_ID, 0, 0, 'primary', 'hash', 1, 1, 0, 'num') +space = box.schema.create_space('tweedledum') +space:create_index('primary', 'hash', { parts = { 0, 'num' }}) box.errinj.info() box.errinj.set("some-injection", true) box.errinj.set("some-injection") -- check error -box.space[0]:select(0,222444) +space:select(0,222444) box.errinj.set("ERRINJ_TESTING", true) -box.space[0]:select(0,222444) +space:select(0,222444) box.errinj.set("ERRINJ_TESTING", false) -- Check how well we handle a failed log write box.errinj.set("ERRINJ_WAL_IO", true) -box.space[0]:insert(1) -box.space[0]:select(0,1) +space:insert(1) +space:select(0,1) box.errinj.set("ERRINJ_WAL_IO", false) -box.space[0]:insert(1) +space:insert(1) box.errinj.set("ERRINJ_WAL_IO", true) -box.space[0]:update(1, '=p', 0, 2) -box.space[0]:select(0,1) -box.space[0]:select(0,2) +space:update(1, '=p', 0, 2) +space:select(0,1) +space:select(0,2) box.errinj.set("ERRINJ_WAL_IO", false) -box.space[0]:truncate() +space:truncate() -- Check a failed log rotation box.errinj.set("ERRINJ_WAL_ROTATE", true) -box.space[0]:insert(1) -box.space[0]:select(0,1) +space:insert(1) +space:select(0,1) box.errinj.set("ERRINJ_WAL_ROTATE", false) -box.space[0]:insert(1) +space:insert(1) box.errinj.set("ERRINJ_WAL_ROTATE", true) -box.space[0]:update(1, '=p', 0, 2) -box.space[0]:select(0,1) -box.space[0]:select(0,2) +space:update(1, '=p', 0, 2) +space:select(0,1) +space:select(0,2) box.errinj.set("ERRINJ_WAL_ROTATE", false) -box.space[0]:update(1, '=p', 0, 2) -box.space[0]:select(0,1) -box.space[0]:select(0,2) +space:update(1, '=p', 0, 2) +space:select(0,1) +space:select(0,2) box.errinj.set("ERRINJ_WAL_ROTATE", true) -box.space[0]:truncate() +space:truncate() box.errinj.set("ERRINJ_WAL_ROTATE", false) -box.space[0]:truncate() +space:truncate() -box.space[0]:drop() +space:drop() diff --git a/test/box/test_init.lua b/test/box/test_init.lua index a0b4045886ce8cf3d839d3f829699c4ad1e4cd9e..a0cd11435c1eb7912d706305db42e881a65f80c2 100644 --- a/test/box/test_init.lua +++ b/test/box/test_init.lua @@ -22,9 +22,8 @@ local function do_insert() box.insert(0, 1, 2, 4, 8) end -box.insert(box.schema.SPACE_ID, 0, 0, 'tweedledum') -box.insert(box.schema.INDEX_ID, 0, 0, 'primary', 'hash', 1, 1, 0, 'num') - +space = box.schema.create_space('tweedledum', { id = 0 }) +space:create_index('primary', 'hash', { parts = { 0, 'num' }}) fiber = box.fiber.create(do_insert) box.fiber.resume(fiber) @@ -33,4 +32,4 @@ box.fiber.resume(fiber) -- Test insert from start-up script -- -box.insert(0, 2, 4, 8, 16) +space:insert(2, 4, 8, 16)