From 52915a4c4948c6123cce6455e76dcb723abeb4ed Mon Sep 17 00:00:00 2001
From: Roman Tsisyk <roman@tsisyk.com>
Date: Wed, 5 Mar 2014 16:50:40 +0400
Subject: [PATCH] Replace index:iterator() API with Lua-compatible pairs()

This patch converts space:iterator() to be compatible with Lua
for-in loop conventions. The most important change is that
generating function now returns *state* as its first result:

    for _state, val in space.index[0]:pairs() do work(val) end

New syntax follows the best practices of Lua community and makes
index API to be more consistent with pairs() and tuple iterators.

This change partially restores pairs() logic as it was implemented
before 4987561559388c8c5d672d613d17dbf6cd2f890f.
---
 src/box/lua/schema.lua              | 79 ++++++++++++++++++++---------
 test/big/hash_multipart.result      |  3 +-
 test/big/hash_multipart.test.lua    |  3 +-
 test/big/iterator.result            |  4 +-
 test/big/iterator.test.lua          |  4 +-
 test/big/lua.result                 | 28 ++++++----
 test/big/lua.test.lua               | 22 ++++----
 test/big/lua/utils.lua              |  3 +-
 test/big/sql.result                 |  2 +-
 test/big/sql.test.py                |  2 +-
 test/big/tree_pk.result             | 45 +++++++++++-----
 test/big/tree_pk.test.lua           | 31 ++++++-----
 test/big/tree_pk_multipart.result   |  8 +--
 test/big/tree_pk_multipart.test.lua |  8 +--
 test/box/crossjoin.result           |  4 +-
 test/box/crossjoin.test.lua         |  4 +-
 test/box/errinj_index.result        |  8 +--
 test/box/errinj_index.test.lua      |  8 +--
 test/wal/lua.result                 |  2 +-
 test/wal/lua.test.lua               |  2 +-
 test/wal/oom.result                 |  2 +-
 test/wal/oom.test.lua               |  2 +-
 22 files changed, 171 insertions(+), 103 deletions(-)

diff --git a/src/box/lua/schema.lua b/src/box/lua/schema.lua
index e3cff88a57..e92e5f6012 100644
--- a/src/box/lua/schema.lua
+++ b/src/box/lua/schema.lua
@@ -203,23 +203,49 @@ 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()
@@ -260,7 +286,7 @@ function box.schema.space.bless(space)
     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
@@ -281,12 +307,10 @@ 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 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
@@ -302,7 +326,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
@@ -352,7 +377,8 @@ function box.schema.space.bless(space)
             return result
         end
 
-        for tuple in index:iterator(key, { iterator = iterator }) do
+        local state, tuple
+        for state, tuple in index:pairs(key, { iterator = iterator }) do
             if grep == nil or grep(tuple) then
                 if skip < offset then
                     skip = skip + 1
