[PATCH v2 1/2] schema: move space_mt and index_mt definition out of space bless
Vladislav Shpilevoy
v.shpilevoy at tarantool.org
Thu Mar 29 17:31:44 MSK 2018
From: aleclarson <alec.stanford.larson at gmail.com>
Space_mt and index_mt are created individually for each space
inside a giant space.bless function. It makes impossible to
implement #3204: exposing space and index metatables to a user,
because for this they must be global and shared between all
spaces and indexes.
Lets move their definition out of space.bless function, and do
their duplicate inside.
Needed #3204
---
src/box/lua/schema.lua | 608 +++++++++++++++++++---------------------
test/box-tap/schema_mt.test.lua | 79 ++++++
2 files changed, 373 insertions(+), 314 deletions(-)
create mode 100755 test/box-tap/schema_mt.test.lua
diff --git a/src/box/lua/schema.lua b/src/box/lua/schema.lua
index 5a0f71559..ff89c8e58 100644
--- a/src/box/lua/schema.lua
+++ b/src/box/lua/schema.lua
@@ -1074,221 +1074,321 @@ end
internal.check_iterator_type = check_iterator_type -- export for net.box
-function box.schema.space.bless(space)
- local index_mt = {}
- -- __len and __index
- index_mt.len = function(index)
- check_index_arg(index, 'len')
- local ret = builtin.box_index_len(index.space_id, index.id)
- if ret == -1 then
- box.error()
- end
- return tonumber(ret)
- end
- -- index.bsize
- index_mt.bsize = function(index)
- check_index_arg(index, 'bsize')
- local ret = builtin.box_index_bsize(index.space_id, index.id)
- if ret == -1 then
- box.error()
- end
- return tonumber(ret)
- end
- index_mt.__len = index_mt.len -- Lua 5.2 compatibility
- index_mt.__newindex = function(table, index)
- return error('Attempt to modify a read-only table') end
- index_mt.__index = index_mt
- -- min and max
- index_mt.min_ffi = function(index, key)
- check_index_arg(index, 'min')
- local pkey, pkey_end = tuple_encode(key)
- if builtin.box_index_min(index.space_id, index.id,
- pkey, pkey_end, ptuple) ~= 0 then
- box.error() -- error
- elseif ptuple[0] ~= nil then
- return tuple_bless(ptuple[0])
- else
- return
- end
+local space_mt = {}
+space_mt.__index = space_mt
+box.schema.space_mt = space_mt
+
+function space_mt:len()
+ check_space_arg(self, 'len')
+ local pk = self.index[0]
+ if pk == nil then
+ return 0 -- empty space without indexes, return 0
end
- index_mt.min_luac = function(index, key)
- check_index_arg(index, 'min')
- key = keify(key)
- return internal.min(index.space_id, index.id, key);
+ return self.index[0]:len()
+end
+function space_mt:count(key, opts)
+ check_space_arg(self, 'count')
+ local pk = self.index[0]
+ if pk == nil then
+ return 0 -- empty space without indexes, return 0
end
- index_mt.max_ffi = function(index, key)
- check_index_arg(index, 'max')
- local pkey, pkey_end = tuple_encode(key)
- if builtin.box_index_max(index.space_id, index.id,
- pkey, pkey_end, ptuple) ~= 0 then
- box.error() -- error
- elseif ptuple[0] ~= nil then
- return tuple_bless(ptuple[0])
- else
- return
- end
+ return pk:count(key, opts)
+end
+function space_mt:bsize()
+ check_space_arg(self, 'bsize')
+ local s = builtin.space_by_id(self.id)
+ if s == nil then
+ box.error(box.error.NO_SUCH_SPACE, self.name)
end
- index_mt.max_luac = function(index, key)
- check_index_arg(index, 'max')
- key = keify(key)
- return internal.max(index.space_id, index.id, key);
+ return builtin.space_bsize(s)
+end
+function space_mt:get(key)
+ check_space_arg(self, 'get')
+ return check_primary_index(self):get(key)
+end
+function space_mt:select(key, opts)
+ check_space_arg(self, 'select')
+ return check_primary_index(self):select(key, opts)
+end
+function space_mt:insert(tuple)
+ check_space_arg(self, 'insert')
+ return internal.insert(self.id, tuple)
+end
+function space_mt:replace(tuple)
+ check_space_arg(self, 'replace')
+ return internal.replace(self.id, tuple)
+end
+space_mt.put = space_mt.replace -- put is an alias for replace
+function space_mt:update(key, ops)
+ check_space_arg(self, 'update')
+ return check_primary_index(self):update(key, ops)
+end
+function space_mt:upsert(tuple_key, ops, deprecated)
+ check_space_arg(self, 'upsert')
+ if deprecated ~= nil then
+ local msg = "Error: extra argument in upsert call: "
+ msg = msg .. tostring(deprecated)
+ msg = msg .. ". Usage :upsert(tuple, operations)"
+ box.error(box.error.PROC_LUA, msg)
end
- index_mt.random_ffi = function(index, rnd)
- check_index_arg(index, 'random')
- rnd = rnd or math.random()
- if builtin.box_index_random(index.space_id, index.id, rnd,
- ptuple) ~= 0 then
- box.error() -- error
- elseif ptuple[0] ~= nil then
- return tuple_bless(ptuple[0])
- else
- return
- end
+ return internal.upsert(self.id, tuple_key, ops)
+end
+function space_mt:delete(key)
+ check_space_arg(self, 'delete')
+ return check_primary_index(self):delete(key)
+end
+-- Assumes that spaceno has a TREE (NUM) primary key
+-- inserts a tuple after getting the next value of the
+-- primary key and returns it back to the user
+function space_mt:auto_increment(tuple)
+ check_space_arg(self, 'auto_increment')
+ local max_tuple = check_primary_index(self):max()
+ local max = 0
+ if max_tuple ~= nil then
+ max = max_tuple[1]
+ end
+ table.insert(tuple, 1, max + 1)
+ return self:insert(tuple)
+end
+function space_mt:pairs(key, opts)
+ check_space_arg(self, 'pairs')
+ local pk = self.index[0]
+ if pk == nil then
+ -- empty space without indexes, return empty iterator
+ return fun.iter({})
+ end
+ return pk:pairs(key, opts)
+end
+space_mt.__pairs = space_mt.pairs -- Lua 5.2 compatibility
+space_mt.__ipairs = space_mt.pairs -- Lua 5.2 compatibility
+function space_mt:truncate()
+ check_space_arg(self, 'truncate')
+ return internal.truncate(self.id)
+end
+function space_mt:format(format)
+ check_space_arg(self, 'format')
+ return box.schema.space.format(self.id, format)
+end
+function space_mt:drop()
+ check_space_arg(self, 'drop')
+ check_space_exists(self)
+ return box.schema.space.drop(self.id, self.name)
+end
+function space_mt:rename(name)
+ check_space_arg(self, 'rename')
+ check_space_exists(self)
+ return box.schema.space.rename(self.id, name)
+end
+function space_mt:create_index(name, options)
+ check_space_arg(self, 'create_index')
+ check_space_exists(self)
+ return box.schema.index.create(self.id, name, options)
+end
+function space_mt:run_triggers(yesno)
+ check_space_arg(self, 'run_triggers')
+ local s = builtin.space_by_id(self.id)
+ if s == nil then
+ box.error(box.error.NO_SUCH_SPACE, self.name)
end
- index_mt.random_luac = function(index, rnd)
- check_index_arg(index, 'random')
- rnd = rnd or math.random()
- return internal.random(index.space_id, index.id, rnd);
- end
- -- iteration
- index_mt.pairs_ffi = function(index, key, opts)
- check_index_arg(index, 'pairs')
- local pkey, pkey_end = tuple_encode(key)
- local itype = check_iterator_type(opts, pkey + 1 >= pkey_end);
-
- local keybuf = ffi.string(pkey, pkey_end - pkey)
- local pkeybuf = ffi.cast('const char *', keybuf)
- local cdata = builtin.box_index_iterator(index.space_id, index.id,
- itype, pkeybuf, pkeybuf + #keybuf);
- if cdata == nil then
- box.error()
- end
- return fun.wrap(iterator_gen, keybuf,
- ffi.gc(cdata, builtin.box_iterator_free))
- end
- index_mt.pairs_luac = function(index, key, opts)
- check_index_arg(index, 'pairs')
- key = keify(key)
- local itype = check_iterator_type(opts, #key == 0);
- local keymp = msgpack.encode(key)
- local keybuf = ffi.string(keymp, #keymp)
- local cdata = internal.iterator(index.space_id, index.id, itype, keymp);
- return fun.wrap(iterator_gen_luac, keybuf,
- ffi.gc(cdata, builtin.box_iterator_free))
- end
-
- -- index subtree size
- index_mt.count_ffi = function(index, key, opts)
- check_index_arg(index, 'count')
- local pkey, pkey_end = tuple_encode(key)
- local itype = check_iterator_type(opts, pkey + 1 >= pkey_end);
- local count = builtin.box_index_count(index.space_id, index.id,
- itype, pkey, pkey_end);
- if count == -1 then
- box.error()
- end
- return tonumber(count)
- end
- index_mt.count_luac = function(index, key, opts)
- check_index_arg(index, 'count')
- key = keify(key)
- local itype = check_iterator_type(opts, #key == 0);
- return internal.count(index.space_id, index.id, itype, key);
- end
-
- index_mt.get_ffi = function(index, key)
- check_index_arg(index, 'get')
- local key, key_end = tuple_encode(key)
- if builtin.box_index_get(index.space_id, index.id,
- key, key_end, ptuple) ~= 0 then
- return box.error() -- error
- elseif ptuple[0] ~= nil then
- return tuple_bless(ptuple[0])
- else
- return
- end
+ builtin.space_run_triggers(s, yesno)
+end
+
+local index_mt = {}
+index_mt.__index = index_mt
+box.schema.index_mt = index_mt
+
+function index_mt:len()
+ check_index_arg(self, 'len')
+ local ret = builtin.box_index_len(self.space_id, self.id)
+ if ret == -1 then
+ box.error()
end
- index_mt.get_luac = function(index, key)
- check_index_arg(index, 'get')
- key = keify(key)
- return internal.get(index.space_id, index.id, key)
+ return tonumber(ret)
+end
+function index_mt:bsize()
+ check_index_arg(self, 'bsize')
+ local ret = builtin.box_index_bsize(self.space_id, self.id)
+ if ret == -1 then
+ box.error()
end
-
- local function check_select_opts(opts, key_is_nil)
- local offset = 0
- local limit = 4294967295
- local iterator = check_iterator_type(opts, key_is_nil)
- if opts ~= nil then
- if opts.offset ~= nil then
- offset = opts.offset
- end
- if opts.limit ~= nil then
- limit = opts.limit
- end
- end
- return iterator, offset, limit
+ return tonumber(ret)
+end
+index_mt.__len = index_mt.len -- Lua 5.2 compatibility
+index_mt.__index = index_mt
+function index_mt:min_ffi(key)
+ check_index_arg(self, 'min')
+ local pkey, pkey_end = tuple_encode(key)
+ if builtin.box_index_min(self.space_id, self.id,
+ pkey, pkey_end, ptuple) ~= 0 then
+ box.error()
+ elseif ptuple[0] ~= nil then
+ return tuple_bless(ptuple[0])
end
+end
+function index_mt:min_luac(key)
+ check_index_arg(self, 'min')
+ key = keify(key)
+ return internal.min(self.space_id, self.id, key)
+end
+function index_mt:max_ffi(key)
+ check_index_arg(self, 'max')
+ local pkey, pkey_end = tuple_encode(key)
+ if builtin.box_index_max(self.space_id, self.id,
+ pkey, pkey_end, ptuple) ~= 0 then
+ box.error()
+ elseif ptuple[0] ~= nil then
+ return tuple_bless(ptuple[0])
+ end
+end
+function index_mt:max_luac(key)
+ check_index_arg(self, 'max')
+ key = keify(key)
+ return internal.max(self.space_id, self.id, key)
+end
+function index_mt:random_ffi(rnd)
+ check_index_arg(self, 'random')
+ rnd = rnd or math.random()
+ if builtin.box_index_random(self.space_id, self.id, rnd, ptuple) ~= 0 then
+ box.error()
+ elseif ptuple[0] ~= nil then
+ return tuple_bless(ptuple[0])
+ end
+end
+function index_mt:random_luac(rnd)
+ check_index_arg(self, 'random')
+ rnd = rnd or math.random()
+ return internal.random(self.space_id, self.id, rnd)
+end
+function index_mt:pairs_ffi(key, opts)
+ check_index_arg(self, 'pairs')
+ local pkey, pkey_end = tuple_encode(key)
+ local itype = check_iterator_type(opts, pkey + 1 >= pkey_end)
- index_mt.select_ffi = function(index, key, opts)
- check_index_arg(index, 'select')
- local key, key_end = tuple_encode(key)
- local iterator, offset, limit = check_select_opts(opts, key + 1 >= key_end)
-
- local port = ffi.cast('struct port *', port_tuple)
+ local keybuf = ffi.string(pkey, pkey_end - pkey)
+ local pkeybuf = ffi.cast('const char *', keybuf)
+ local cdata = builtin.box_index_iterator(self.space_id, self.id, itype,
+ pkeybuf, pkeybuf + #keybuf)
+ if cdata == nil then
+ box.error()
+ end
+ return fun.wrap(iterator_gen, keybuf,
+ ffi.gc(cdata, builtin.box_iterator_free))
+end
+function index_mt:pairs_luac(key, opts)
+ check_index_arg(self, 'pairs')
+ key = keify(key)
+ local itype = check_iterator_type(opts, #key == 0)
+ local keymp = msgpack.encode(key)
+ local keybuf = ffi.string(keymp, #keymp)
+ local cdata = internal.iterator(self.space_id, self.id, itype, keymp)
+ return fun.wrap(iterator_gen_luac, keybuf,
+ ffi.gc(cdata, builtin.box_iterator_free))
+end
+function index_mt:count_ffi(key, opts)
+ check_index_arg(self, 'count')
+ local pkey, pkey_end = tuple_encode(key)
+ local itype = check_iterator_type(opts, pkey + 1 >= pkey_end)
+ local count = builtin.box_index_count(self.space_id, self.id, itype, pkey,
+ pkey_end)
+ if count == -1 then
+ box.error()
+ end
+ return tonumber(count)
+end
+function index_mt:count_luac(key, opts)
+ check_index_arg(self, 'count')
+ key = keify(key)
+ local itype = check_iterator_type(opts, #key == 0)
+ return internal.count(self.space_id, self.id, itype, key)
+end
+function index_mt:get_ffi(key)
+ check_index_arg(self, 'get')
+ local key, key_end = tuple_encode(key)
+ if builtin.box_index_get(self.space_id, self.id, key, key_end,
+ ptuple) ~= 0 then
+ return box.error()
+ elseif ptuple[0] ~= nil then
+ return tuple_bless(ptuple[0])
+ end
+end
+function index_mt:get_luac(key)
+ check_index_arg(self, 'get')
+ key = keify(key)
+ return internal.get(self.space_id, self.id, key)
+end
- if builtin.box_select(index.space_id, index.id,
- iterator, offset, limit, key, key_end, port) ~= 0 then
- return box.error()
+local function check_select_opts(opts, key_is_nil)
+ local offset = 0
+ local limit = 4294967295
+ local iterator = check_iterator_type(opts, key_is_nil)
+ if opts ~= nil then
+ if opts.offset ~= nil then
+ offset = opts.offset
end
-
- local ret = {}
- local entry = port_tuple.first
- for i=1,tonumber(port_tuple.size),1 do
- ret[i] = tuple_bless(entry.tuple)
- entry = entry.next
+ if opts.limit ~= nil then
+ limit = opts.limit
end
- builtin.port_destroy(port);
- return ret
end
+ return iterator, offset, limit
+end
- index_mt.select_luac = function(index, key, opts)
- check_index_arg(index, 'select')
- local key = keify(key)
- local iterator, offset, limit = check_select_opts(opts, #key == 0)
- return internal.select(index.space_id, index.id, iterator,
- offset, limit, key)
- end
+function index_mt:select_ffi(key, opts)
+ check_index_arg(self, 'select')
+ local key, key_end = tuple_encode(key)
+ local iterator, offset, limit = check_select_opts(opts, key + 1 >= key_end)
- index_mt.update = function(index, key, ops)
- check_index_arg(index, 'update')
- return internal.update(index.space_id, index.id, keify(key), ops);
- end
- index_mt.delete = function(index, key)
- check_index_arg(index, 'delete')
- return internal.delete(index.space_id, index.id, keify(key));
- end
+ local port = ffi.cast('struct port *', port_tuple)
- index_mt.info = function(index)
- return internal.info(index.space_id, index.id);
+ if builtin.box_select(self.space_id, self.id, iterator, offset, limit, key,
+ key_end, port) ~= 0 then
+ return box.error()
end
- index_mt.drop = function(index)
- check_index_arg(index, 'drop')
- return box.schema.index.drop(index.space_id, index.id)
- end
- index_mt.rename = function(index, name)
- check_index_arg(index, 'rename')
- return box.schema.index.rename(index.space_id, index.id, name)
+ local ret = {}
+ local entry = port_tuple.first
+ for i=1,tonumber(port_tuple.size),1 do
+ ret[i] = tuple_bless(entry.tuple)
+ entry = entry.next
end
- index_mt.alter = function(index, options)
- check_index_arg(index, 'alter')
- if index.id == nil or index.space_id == nil then
- box.error(box.error.PROC_LUA, "Usage: index:alter{opts}")
- end
- return box.schema.index.alter(index.space_id, index.id, options)
+ builtin.port_destroy(port)
+ return ret
+end
+function index_mt:select_luac(key, opts)
+ check_index_arg(self, 'select')
+ local key = keify(key)
+ local iterator, offset, limit = check_select_opts(opts, #key == 0)
+ return internal.select(self.space_id, self.id, iterator, offset, limit, key)
+end
+function index_mt:update(key, ops)
+ check_index_arg(self, 'update')
+ return internal.update(self.space_id, self.id, keify(key), ops)
+end
+function index_mt:delete(key)
+ check_index_arg(self, 'delete')
+ return internal.delete(self.space_id, self.id, keify(key))
+end
+function index_mt:info()
+ return internal.info(self.space_id, self.id)
+end
+function index_mt:drop()
+ check_index_arg(self, 'drop')
+ return box.schema.index.drop(self.space_id, self.id)
+end
+function index_mt:rename(name)
+ check_index_arg(self, 'rename')
+ return box.schema.index.rename(self.space_id, self.id, name)
+end
+function index_mt:alter(options)
+ check_index_arg(self, 'alter')
+ if self.id == nil or self.space_id == nil then
+ box.error(box.error.PROC_LUA, "Usage: index:alter{opts}")
end
+ return box.schema.index.alter(self.space_id, self.id, options)
+end
- -- true if reading operations may yield
+function box.schema.space.bless(space)
+ local space_mt = table.deepcopy(space_mt)
+ local index_mt = table.deepcopy(index_mt)
local read_yields = space.engine == 'vinyl'
local read_ops = {'select', 'get', 'min', 'max', 'count', 'random', 'pairs'}
for _, op in ipairs(read_ops) do
@@ -1302,126 +1402,6 @@ function box.schema.space.bless(space)
end
index_mt.__pairs = index_mt.pairs -- Lua 5.2 compatibility
index_mt.__ipairs = index_mt.pairs -- Lua 5.2 compatibility
- --
- local space_mt = {}
- space_mt.len = function(space)
- check_space_arg(space, 'len')
- local pk = space.index[0]
- if pk == nil then
- return 0 -- empty space without indexes, return 0
- end
- return space.index[0]:len()
- end
- space_mt.count = function(space, key, opts)
- check_space_arg(space, 'count')
- local pk = space.index[0]
- if pk == nil then
- return 0 -- empty space without indexes, return 0
- end
- return pk:count(key, opts)
- end
- space_mt.bsize = function(space)
- check_space_arg(space, 'bsize')
- local s = builtin.space_by_id(space.id)
- if s == nil then
- box.error(box.error.NO_SUCH_SPACE, space.name)
- end
- return builtin.space_bsize(s)
- end
- space_mt.__newindex = index_mt.__newindex
-
- space_mt.get = function(space, key)
- check_space_arg(space, 'get')
- return check_primary_index(space):get(key)
- end
- space_mt.select = function(space, key, opts)
- check_space_arg(space, 'select')
- return check_primary_index(space):select(key, opts)
- end
- space_mt.insert = function(space, tuple)
- check_space_arg(space, 'insert')
- return internal.insert(space.id, tuple);
- end
- space_mt.replace = function(space, tuple)
- check_space_arg(space, 'replace')
- return internal.replace(space.id, tuple);
- end
- space_mt.put = space_mt.replace; -- put is an alias for replace
- space_mt.update = function(space, key, ops)
- check_space_arg(space, 'update')
- return check_primary_index(space):update(key, ops)
- end
- space_mt.upsert = function(space, tuple_key, ops, deprecated)
- check_space_arg(space, 'upsert')
- if deprecated ~= nil then
- local msg = "Error: extra argument in upsert call: "
- msg = msg .. tostring(deprecated)
- msg = msg .. ". Usage :upsert(tuple, operations)"
- box.error(box.error.PROC_LUA, msg)
- end
- return internal.upsert(space.id, tuple_key, ops);
- end
- space_mt.delete = function(space, key)
- check_space_arg(space, 'delete')
- return check_primary_index(space):delete(key)
- end
--- Assumes that spaceno has a TREE (NUM) primary key
--- inserts a tuple after getting the next value of the
--- primary key and returns it back to the user
- space_mt.auto_increment = function(space, tuple)
- check_space_arg(space, 'auto_increment')
- local max_tuple = check_primary_index(space):max()
- local max = 0
- if max_tuple ~= nil then
- max = max_tuple[1]
- end
- table.insert(tuple, 1, max + 1)
- return space:insert(tuple)
- end
-
- space_mt.pairs = function(space, key, opts)
- check_space_arg(space, 'pairs')
- local pk = space.index[0]
- if pk == nil then
- -- empty space without indexes, return empty iterator
- return fun.iter({})
- end
- return pk:pairs(key, opts)
- 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_space_arg(space, 'truncate')
- return internal.truncate(space.id)
- end
- space_mt.format = function(space, format)
- check_space_arg(space, 'format')
- return box.schema.space.format(space.id, format)
- end
- space_mt.drop = function(space)
- check_space_arg(space, 'drop')
- check_space_exists(space)
- return box.schema.space.drop(space.id, space.name)
- end
- space_mt.rename = function(space, name)
- check_space_arg(space, 'rename')
- check_space_exists(space)
- return box.schema.space.rename(space.id, name)
- end
- space_mt.create_index = function(space, name, options)
- check_space_arg(space, 'create_index')
- check_space_exists(space)
- return box.schema.index.create(space.id, name, options)
- end
- space_mt.run_triggers = function(space, yesno)
- check_space_arg(space, 'run_triggers')
- local s = builtin.space_by_id(space.id)
- if s == nil then
- box.error(box.error.NO_SUCH_SPACE, space.name)
- end
- builtin.space_run_triggers(s, yesno)
- end
- space_mt.__index = space_mt
setmetatable(space, space_mt)
if type(space.index) == 'table' and space.enabled then
diff --git a/test/box-tap/schema_mt.test.lua b/test/box-tap/schema_mt.test.lua
new file mode 100755
index 000000000..096c4ad60
--- /dev/null
+++ b/test/box-tap/schema_mt.test.lua
@@ -0,0 +1,79 @@
+#!/usr/bin/env tarantool
+--
+-- pr-3204: expose space_mt, index_mt into box.schema.
+--
+
+local tap = require('tap')
+local test = tap.test('schema_mt')
+
+test:plan(7)
+
+box.cfg{
+ log="tarantool.log",
+}
+
+local sp1 = box.schema.space.create('test')
+local sp2 = box.schema.space.create('test2')
+
+test:is(
+ getmetatable(sp1),
+ getmetatable(sp2),
+ 'all spaces use the same metatable'
+)
+
+local idx1 = sp1:create_index('primary')
+local idx2 = sp2:create_index('primary')
+
+test:isnt(
+ getmetatable(idx1),
+ getmetatable(idx2),
+ 'all indexes have their own metatable'
+)
+
+test:is(
+ idx1.get,
+ idx2.get,
+ 'memtx indexes share read methods'
+)
+
+local sp3 = box.schema.space.create('test3', {engine='vinyl'})
+local sp4 = box.schema.space.create('test4', {engine='vinyl'})
+
+local idx3 = sp3:create_index('primary')
+local idx4 = sp4:create_index('primary')
+
+test:is(
+ idx3.get,
+ idx4.get,
+ 'vinyl indexes share read methods'
+)
+
+test:isnt(
+ idx1.get,
+ idx3.get,
+ 'memtx and vinyl indexes have separate read methods'
+)
+
+function box.schema.space_mt.foo() end
+
+test:is(
+ sp1.foo,
+ box.schema.space_mt.foo,
+ 'box.schema.space_mt is mutable'
+)
+
+function box.schema.index_mt.foo() end
+
+test:is(
+ idx1.foo,
+ box.schema.index_mt.foo,
+ 'box.schema.index_mt is mutable'
+)
+
+test:check()
+
+sp1:drop()
+sp2:drop()
+sp3:drop()
+sp4:drop()
+os.exit(0)
--
2.14.3 (Apple Git-98)
More information about the Tarantool-patches
mailing list