[tarantool-patches] [PATCH v1 1/1] box: introduce index extract_key method

Kirill Shcherbatov kshcherbatov at tarantool.org
Thu Mar 21 18:25:10 MSK 2019


Close #4025

@TarantoolBot document
Title: Built-in function to get index key from tuple
New index method extract_key allows to return key tuple for
corresponding index.

Example:
-- Removal values for secondary non-unique index
s = box.schema.space.create('test')
pk = s:create_index('pk')
sk = s:create_index('sk', {unique=false,
                           parts={{2, 'number', path ='a'},
                                  {2, 'number', path = 'b'}}})
s:insert{1, {a = 1, b = 1}}
s:insert{2, {a = 1, b = 2}}
for _, tuple in pairs(sk:select({1, nil})) do
    local key = pk:extract_key(tuple)
    pk:delete(key)
end

Branch: http://github.com/tarantool/tarantool/tree/kshch/gh-4025-index-extract-key-method
Issue: https://github.com/tarantool/tarantool/issues/4025
---
 src/box/lua/index.c     | 25 +++++++++++++
 src/box/lua/schema.lua  |  4 +++
 test/box/tuple.result   | 77 +++++++++++++++++++++++++++++++++++++++++
 test/box/tuple.test.lua | 27 +++++++++++++++
 4 files changed, 133 insertions(+)

diff --git a/src/box/lua/index.c b/src/box/lua/index.c
index 4cf3c4d68..47fbf321f 100644
--- a/src/box/lua/index.c
+++ b/src/box/lua/index.c
@@ -34,6 +34,7 @@
 #include "info/info.h"
 #include "box/box.h"
 #include "box/index.h"
+#include "box/tuple.h"
 #include "box/lua/tuple.h"
 #include "box/lua/misc.h" /* lbox_encode_tuple_on_gc() */
 
@@ -294,6 +295,29 @@ lbox_truncate(struct lua_State *L)
 	return 0;
 }
 
+static int
+lbox_index_extract_key(lua_State *L)
+{
+	struct tuple *tuple;
+	if (lua_gettop(L) != 3 || !lua_isnumber(L, 1) || !lua_isnumber(L, 2) ||
+	    ((tuple = luaT_istuple(L, 3)) == NULL))
+		return luaL_error(L, "Usage index.extract_key(space_id, "
+				     "index_id, tuple)");
+
+	uint32_t space_id = lua_tonumber(L, 1);
+	uint32_t index_id = lua_tonumber(L, 2);
+	uint32_t key_size;
+	char *key = box_tuple_extract_key(tuple, space_id, index_id, &key_size);
+	if (key == NULL)
+		return luaT_error(L);
+	struct tuple *ret = box_tuple_new(box_tuple_format_default(), key,
+					  key + key_size);
+	if (ret == NULL)
+		return luaT_error(L);
+	luaT_pushtuple(L, ret);
+	return 1;
+}
+
 /* }}} */
 
 /* {{{ Introspection */
@@ -365,6 +389,7 @@ box_lua_index_init(struct lua_State *L)
 		{"truncate", lbox_truncate},
 		{"stat", lbox_index_stat},
 		{"compact", lbox_index_compact},
+		{"extract_key", lbox_index_extract_key},
 		{NULL, NULL}
 	};
 
diff --git a/src/box/lua/schema.lua b/src/box/lua/schema.lua
index 6049931ab..d5684a489 100644
--- a/src/box/lua/schema.lua
+++ b/src/box/lua/schema.lua
@@ -1443,6 +1443,10 @@ base_index_mt.alter = function(index, options)
     end
     return box.schema.index.alter(index.space_id, index.id, options)
 end
+base_index_mt.extract_key = function(index, tuple)
+    check_index_arg(index, 'extract_key')
+    return internal.extract_key(index.space_id, index.id, tuple);
+end
 
 local read_ops = {'select', 'get', 'min', 'max', 'count', 'random', 'pairs'}
 for _, op in ipairs(read_ops) do
