diff --git a/src/box/lua/schema.lua b/src/box/lua/schema.lua index 970d59b89be138c12f15bd6fd7e5a426cd271f18..c8712ac8b8ac2aa5e02a1fdf7a6f068a2f095ac1 100644 --- a/src/box/lua/schema.lua +++ b/src/box/lua/schema.lua @@ -566,16 +566,19 @@ function box.schema.space.bless(space) end -- iteration index_mt.pairs = function(index, key, opts) + check_param_table(opts, {iterator = 'number,string'}); 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 - if opts then + + if opts and opts.iterator then if type(opts.iterator) == "number" then itype = opts.iterator - elseif box.index[opts.iterator] then - itype = box.index[opts.iterator] - elseif opts.iterator ~= nil then - box.error(box.error.ITERATOR_TYPE, tostring(opts.iterator)) + elseif type(opts.iterator) == "string" then + itype = box.index[string.upper(opts.iterator)] + if itype == nil then + box.error(box.error.ITERATOR_TYPE, opts.iterator) + end end end @@ -635,33 +638,36 @@ function box.schema.space.bless(space) end index_mt.select = function(index, key, opts) - local offset = 0 - local limit = 4294967295 - local iterator = box.index.EQ - + local options_template = { + offset = 'number', + limit = 'number', + iterator = 'number,string', + } + check_param_table(opts, options_template); + + local options_defaults = { + offset = 0, + limit = 4294967295, + iterator = box.index.EQ, + } local key, key_end = msgpackffi.encode_tuple(key) if key_end == key + 1 then -- empty array - iterator = box.index.ALL + options_defaults.iterator = box.index.ALL end + opts = update_param_table(opts, options_defaults) - 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 + if type(opts.iterator) == "string" then + local resolved_iter = box.index[string.upper(opts.iterator)] + if resolved_iter == nil then + box.error(box.error.ITERATOR_TYPE, opts.iterator); end + opts.iterator = resolved_iter end port.size = 0; - if builtin.boxffi_select(ffi.cast(port_t, port), index.space.id, - index.id, iterator, offset, limit, key, key_end) ~=0 then + local space_id = index.space.id + if builtin.boxffi_select(ffi.cast(port_t, port), space_id, index.id, + opts.iterator, opts.offset, opts.limit, key, key_end) ~= 0 then return box.error() end diff --git a/test/big/iterator.result b/test/big/iterator.result index e3b4f2083a51db8b4c5d4c018b0d9a4b897833b1..02ea5419e30bb4f98393fa0ea3b919d9b8bb3319 100644 --- a/test/big/iterator.result +++ b/test/big/iterator.result @@ -938,8 +938,10 @@ box.space.test:insert{1} gen, param, state = space.index.t1:pairs({}, {iterator = box.index.ALL}) --- ... -print(gen(param, state)) +gen(param, state) --- +- <iterator state> +- [0] ... id = space.index.t1.id --- @@ -950,8 +952,78 @@ box.schema.index.drop(space.id, id) box.schema.index.alter(space.id, space.index.t2.id, {id = id}) --- ... -print(gen(param, state)) +gen(param, state) +--- +- null +... +space:drop() +--- +... +------------------------------------------------------------------------------- +-- Iterator: https://github.com/tarantool/tarantool/issues/498 +-- Iterator is not checked for wrong type; accept lowercase iterator +------------------------------------------------------------------------------- +space = box.schema.create_space('test', {temporary=true}) +--- +... +space:create_index('primary', {type='TREE',unique=true}) +--- +... +space:insert{0} +--- +- [0] +... +space:insert{1} +--- +- [1] +... +gen, param, state = space.index.primary:pairs({}, {iterator = 'ALL'}) +--- +... +gen(param, state) +--- +- <iterator state> +- [0] +... +gen(param, state) +--- +- <iterator state> +- [1] +... +gen(param, state) +--- +- null +... +gen, param, state = space.index.primary:pairs({}, {iterator = 'all'}) +--- +... +gen(param, state) +--- +- <iterator state> +- [0] +... +gen(param, state) +--- +- <iterator state> +- [1] +... +gen, param, state = space.index.primary:pairs({}, {iterator = 'mistake'}) +--- +- error: Unknown iterator type 'mistake' +... +space:select({}, {iterator = box.index.ALL}) +--- +- - [0] + - [1] +... +space:select({}, {iterator = 'all'}) +--- +- - [0] + - [1] +... +space:select({}, {iterator = 'mistake'}) --- +- error: Unknown iterator type 'mistake' ... space:drop() --- diff --git a/test/big/iterator.test.lua b/test/big/iterator.test.lua index d98feee2b5327a801948c9bb2a46d2ad94d81444..494173c067d1616e772f5fc05a3cacc68ca15879 100644 --- a/test/big/iterator.test.lua +++ b/test/big/iterator.test.lua @@ -184,13 +184,40 @@ box.space.test:insert{0} box.space.test:insert{1} gen, param, state = space.index.t1:pairs({}, {iterator = box.index.ALL}) -print(gen(param, state)) +gen(param, state) id = space.index.t1.id box.schema.index.drop(space.id, id) box.schema.index.alter(space.id, space.index.t2.id, {id = id}) -print(gen(param, state)) +gen(param, state) + +space:drop() + +------------------------------------------------------------------------------- +-- Iterator: https://github.com/tarantool/tarantool/issues/498 +-- Iterator is not checked for wrong type; accept lowercase iterator +------------------------------------------------------------------------------- + +space = box.schema.create_space('test', {temporary=true}) +space:create_index('primary', {type='TREE',unique=true}) +space:insert{0} +space:insert{1} + +gen, param, state = space.index.primary:pairs({}, {iterator = 'ALL'}) +gen(param, state) +gen(param, state) +gen(param, state) + +gen, param, state = space.index.primary:pairs({}, {iterator = 'all'}) +gen(param, state) +gen(param, state) + +gen, param, state = space.index.primary:pairs({}, {iterator = 'mistake'}) + +space:select({}, {iterator = box.index.ALL}) +space:select({}, {iterator = 'all'}) +space:select({}, {iterator = 'mistake'}) space:drop()