From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from localhost (localhost [127.0.0.1]) by turing.freelists.org (Avenir Technologies Mail Multiplex) with ESMTP id 252292A896 for ; Thu, 21 Mar 2019 11:25:14 -0400 (EDT) Received: from turing.freelists.org ([127.0.0.1]) by localhost (turing.freelists.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id M2F_6uFs5LYN for ; Thu, 21 Mar 2019 11:25:13 -0400 (EDT) Received: from smtp43.i.mail.ru (smtp43.i.mail.ru [94.100.177.103]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by turing.freelists.org (Avenir Technologies Mail Multiplex) with ESMTPS id BA8A52A8A7 for ; Thu, 21 Mar 2019 11:25:13 -0400 (EDT) From: Kirill Shcherbatov Subject: [tarantool-patches] [PATCH v1 1/1] box: introduce index extract_key method Date: Thu, 21 Mar 2019 18:25:10 +0300 Message-Id: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: tarantool-patches-bounce@freelists.org Errors-to: tarantool-patches-bounce@freelists.org Reply-To: tarantool-patches@freelists.org List-Help: List-Unsubscribe: List-software: Ecartis version 1.0.0 List-Id: tarantool-patches List-Subscribe: List-Owner: List-post: List-Archive: To: tarantool-patches@freelists.org, v.shpilevoy@tarantool.org Cc: Kirill Shcherbatov 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