@@ -494,15 +520,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
diff --git a/test/big/hash_multipart.result b/test/big/hash_multipart.result
index 4eaad79a45..33d6d02dd9 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
diff --git a/test/big/hash_multipart.test.lua b/test/big/hash_multipart.test.lua
index 4e1e0d0cb3..847326d7f2 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
diff --git a/test/big/iterator.result b/test/big/iterator.result
index 86c43987a1..e1b76a8736 100644
--- a/test/big/iterator.result
+++ b/test/big/iterator.result
@@ -884,12 +884,12 @@ 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'''
diff --git a/test/big/iterator.test.lua b/test/big/iterator.test.lua
index e0ca38eaa6..a6f6b6ecf3 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 45e66a3caf..524b6a6a3e 100644
--- a/test/big/lua.result
+++ b/test/big/lua.result
@@ -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']
 ...
@@ -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)..."]:273: Wrong iterator type: wrong_iterator_type'
+- error: '[string "-- schema.lua (internal file)..."]:299: Wrong iterator type: wrong_iterator_type'
 ...
 index = nil
 ---
diff --git a/test/big/lua.test.lua b/test/big/lua.test.lua
index 3c77c28056..b964930755 100644
--- a/test/big/lua.test.lua
+++ b/test/big/lua.test.lua
@@ -24,9 +24,11 @@ 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'}
@@ -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/utils.lua b/test/big/lua/utils.lua
index 063bf5fa89..67adc0e6d9 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 05185e29cc..cfc2318c38 100644
--- a/test/big/sql.result
+++ b/test/big/sql.result
@@ -228,7 +228,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
diff --git a/test/big/sql.test.py b/test/big/sql.test.py
index 7c8b8c52a6..1d3854dbd5 100644
--- a/test/big/sql.test.py
+++ b/test/big/sql.test.py
@@ -90,7 +90,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")
diff --git a/test/big/tree_pk.result b/test/big/tree_pk.result
index 2a4bc433ae..0eeee0869a 100644
--- a/test/big/tree_pk.result
+++ b/test/big/tree_pk.result
@@ -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
@@ -590,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:
@@ -635,25 +635,37 @@ s:insert{1}
 ---
 - [1]
 ...
-itr = ind:iterator()
+gen, param, state = ind:pairs()
 ---
 ...
-itr() -- 1
+state, val = gen(param, state)
+---
+...
+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
 ...
@@ -687,10 +699,13 @@ s:insert{3}
 ---
 - [3]
 ...
-itr = ind:iterator()
+gen, param, state = ind:pairs()
+---
+...
+state, val = gen(param, state)
 ---
 ...
-itr() -- 1
+val -- 1
 ---
 - [1]
 ...
@@ -702,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 028ec47c6b..e950f3be2e 100644
--- a/test/big/tree_pk.test.lua
+++ b/test/big/tree_pk.test.lua
@@ -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
@@ -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 efce5b461f..b54c2cffc5 100644
--- a/test/big/tree_pk_multipart.result
+++ b/test/big/tree_pk_multipart.result
@@ -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 942f30c246..c848914111 100644
--- a/test/big/tree_pk_multipart.test.lua
+++ b/test/big/tree_pk_multipart.test.lua
@@ -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/box/crossjoin.result b/test/box/crossjoin.result
index b3c9739ae9..ef64f6e841 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 b7839c1f4e..5919ae40b5 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/errinj_index.result b/test/box/errinj_index.result
index 76b497c56f..feb59b77a8 100644
--- a/test/box/errinj_index.result
+++ b/test/box/errinj_index.result
@@ -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
@@ -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
 ...
@@ -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
 ...
@@ -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
 ...
diff --git a/test/box/errinj_index.test.lua b/test/box/errinj_index.test.lua
index d6743cbe8d..05e65e060a 100644
--- a/test/box/errinj_index.test.lua
+++ b/test/box/errinj_index.test.lua
@@ -8,7 +8,7 @@ res = {}
 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)
@@ -19,7 +19,7 @@ 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
@@ -33,7 +33,7 @@ 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)
@@ -46,7 +46,7 @@ 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)
 
diff --git a/test/wal/lua.result b/test/wal/lua.result
index 599b03be4b..ee9912e4e9 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
diff --git a/test/wal/lua.test.lua b/test/wal/lua.test.lua
index 6895ce5339..91cfbd9b0d 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
diff --git a/test/wal/oom.result b/test/wal/oom.result
index 9686221457..0a1c9e08fe 100644
--- a/test/wal/oom.result
+++ b/test/wal/oom.result
@@ -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
diff --git a/test/wal/oom.test.lua b/test/wal/oom.test.lua
index bb949f1917..4cbac50b32 100644
--- a/test/wal/oom.test.lua
+++ b/test/wal/oom.test.lua
@@ -31,7 +31,7 @@ space.index['primary']:get{15}
 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
-- 
GitLab