Proposed design, 100% compatible with current API and supports for new
extension and new features:

enum iterator_flags {
        /* :2 bits, direction */
        ITER_FORWARD           = 0x0,      /* forward direction */
        ITER_REVERSE           = 0x1,      /* backward direction */

        /* :6 bits, match type */
        ITER_EXACT_GE          = 0x0 << 2, /* exact match, key >= or key <= x */
        ITER_EXACT_EQ          = 0x1 << 2, /* exact match, key = x */
        ITER_ALL               = 0x2 << 2, /* from the first/last element  */

        ITER_EXPR              = 0x3 << 2, /* x is index-dependent
expression */

        /*    bitmap_index specific-flags, typical cases */
        ITER_BITS_ALL_SET      = 0x5 << 2, /* all bits from x are set in key */
        ITER_BITS_ANY_SET      = 0x6 << 2, /* at least one x's bit is set */
        ITER_BITS_ALL_NOTSET   = 0x7 << 2, /* all bits are not set */
        ITER_BITS_ANY_NOTSET   = 0x8 << 2 /* at least one x's bit is not set */
};

localhost>  INSERT INTO t0 VALUES(2,1)
Insert OK, 1 rows affected
localhost>  INSERT INTO t0 VALUES(2,3)
Insert OK, 1 rows affected
localhost>  INSERT INTO t0 VALUES(2,4)
Insert OK, 1 rows affected
localhost>  INSERT INTO t0 VALUES(2,5)
Insert OK, 1 rows affected
localhost>  INSERT INTO t0 VALUES(2,6)
Insert OK, 1 rows affected
localhost>  INSERT INTO t0 VALUES(2,7)
Insert OK, 1 rows affected
localhost>  INSERT INTO t0 VALUES(2,8)
Insert OK, 1 rows affected
localhost>  INSERT INTO t0 VALUES(1,1)
Insert OK, 1 rows affected

-- FORWARD | EXACT_GE
lua iter = box.space[0].index[0]:tuples(0, 2, 3); print(iter(), iter(), iter());
2: {3} 2: {4} 2: {5}

-- REVERSE | EXACT_GE
lua iter = box.space[0].index[0]:tuples(1, 2, 3); print(iter(), iter(), iter());
2: {3}2: {1}1: {1}


-- FORWARD | EXACT_EQ
lua iter = box.space[0].index[0]:tuples(4, 2, 3); print(iter(), iter(), iter());
2: {3}nilnil

-- REVERSE | EXACT_EQ
lua iter = box.space[0].index[0]:tuples(5, 2, 3); print(iter(), iter(), iter());
2: {3}nilnil

-- FORWARD | ALL
localhost> lua iter = box.space[0].index[0]:tuples(8); print(iter(), iter(), 
iter());
1: {1}2: {1}2: {3}

-- REVERSE | ALL
localhost> lua iter = box.space[0].index[0]:tuples(9); print(iter(), iter(), 
iter());
2: {8}2: {7}2: {6}

-- FORWARD | EXACT_GE (missing parameters)
lua iter = box.space[0].index[0]:tuples(0); print(iter(), iter(), iter());
---
error: 'Illegal parameters, key is needed'

-- FORWARD | EXPR (is not supported on TREE)
lua iter = box.space[0].index[0]:tuples(12); print(iter(), iter(), iter());
---
error: 'Illegal parameters, unsupported match type'
...


Old function (next, prev, next_equal, prev_equal) can be removed from C/ObjC 
code (box_lua.m) and implemented in Lua.
Flags can be added to read-only Lua table (to implement enum-like feature).

-- 
You received this bug notification because you are a member of Tarantool
Development Team, which is subscribed to tarantool.
https://bugs.launchpad.net/bugs/1073476

Title:
  box.select_range and box.select_reverse_range only use first part of
  compound keys  / index.next API is weird

Status in Tarantool - an efficient in-memory data store:
  New

Bug description:
  This bug is related to
  https://bugs.launchpad.net/tarantool/+bug/1073457 , but have another
  roots of the problem.

  space[0].enabled = 1
  space[0].index[0].type = "TREE"
  space[0].index[0].unique = 1
  space[0].index[0].key_field[0].fieldno = 0
  space[0].index[0].key_field[0].type = "NUM"
  space[0].index[0].key_field[1].fieldno = 1
  space[0].index[0].key_field[1].type = "NUM"

   INSERT INTO t0 VALUES(2,1)
   INSERT INTO t0 VALUES(2,3)
   INSERT INTO t0 VALUES(2,4)
   INSERT INTO t0 VALUES(2,5)
   INSERT INTO t0 VALUES(2,6)
   INSERT INTO t0 VALUES(2,7)
   INSERT INTO t0 VALUES(2,8)

  localhost> lua box.select_range(0, 0, 100, 2)
  ---
  - 2: {1}
   - 2: {3}
   - 2: {4}
   - 2: {5}
   - 2: {6}
   - 2: {7}
   - 2: {8}

  Incorrect, works like box.select bug (see
  https://bugs.launchpad.net/tarantool/+bug/1073457).

  localhost> lua box.select_range(0, 0, 100, 2, 3)
  ---
   - 2: {1}
   - 2: {3}
   - 2: {4}
   - 2: {5}
   - 2: {6}
   - 2: {7}
   - 2: {8}

  Also incorrect, should select entries starting from 2: {3} (box.select
  works properly).

  box.select_range and box.select_reverse_range are implemented entirely
  in Lua, based on box.index methods.

  01    index_mt.select_range = function(index, limit, ...)
  02       local range = {}
  03        for k, v in index.idx.next, index.idx, ... do
  04           if #range >= limit then
  05                break
  06           end
  07            table.insert(range, v)
  08        end
  09       return unpack(range)
  10    end

  I am not Lua guru, but seems that expression in line 10 with params like 
  "box.select_range(space_no, index_no, key0, key1, key2)" will be expanded to
  "for k, v in index.idx.next, index.idx, key0, key1, key2 do".

  According to lua manual, a for statement like
       for var_1, ···, var_n in explist do block end

  is equivalent to the code:

       do
         local f, s, var = explist
         while true do
           local var_1, ···, var_n = f(s, var)
           var = var_1
           if var == nil then break end
           block
         end
       end

  for our case "for" is evaluated like this
         "local f, s, var = index.idx.next, index.idx, key0, key1, key2"

  As result, all keys begin from second will be ignored.
  I have no idea how to fix it, because current the index iteration API is 
definetly weird (will post another bug for that).

To manage notifications about this bug go to:
https://bugs.launchpad.net/tarantool/+bug/1073476/+subscriptions

_______________________________________________
Mailing list: https://launchpad.net/~tarantool-developers
Post to     : [email protected]
Unsubscribe : https://launchpad.net/~tarantool-developers
More help   : https://help.launchpad.net/ListHelp

Reply via email to