[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