[tarantool-patches] Re: [PATCH v4 4/4] box: introduce functional indexes
Kirill Shcherbatov
kshcherbatov at tarantool.org
Thu Jul 25 14:22:24 MSK 2019
>> + /**
>> + * Can't verify functional index function
>> + * reference on load because the function object
>> + * had not been registered in Tarantool yet.
>> + */
>> + struct memtx_engine *engine = (struct memtx_engine *)space->engine;
>> + if (engine->state == MEMTX_OK && opts->functional_fid > 0) {
>> + struct func *func = func_cache_find(opts->functional_fid);
>> + if (func->def->language != FUNC_LANGUAGE_LUA ||
>> + func->def->body == NULL || !func->def->is_deterministic ||
>> + !func->def->is_sandboxed) {
>> + tnt_raise(ClientError, ER_WRONG_INDEX_OPTIONS, 0,
>> + "referenced function doesn't satisfy "
>> + "functional index constraints");
>> + }
>> + }
>
> this part is obviously incorrect. alter should not depend on
> memtx_engine. And you don't need it at all. Please verify
> key parts inside the trigger on _func_index space, then you don't
> need to check for recovery state.
Don't mind. But we need to clean-up index object in case of failure. The change diff is below:
(I've also dropped collectgarbage calls - it is a legacy)
===========================================================
---
src/box/alter.cc | 27 +++++++-------------
test/engine/functional.result | 44 +++++++++------------------------
test/engine/functional.test.lua | 12 +++------
3 files changed, 25 insertions(+), 58 deletions(-)
diff --git a/src/box/alter.cc b/src/box/alter.cc
index 0b23dd6bb..eb2db1dc9 100644
--- a/src/box/alter.cc
+++ b/src/box/alter.cc
@@ -196,7 +196,7 @@ err:
*/
static void
index_opts_decode(struct index_opts *opts, const char *map,
- struct space *space, struct region *region)
+ struct region *region)
{
index_opts_create(opts);
if (opts_decode(opts, index_opts_reg, &map, ER_WRONG_INDEX_OPTIONS,
@@ -230,22 +230,6 @@ index_opts_decode(struct index_opts *opts, const char *map,
"bloom_fpr must be greater than 0 and "
"less than or equal to 1");
}
- /**
- * Can't verify functional index function
- * reference on load because the function object
- * had not been registered in Tarantool yet.
- */
- struct memtx_engine *engine = (struct memtx_engine *)space->engine;
- if (opts->func_id > 0 && engine->state == MEMTX_OK) {
- struct func *func = func_cache_find(opts->func_id);
- if (func->def->language != FUNC_LANGUAGE_LUA ||
- func->def->body == NULL || !func->def->is_deterministic ||
- !func->def->is_sandboxed) {
- tnt_raise(ClientError, ER_WRONG_INDEX_OPTIONS, 0,
- "referenced function doesn't satisfy "
- "functional index constraints");
- }
- }
}
/**
@@ -277,7 +261,7 @@ index_def_new_from_tuple(struct tuple *tuple, struct space *space)
const char *opts_field =
tuple_field_with_type_xc(tuple, BOX_INDEX_FIELD_OPTS,
MP_MAP);
- index_opts_decode(&opts, opts_field, space, &fiber()->gc);
+ index_opts_decode(&opts, opts_field, &fiber()->gc);
const char *parts = tuple_field(tuple, BOX_INDEX_FIELD_PARTS);
uint32_t part_count = mp_decode_array(&parts);
if (name_len > BOX_NAME_MAX) {
@@ -4761,6 +4745,13 @@ on_replace_dd_func_index(struct trigger *trigger, void *event)
space = space_cache_find_xc(space_id);
index = index_find_xc(space, index_id);
func = func_cache_find(fid);
+ if (func->def->language != FUNC_LANGUAGE_LUA ||
+ func->def->body == NULL || !func->def->is_deterministic ||
+ !func->def->is_sandboxed) {
+ tnt_raise(ClientError, ER_WRONG_INDEX_OPTIONS, 0,
+ "referenced function doesn't satisfy "
+ "functional index constraints");
+ }
} else if (old_tuple != NULL && new_tuple == NULL) {
uint32_t space_id = tuple_field_u32_xc(old_tuple,
BOX_FUNC_INDEX_FIELD_SPACE_ID);
diff --git a/test/engine/functional.result b/test/engine/functional.result
index ca8d0e366..c9f2d813a 100644
--- a/test/engine/functional.result
+++ b/test/engine/functional.result
@@ -49,24 +49,36 @@ _ = s:create_index('idx', {func = 6666, parts = {{1, 'unsigned'}}})
| ---
| - error: Function '6666' does not exist
| ...
+s.index.idx:drop()
+ | ---
+ | ...
-- Can't use non-persistent function in functional index.
_ = s:create_index('idx', {func = box.func.s_nonpersistent.id, parts = {{1, 'unsigned'}}})
| ---
| - error: 'Wrong index options (field 0): referenced function doesn''t satisfy functional
| index constraints'
| ...
+s.index.idx:drop()
+ | ---
+ | ...
-- Can't use non-deterministic function in functional index.
_ = s:create_index('idx', {func = box.func.s_ivaliddef1.id, parts = {{1, 'unsigned'}}})
| ---
| - error: 'Wrong index options (field 0): referenced function doesn''t satisfy functional
| index constraints'
| ...
+s.index.idx:drop()
+ | ---
+ | ...
-- Can't use non-sandboxed function in functional index.
_ = s:create_index('idx', {func = box.func.s_ivaliddef2.id, parts = {{1, 'unsigned'}}})
| ---
| - error: 'Wrong index options (field 0): referenced function doesn''t satisfy functional
| index constraints'
| ...
+s.index.idx:drop()
+ | ---
+ | ...
-- Can't use non-sequential parts in returned key definition.
_ = s:create_index('idx', {func = box.func.ss.id, parts = {{1, 'unsigned'}, {3, 'unsigned'}}})
| ---
@@ -302,10 +314,6 @@ s:drop()
box.schema.func.drop('extr')
| ---
| ...
-collectgarbage()
- | ---
- | - 0
- | ...
-- Multikey functional index.
s = box.schema.space.create('withdata', {engine = engine})
@@ -361,10 +369,6 @@ idx:get(5)
s:drop()
| ---
| ...
-collectgarbage()
- | ---
- | - 0
- | ...
box.schema.func.drop('extr')
| ---
| ...
@@ -416,10 +420,6 @@ idx:select({503}, {iterator = "LE"})
s:drop()
| ---
| ...
-collectgarbage()
- | ---
- | - 0
- | ...
box.schema.func.drop('extr')
| ---
| ...
@@ -521,10 +521,6 @@ idx:select({503})
s:drop()
| ---
| ...
-collectgarbage()
- | ---
- | - 0
- | ...
box.schema.func.drop('extr')
| ---
| ...
@@ -582,10 +578,6 @@ idx:select('Sis')
s:drop()
| ---
| ...
-collectgarbage()
- | ---
- | - 0
- | ...
box.schema.func.drop('addr_extractor')
| ---
| ...
@@ -630,10 +622,6 @@ idx:select()
s:drop()
| ---
| ...
-collectgarbage()
- | ---
- | - 0
- | ...
box.schema.func.drop('extr')
| ---
| ...
@@ -662,10 +650,6 @@ s:insert({1})
s:drop()
| ---
| ...
-collectgarbage()
- | ---
- | - 0
- | ...
box.schema.func.drop('extr')
| ---
| ...
@@ -717,10 +701,6 @@ idx2:get(3)
s:drop()
| ---
| ...
-collectgarbage()
- | ---
- | - 0
- | ...
box.schema.func.drop('s')
| ---
| ...
diff --git a/test/engine/functional.test.lua b/test/engine/functional.test.lua
index ae88f2900..9718fbfb3 100644
--- a/test/engine/functional.test.lua
+++ b/test/engine/functional.test.lua
@@ -19,12 +19,16 @@ _ = s:create_index('idx', {func = box.func.s.id, parts = {{1, 'unsigned'}}})
pk = s:create_index('pk')
-- Invalid fid.
_ = s:create_index('idx', {func = 6666, parts = {{1, 'unsigned'}}})
+s.index.idx:drop()
-- Can't use non-persistent function in functional index.
_ = s:create_index('idx', {func = box.func.s_nonpersistent.id, parts = {{1, 'unsigned'}}})
+s.index.idx:drop()
-- Can't use non-deterministic function in functional index.
_ = s:create_index('idx', {func = box.func.s_ivaliddef1.id, parts = {{1, 'unsigned'}}})
+s.index.idx:drop()
-- Can't use non-sandboxed function in functional index.
_ = s:create_index('idx', {func = box.func.s_ivaliddef2.id, parts = {{1, 'unsigned'}}})
+s.index.idx:drop()
-- Can't use non-sequential parts in returned key definition.
_ = s:create_index('idx', {func = box.func.ss.id, parts = {{1, 'unsigned'}, {3, 'unsigned'}}})
-- Can't use parts started not by 1 field.
@@ -112,7 +116,6 @@ s:insert({2, 1})
idx:get(3)
s:drop()
box.schema.func.drop('extr')
-collectgarbage()
-- Multikey functional index.
s = box.schema.space.create('withdata', {engine = engine})
@@ -129,7 +132,6 @@ idx:get(3)
idx:get(1)
idx:get(5)
s:drop()
-collectgarbage()
box.schema.func.drop('extr')
-- Multikey multipart functional index.
@@ -145,7 +147,6 @@ idx:select({600}, {iterator = "GE"})
idx:get({603, 603})
idx:select({503}, {iterator = "LE"})
s:drop()
-collectgarbage()
box.schema.func.drop('extr')
-- Multikey non-unique functional index.
@@ -174,7 +175,6 @@ idx:select({501})
idx:select({502})
idx:select({503})
s:drop()
-collectgarbage()
box.schema.func.drop('extr')
-- Multikey UTF-8 address extractor
@@ -198,7 +198,6 @@ idx = s:create_index('addr', {unique = false, func = box.func.addr_extractor.id,
idx:select('uk')
idx:select('Sis')
s:drop()
-collectgarbage()
box.schema.func.drop('addr_extractor')
-- Partial index with functional index extractor
@@ -213,7 +212,6 @@ s:insert({3})
s:insert({4})
idx:select()
s:drop()
-collectgarbage()
box.schema.func.drop('extr')
-- Return nil from functional index extractor.
@@ -224,7 +222,6 @@ box.schema.func.create('extr', {body = lua_code, is_deterministic = true, is_san
idx = s:create_index('idx', {unique = false, func = box.func.extr.id, parts = {{1, 'integer', is_nullable = true}}})
s:insert({1})
s:drop()
-collectgarbage()
box.schema.func.drop('extr')
-- Multiple functional indexes
@@ -242,6 +239,5 @@ idx2:get(3)
idx1:drop()
idx2:get(3)
s:drop()
-collectgarbage()
box.schema.func.drop('s')
box.schema.func.drop('sub')
--
2.22.0
More information about the Tarantool-patches
mailing list