diff --git a/test/box/tuple.result b/test/box/tuple.result
index 16aa66b1a..288634f84 100644
--- a/test/box/tuple.result
+++ b/test/box/tuple.result
@@ -1214,3 +1214,80 @@ s2:frommap({a="1", k="11"})
 s2:drop()
 ---
 ...
+--
+-- gh-4025: Introduce built-in function to get index key
+--          from tuple.
+--
+s = box.schema.space.create('test')
+---
+...
+pk = s:create_index('pk')
+---
+...
+sk = s:create_index('sk', {unique=false, parts = {{2, 'number', path = 'a'}, {2, 'number', path = 'b'}}})
+---
+...
+-- Test invalid usage.
+box.internal.extract_key(666, 666, 666)
+---
+- error: Usage index.extract_key(space_id, index_id, tuple)
+...
+box.internal.extract_key(s.id, 666, 666)
+---
+- error: Usage index.extract_key(space_id, index_id, tuple)
+...
+box.internal.extract_key(s.id, sk.id, 666)
+---
+- error: Usage index.extract_key(space_id, index_id, tuple)
+...
+-- Test feature.
+tuple = s:insert{1, {a = 1, b = 1}}
+---
+...
+sk:extract_key(tuple)
+---
+- [1, 1]
+...
+pk:extract_key(tuple)
+---
+- [1]
+...
+pk:delete(pk:extract_key(tuple))
+---
+- [1, {'a': 1, 'b': 1}]
+...
+-- Removal using secondary non-unique index.
+s:insert{1, {a = 1, b = 1}}
+---
+- [1, {'a': 1, 'b': 1}]
+...
+s:insert{2, {a = 1, b = 2}}
+---
+- [2, {'a': 1, 'b': 2}]
+...
+s:insert{3, {a = 1, b = 3}}
+---
+- [3, {'a': 1, 'b': 3}]
+...
+s:insert{4, {a = 2, b = 1}}
+---
+- [4, {'a': 2, 'b': 1}]
+...
+s:insert{6, {a = 3, b = 1}}
+---
+- [6, {'a': 3, 'b': 1}]
+...
+s:insert{9, {a = 3, b = 2}}
+---
+- [9, {'a': 3, 'b': 2}]
+...
+for _, tuple in pairs(sk:select({1, nil})) do _ = pk:delete(pk:extract_key(tuple)) end
+---
+...
+sk:select({1, nil})
+---
+- []
+...
+s:drop()
+---
+...
diff --git a/test/box/tuple.test.lua b/test/box/tuple.test.lua
index 0c89feace..ec8588fe7 100644
--- a/test/box/tuple.test.lua
+++ b/test/box/tuple.test.lua
@@ -410,3 +410,30 @@ s2:format({{name="a", type="str"}, {name="b", type="str", is_nullable=true},
 test_run:cmd("setopt delimiter ''");
 s2:frommap({a="1", k="11"})
 s2:drop()
+
+--
+-- gh-4025: Introduce built-in function to get index key
+--          from tuple.
+--
+s = box.schema.space.create('test')
+pk = s:create_index('pk')
+sk = s:create_index('sk', {unique=false, parts = {{2, 'number', path = 'a'}, {2, 'number', path = 'b'}}})
+-- Test invalid usage.
+box.internal.extract_key(666, 666, 666)
+box.internal.extract_key(s.id, 666, 666)
+box.internal.extract_key(s.id, sk.id, 666)
+-- Test feature.
+tuple = s:insert{1, {a = 1, b = 1}}
+sk:extract_key(tuple)
+pk:extract_key(tuple)
+pk:delete(pk:extract_key(tuple))
+-- Removal using secondary non-unique index.
+s:insert{1, {a = 1, b = 1}}
+s:insert{2, {a = 1, b = 2}}
+s:insert{3, {a = 1, b = 3}}
+s:insert{4, {a = 2, b = 1}}
+s:insert{6, {a = 3, b = 1}}
+s:insert{9, {a = 3, b = 2}}
+for _, tuple in pairs(sk:select({1, nil})) do _ = pk:delete(pk:extract_key(tuple)) end
+sk:select({1, nil})
+s:drop()
-- 
2.21.0





More information about the Tarantool-patches mailing list