[PATCH v1 4/5] box: refactor ER_{FIELD_TYPE, ACTION_MISMATCH}

Kirill Shcherbatov kshcherbatov at tarantool.org
Sun Dec 23 15:40:39 MSK 2018


Reworked ER_FIELD_TYPE and ER_ACTION_MISMATCH error to pass
JSON path to field string instead of field number.
This patch is required for further JSON patches, to give detailed
information about field on error.

Needed for #1012
---
 src/box/errcode.h                   |  4 +-
 src/box/memtx_rtree.c               |  2 +-
 src/box/tuple.h                     | 15 +++--
 src/box/tuple_format.c              | 36 ++++++------
 test/box/alter.result               |  6 +-
 test/box/alter_limits.result        |  7 ++-
 test/box/blackhole.result           |  6 +-
 test/box/ddl.result                 |  8 ++-
 test/box/hash.result                | 15 +++--
 test/box/rtree_misc.result          | 18 ++++--
 test/box/sequence.result            |  3 +-
 test/box/tree_pk.result             |  9 ++-
 test/engine/ddl.result              | 88 ++++++++++++++++++-----------
 test/engine/indices_any_type.result | 12 ++--
 test/engine/null.result             | 33 +++++++----
 test/engine/tree.result             | 12 ++--
 test/engine/tree_variants.result    | 12 ++--
 test/engine/update.result           |  6 +-
 test/engine/upsert.result           |  9 ++-
 test/replication/misc.result        |  3 +-
 test/vinyl/constraint.result        | 18 ++++--
 test/vinyl/errinj.result            |  3 +-
 test/vinyl/gh.result                |  3 +-
 test/vinyl/savepoint.result         |  3 +-
 24 files changed, 206 insertions(+), 125 deletions(-)

diff --git a/src/box/errcode.h b/src/box/errcode.h
index 73359ebdf..7d1f8ddc7 100644
--- a/src/box/errcode.h
+++ b/src/box/errcode.h
@@ -75,7 +75,7 @@ struct errcode_record {
 	/* 20 */_(ER_INVALID_MSGPACK,		"Invalid MsgPack - %s") \
 	/* 21 */_(ER_PROC_RET,			"msgpack.encode: can not encode Lua type '%s'") \
 	/* 22 */_(ER_TUPLE_NOT_ARRAY,		"Tuple/Key must be MsgPack array") \
-	/* 23 */_(ER_FIELD_TYPE,		"Tuple field %u type does not match one required by operation: expected %s") \
+	/* 23 */_(ER_FIELD_TYPE,		"Tuple field %s type does not match one required by operation: expected %s") \
 	/* 24 */_(ER_INDEX_PART_TYPE_MISMATCH,	"Field %s has type '%s' in one index, but type '%s' in another") \
 	/* 25 */_(ER_SPLICE,			"SPLICE error on field %u: %s") \
 	/* 26 */_(ER_UPDATE_ARG_TYPE,		"Argument type in operation '%c' on field %u does not match field type: expected %s") \
@@ -214,7 +214,7 @@ struct errcode_record {
 	/*159 */_(ER_SQL_EXECUTE,               "Failed to execute SQL statement: %s") \
 	/*160 */_(ER_SQL,			"SQL error: %s") \
 	/*161 */_(ER_SQL_BIND_NOT_FOUND,	"Parameter %s was not found in the statement") \
-	/*162 */_(ER_ACTION_MISMATCH,		"Field %d contains %s on conflict action, but %s in index parts") \
+	/*162 */_(ER_ACTION_MISMATCH,		"Field %s contains %s on conflict action, but %s in index parts") \
 	/*163 */_(ER_VIEW_MISSING_SQL,		"Space declared as a view must have SQL statement") \
 	/*164 */_(ER_FOREIGN_KEY_CONSTRAINT,	"Can not commit transaction: deferred foreign keys violations are not resolved") \
 	/*165 */_(ER_NO_SUCH_MODULE,		"Module '%s' does not exist") \
diff --git a/src/box/memtx_rtree.c b/src/box/memtx_rtree.c
index f2aa6c3e5..269660ac3 100644
--- a/src/box/memtx_rtree.c
+++ b/src/box/memtx_rtree.c
@@ -48,7 +48,7 @@ mp_decode_num(const char **data, uint32_t fieldno, double *ret)
 {
 	if (mp_read_double(data, ret) != 0) {
 		diag_set(ClientError, ER_FIELD_TYPE,
-			 fieldno + TUPLE_INDEX_BASE,
+			 tt_sprintf("%u", fieldno + TUPLE_INDEX_BASE),
 			 field_type_strs[FIELD_TYPE_NUMBER]);
 		return -1;
 	}
diff --git a/src/box/tuple.h b/src/box/tuple.h
index 3361b6757..3c8b8825e 100644
--- a/src/box/tuple.h
+++ b/src/box/tuple.h
@@ -640,8 +640,8 @@ tuple_next_with_type(struct tuple_iterator *it, enum mp_type type)
 	}
 	if (mp_typeof(*field) != type) {
 		diag_set(ClientError, ER_FIELD_TYPE,
-			  fieldno + TUPLE_INDEX_BASE,
-			  mp_type_strs[type]);
+			 tt_sprintf("%u", fieldno + TUPLE_INDEX_BASE),
+			 mp_type_strs[type]);
 		return NULL;
 	}
 	return field;
@@ -658,7 +658,7 @@ tuple_next_u32(struct tuple_iterator *it, uint32_t *out)
 	uint32_t val = mp_decode_uint(&field);
 	if (val > UINT32_MAX) {
 		diag_set(ClientError, ER_FIELD_TYPE,
-			 fieldno + TUPLE_INDEX_BASE,
+			 tt_sprintf("%u", fieldno + TUPLE_INDEX_BASE),
 			 field_type_strs[FIELD_TYPE_UNSIGNED]);
 		return -1;
 	}
@@ -706,7 +706,8 @@ tuple_field_with_type(const struct tuple *tuple, uint32_t fieldno,
 	}
 	if (mp_typeof(*field) != type) {
 		diag_set(ClientError, ER_FIELD_TYPE,
-			 fieldno + TUPLE_INDEX_BASE, mp_type_strs[type]);
+			 tt_sprintf("%u", fieldno + TUPLE_INDEX_BASE),
+			 mp_type_strs[type]);
 		return NULL;
 	}
 	return field;
@@ -751,7 +752,8 @@ tuple_field_i64(const struct tuple *tuple, uint32_t fieldno, int64_t *out)
 		}
 		FALLTHROUGH;
 	default:
-		diag_set(ClientError, ER_FIELD_TYPE, fieldno + TUPLE_INDEX_BASE,
+		diag_set(ClientError, ER_FIELD_TYPE,
+			 tt_sprintf("%u", fieldno + TUPLE_INDEX_BASE),
 			 field_type_strs[FIELD_TYPE_INTEGER]);
 		return -1;
 	}
@@ -784,7 +786,8 @@ tuple_field_u32(const struct tuple *tuple, uint32_t fieldno, uint32_t *out)
 		return -1;
 	*out = mp_decode_uint(&field);
 	if (*out > UINT32_MAX) {
-		diag_set(ClientError, ER_FIELD_TYPE, fieldno + TUPLE_INDEX_BASE,
+		diag_set(ClientError, ER_FIELD_TYPE,
+			 tt_sprintf("%u", fieldno + TUPLE_INDEX_BASE),
 			 field_type_strs[FIELD_TYPE_UNSIGNED]);
 		return -1;
 	}
diff --git a/src/box/tuple_format.c b/src/box/tuple_format.c
index 04343fd53..e29f84dc5 100644
--- a/src/box/tuple_format.c
+++ b/src/box/tuple_format.c
@@ -61,9 +61,17 @@ tuple_field_delete(struct tuple_field *field)
 	free(field);
 }
 
+static const char *
+tuple_field_path(const struct tuple_field *field)
+{
+	char *msg = tt_static_buf();
+	json_token_path_snprint(msg, TT_STATIC_BUF_LEN, &field->token,
+				TUPLE_INDEX_BASE);
+	return msg;
+}
+
 static int
-tuple_format_use_key_part(struct tuple_format *format,
-			  const struct field_def *fields, uint32_t field_count,
+tuple_format_use_key_part(struct tuple_format *format, uint32_t field_count,
 			  const struct key_part *part, bool is_sequential,
 			  int *current_slot)
 {
@@ -94,9 +102,9 @@ tuple_format_use_key_part(struct tuple_format *format,
 			field->nullable_action = part->nullable_action;
 	} else if (field->nullable_action != part->nullable_action) {
 		diag_set(ClientError, ER_ACTION_MISMATCH,
-				part->fieldno + TUPLE_INDEX_BASE,
-				on_conflict_action_strs[field->nullable_action],
-				on_conflict_action_strs[part->nullable_action]);
+			 tuple_field_path(field),
+			 on_conflict_action_strs[field->nullable_action],
+			 on_conflict_action_strs[part->nullable_action]);
 		return -1;
 	}
 
@@ -111,21 +119,12 @@ tuple_format_use_key_part(struct tuple_format *format,
 		field->type = part->type;
 	} else if (!field_type1_contains_type2(part->type,
 					       field->type)) {
-		const char *name;
-		int fieldno = part->fieldno + TUPLE_INDEX_BASE;
-		if (part->fieldno >= field_count) {
-			name = tt_sprintf("%d", fieldno);
-		} else {
-			const struct field_def *def =
-				&fields[part->fieldno];
-			name = tt_sprintf("'%s'", def->name);
-		}
 		int errcode;
 		if (!field->is_key_part)
 			errcode = ER_FORMAT_MISMATCH_INDEX_PART;
 		else
 			errcode = ER_INDEX_PART_TYPE_MISMATCH;
-		diag_set(ClientError, errcode, name,
+		diag_set(ClientError, errcode, tuple_field_path(field),
 			 field_type_strs[field->type],
 			 field_type_strs[part->type]);
 		return -1;
@@ -190,8 +189,7 @@ tuple_format_create(struct tuple_format *format, struct key_def * const *keys,
 		const struct key_part *parts_end = part + key_def->part_count;
 
 		for (; part < parts_end; part++) {
-			if (tuple_format_use_key_part(format, fields,
-						      field_count, part,
+			if (tuple_format_use_key_part(format, field_count, part,
 						      is_sequential,
 						      &current_slot) != 0)
 				return -1;
@@ -456,7 +454,7 @@ tuple_init_field_map(const struct tuple_format *format, uint32_t *field_map,
 	if (validate &&
 	    !field_mp_type_is_compatible(field->type, mp_typeof(*pos),
 					 tuple_field_is_nullable(field))) {
-		diag_set(ClientError, ER_FIELD_TYPE, TUPLE_INDEX_BASE,
+		diag_set(ClientError, ER_FIELD_TYPE, tuple_field_path(field),
 			 field_type_strs[field->type]);
 		return -1;
 	}
@@ -480,7 +478,7 @@ tuple_init_field_map(const struct tuple_format *format, uint32_t *field_map,
 		    !field_mp_type_is_compatible(field->type, mp_typeof(*pos),
 						 tuple_field_is_nullable(field))) {
 			diag_set(ClientError, ER_FIELD_TYPE,
-				 i + TUPLE_INDEX_BASE,
+				 tuple_field_path(field),
 				 field_type_strs[field->type]);
 			return -1;
 		}
diff --git a/test/box/alter.result b/test/box/alter.result
index 9a1086e0c..95746a27b 100644
--- a/test/box/alter.result
+++ b/test/box/alter.result
@@ -36,7 +36,8 @@ _space:insert{_space.id, ADMIN, 'test', 'memtx', 0, EMPTY_MAP, {}}
 --
 _space:insert{'hello', 'world', 'test', 'memtx', 0, EMPTY_MAP, {}}
 ---
-- error: 'Tuple field 1 type does not match one required by operation: expected unsigned'
+- error: 'Tuple field [1] type does not match one required by operation: expected
+    unsigned'
 ...
 --
 -- Can't create a space which has wrong field count - field_count must be NUM
@@ -1025,7 +1026,8 @@ s:replace{1}
 ...
 pk:alter{parts = {{1, 'string'}}} -- Must fail.
 ---
-- error: 'Tuple field 1 type does not match one required by operation: expected string'
+- error: 'Tuple field [1] type does not match one required by operation: expected
+    string'
 ...
 s:drop()
 ---
diff --git a/test/box/alter_limits.result b/test/box/alter_limits.result
index 4fd80a374..7f7e5a24e 100644
--- a/test/box/alter_limits.result
+++ b/test/box/alter_limits.result
@@ -564,7 +564,7 @@ index = s:create_index('t1', { type = 'hash' })
 -- field type contradicts field type of another index
 index = s:create_index('t2', { type = 'hash', parts = { 1, 'string' }})
 ---
-- error: Field 1 has type 'unsigned' in one index, but type 'string' in another
+- error: Field [1] has type 'unsigned' in one index, but type 'string' in another
 ...
 -- ok
 index = s:create_index('t2', { type = 'hash', parts = { 2, 'string' }})
@@ -837,7 +837,7 @@ s.index.primary:select{}
 -- ambiguous field type
 index = s:create_index('string', { type = 'tree', unique =  false, parts = { 2, 'string'}})
 ---
-- error: Field 2 has type 'unsigned' in one index, but type 'string' in another
+- error: Field [2] has type 'unsigned' in one index, but type 'string' in another
 ...
 -- create index on a non-existing field
 index = s:create_index('nosuchfield', { type = 'tree', unique = true, parts = { 3, 'string'}})
@@ -855,7 +855,8 @@ s:insert{'Der Baader Meinhof Komplex', '2009 '}
 -- create an index on a field with a wrong type
 index = s:create_index('year', { type = 'tree', unique = false, parts = { 2, 'unsigned'}})
 ---
-- error: 'Tuple field 2 type does not match one required by operation: expected unsigned'
+- error: 'Tuple field [2] type does not match one required by operation: expected
+    unsigned'
 ...
 -- a field is missing
 s:replace{'Der Baader Meinhof Komplex'}
diff --git a/test/box/blackhole.result b/test/box/blackhole.result
index 945b2755c..fef85aa27 100644
--- a/test/box/blackhole.result
+++ b/test/box/blackhole.result
@@ -28,11 +28,13 @@ t, t.key, t.value
 ...
 s:insert{1, 2, 3} -- error
 ---
-- error: 'Tuple field 2 type does not match one required by operation: expected string'
+- error: 'Tuple field [2] type does not match one required by operation: expected
+    string'
 ...
 s:replace{'a', 'b', 'c'} -- error
 ---
-- error: 'Tuple field 1 type does not match one required by operation: expected unsigned'
+- error: 'Tuple field [1] type does not match one required by operation: expected
+    unsigned'
 ...
 s:format{}
 ---
diff --git a/test/box/ddl.result b/test/box/ddl.result
index d3b0d1e0e..7b4aba156 100644
--- a/test/box/ddl.result
+++ b/test/box/ddl.result
@@ -146,7 +146,7 @@ _ = {fiber.create(insert_tuple, {1, 2, 'a'}), fiber.create(add_index), fiber.cre
 {ch:get(), ch:get(), ch:get()}
 ---
 - - - false
-    - 'Tuple field 2 type does not match one required by operation: expected unsigned'
+    - 'Tuple field [2] type does not match one required by operation: expected unsigned'
   - - true
     - [1, 2, 'a']
   - true
@@ -371,11 +371,13 @@ box.space._collation.index.name:delete{'nothing'} -- allowed
 ...
 box.space._collation:auto_increment{'test', 0, 'ICU', 'ru_RU', 42}
 ---
-- error: 'Tuple field 6 type does not match one required by operation: expected map'
+- error: 'Tuple field [6] type does not match one required by operation: expected
+    map'
 ...
 box.space._collation:auto_increment{'test', 0, 'ICU', 'ru_RU', 'options'}
 ---
-- error: 'Tuple field 6 type does not match one required by operation: expected map'
+- error: 'Tuple field [6] type does not match one required by operation: expected
+    map'
 ...
 box.space._collation:auto_increment{'test', 0, 'ICU', 'ru_RU', {ping='pong'}}
 ---
diff --git a/test/box/hash.result b/test/box/hash.result
index 6893a1be0..4846cfebf 100644
--- a/test/box/hash.result
+++ b/test/box/hash.result
@@ -37,7 +37,8 @@ tmp:bsize() > bsize
 -- Insert invalid fields
 hash:insert{'invalid key', 'value1 v1.0', 'value2 v1.0'}
 ---
-- error: 'Tuple field 1 type does not match one required by operation: expected unsigned'
+- error: 'Tuple field [1] type does not match one required by operation: expected
+    unsigned'
 ...
 -------------------------------------------------------------------------------
 -- 32-bit hash replace fields tests
@@ -58,7 +59,8 @@ hash:replace{2, 'value1 v1.43', 'value2 1.92'}
 -- Replace invalid fields
 hash:replace{'invalid key', 'value1 v1.0', 'value2 v1.0'}
 ---
-- error: 'Tuple field 1 type does not match one required by operation: expected unsigned'
+- error: 'Tuple field [1] type does not match one required by operation: expected
+    unsigned'
 ...
 -------------------------------------------------------------------------------
 -- 32-bit hash select fields test
@@ -175,7 +177,8 @@ hash:insert{103, 'value1 v1.0', 'value2 v1.0'}
 ...
 hash:insert{'invalid key', 'value1 v1.0', 'value2 v1.0'}
 ---
-- error: 'Tuple field 1 type does not match one required by operation: expected unsigned'
+- error: 'Tuple field [1] type does not match one required by operation: expected
+    unsigned'
 ...
 -------------------------------------------------------------------------------
 -- 64-bit hash replace fields tests
@@ -208,7 +211,8 @@ hash:replace{2, 'value1 v1.43', 'value2 1.92'}
 ...
 hash:replace{'invalid key', 'value1 v1.0', 'value2 v1.0'}
 ---
-- error: 'Tuple field 1 type does not match one required by operation: expected unsigned'
+- error: 'Tuple field [1] type does not match one required by operation: expected
+    unsigned'
 ...
 -------------------------------------------------------------------------------
 -- 64-bit hash select fields test
@@ -766,7 +770,8 @@ _ = box.space.test:create_index('i',{parts={1,'string'}})
 ...
 box.space.test:insert{1}
 ---
-- error: 'Tuple field 1 type does not match one required by operation: expected string'
+- error: 'Tuple field [1] type does not match one required by operation: expected
+    string'
 ...
 box.space.test:drop()
 ---
diff --git a/test/box/rtree_misc.result b/test/box/rtree_misc.result
index 36d5b8f55..1c9396264 100644
--- a/test/box/rtree_misc.result
+++ b/test/box/rtree_misc.result
@@ -50,11 +50,13 @@ i = s:create_index('secondary', { type = 'hash', parts = {2, 'unsigned'}})
 -- adding a tuple with array instead of num will fail
 i = s:insert{{1, 2, 3}, 4}
 ---
-- error: 'Tuple field 1 type does not match one required by operation: expected unsigned'
+- error: 'Tuple field [1] type does not match one required by operation: expected
+    unsigned'
 ...
 i = s:insert{1, {2, 3, 4}}
 ---
-- error: 'Tuple field 2 type does not match one required by operation: expected unsigned'
+- error: 'Tuple field [2] type does not match one required by operation: expected
+    unsigned'
 ...
 -- rtree index must be one-part
 i = s:create_index('spatial', { type = 'rtree', unique = false, parts = {1, 'array', 2, 'array'}})
@@ -87,15 +89,18 @@ i = s:create_index('spatial', { type = 'rtree', unique = false, parts = {3, 'arr
 -- inserting wrong values (should fail)
 s:insert{1, 2, 3}
 ---
-- error: 'Tuple field 3 type does not match one required by operation: expected array'
+- error: 'Tuple field [3] type does not match one required by operation: expected
+    array'
 ...
 s:insert{1, 2, "3"}
 ---
-- error: 'Tuple field 3 type does not match one required by operation: expected array'
+- error: 'Tuple field [3] type does not match one required by operation: expected
+    array'
 ...
 s:insert{1, 2, nil, 3}
 ---
-- error: 'Tuple field 3 type does not match one required by operation: expected array'
+- error: 'Tuple field [3] type does not match one required by operation: expected
+    array'
 ...
 s:insert{1, 2, {}}
 ---
@@ -554,7 +559,8 @@ s.index.s:drop()
 -- with wrong args
 box.space._index:insert{s.id, 2, 's', 'rtree', nil, {{2, 'array'}}}
 ---
-- error: 'Tuple field 5 type does not match one required by operation: expected map'
+- error: 'Tuple field [5] type does not match one required by operation: expected
+    map'
 ...
 box.space._index:insert{s.id, 2, 's', 'rtree', utils.setmap({}), {{2, 'array'}}}
 ---
diff --git a/test/box/sequence.result b/test/box/sequence.result
index b3907659f..e59498db2 100644
--- a/test/box/sequence.result
+++ b/test/box/sequence.result
@@ -1019,7 +1019,8 @@ s.index.pk.sequence_id == nil
 ...
 s:insert{nil, 'x'} -- error
 ---
-- error: 'Tuple field 1 type does not match one required by operation: expected unsigned'
+- error: 'Tuple field [1] type does not match one required by operation: expected
+    unsigned'
 ...
 box.sequence.test_seq == nil
 ---
diff --git a/test/box/tree_pk.result b/test/box/tree_pk.result
index df3c78bed..fe6385b57 100644
--- a/test/box/tree_pk.result
+++ b/test/box/tree_pk.result
@@ -64,15 +64,18 @@ s0:delete{3}
 -- https://bugs.launchpad.net/tarantool/+bug/1072624
 s0:insert{'xxxxxxx'}
 ---
-- error: 'Tuple field 1 type does not match one required by operation: expected unsigned'
+- error: 'Tuple field [1] type does not match one required by operation: expected
+    unsigned'
 ...
 s0:insert{''}
 ---
-- error: 'Tuple field 1 type does not match one required by operation: expected unsigned'
+- error: 'Tuple field [1] type does not match one required by operation: expected
+    unsigned'
 ...
 s0:insert{'12'}
 ---
-- error: 'Tuple field 1 type does not match one required by operation: expected unsigned'
+- error: 'Tuple field [1] type does not match one required by operation: expected
+    unsigned'
 ...
 s1 = box.schema.space.create('tweedledee')
 ---
diff --git a/test/engine/ddl.result b/test/engine/ddl.result
index 3c84e942d..09001c9a1 100644
--- a/test/engine/ddl.result
+++ b/test/engine/ddl.result
@@ -683,7 +683,8 @@ sk = s:create_index('sk', { parts = { 2, 'string' } })
 ...
 s:replace{1, 1}
 ---
-- error: 'Tuple field 2 type does not match one required by operation: expected string'
+- error: 'Tuple field [2] type does not match one required by operation: expected
+    string'
 ...
 sk:drop()
 ---
@@ -707,8 +708,8 @@ pk = s:create_index('pk')
 ...
 sk1 = s:create_index('sk1', { parts = { 2, 'unsigned' } })
 ---
-- error: Field 'field2' has type 'string' in space format, but type 'unsigned' in
-    index definition
+- error: Field [2] has type 'string' in space format, but type 'unsigned' in index
+    definition
 ...
 -- Check space format conflicting with index parts.
 sk3 = s:create_index('sk3', { parts = { 2, 'string' } })
@@ -719,8 +720,8 @@ format[2].type = 'unsigned'
 ...
 s:format(format)
 ---
-- error: Field 'field2' has type 'unsigned' in space format, but type 'string' in
-    index definition
+- error: Field [2] has type 'unsigned' in space format, but type 'string' in index
+    definition
 ...
 s:format()
 ---
@@ -822,27 +823,33 @@ s:replace{1, '2', {3, 3}, 4.4, -5, true, {value=7}, 8, 9}
 ...
 s:replace{1, 2, {3, 3}, 4.4, -5, true, {value=7}, 8, 9}
 ---
-- error: 'Tuple field 2 type does not match one required by operation: expected string'
+- error: 'Tuple field [2] type does not match one required by operation: expected
+    string'
 ...
 s:replace{1, '2', 3, 4.4, -5, true, {value=7}, 8, 9}
 ---
-- error: 'Tuple field 3 type does not match one required by operation: expected array'
+- error: 'Tuple field [3] type does not match one required by operation: expected
+    array'
 ...
 s:replace{1, '2', {3, 3}, '4', -5, true, {value=7}, 8, 9}
 ---
-- error: 'Tuple field 4 type does not match one required by operation: expected number'
+- error: 'Tuple field [4] type does not match one required by operation: expected
+    number'
 ...
 s:replace{1, '2', {3, 3}, 4.4, -5.5, true, {value=7}, 8, 9}
 ---
-- error: 'Tuple field 5 type does not match one required by operation: expected integer'
+- error: 'Tuple field [5] type does not match one required by operation: expected
+    integer'
 ...
 s:replace{1, '2', {3, 3}, 4.4, -5, {6, 6}, {value=7}, 8, 9}
 ---
-- error: 'Tuple field 6 type does not match one required by operation: expected scalar'
+- error: 'Tuple field [6] type does not match one required by operation: expected
+    scalar'
 ...
 s:replace{1, '2', {3, 3}, 4.4, -5, true, {7}, 8, 9}
 ---
-- error: 'Tuple field 7 type does not match one required by operation: expected map'
+- error: 'Tuple field [7] type does not match one required by operation: expected
+    map'
 ...
 s:replace{1, '2', {3, 3}, 4.4, -5, true, {value=7}}
 ---
@@ -1137,7 +1144,7 @@ inspector:cmd("setopt delimiter ''");
 -- any --X--> unsigned
 fail_format_change(2, 'unsigned')
 ---
-- 'Tuple field 2 type does not match one required by operation: expected unsigned'
+- 'Tuple field [2] type does not match one required by operation: expected unsigned'
 ...
 -- unsigned -----> any
 ok_format_change(3, 'any')
@@ -1146,7 +1153,7 @@ ok_format_change(3, 'any')
 -- unsigned --X--> string
 fail_format_change(3, 'string')
 ---
-- 'Tuple field 3 type does not match one required by operation: expected string'
+- 'Tuple field [3] type does not match one required by operation: expected string'
 ...
 -- unsigned -----> number
 ok_format_change(3, 'number')
@@ -1163,7 +1170,7 @@ ok_format_change(3, 'scalar')
 -- unsigned --X--> map
 fail_format_change(3, 'map')
 ---
-- 'Tuple field 3 type does not match one required by operation: expected map'
+- 'Tuple field [3] type does not match one required by operation: expected map'
 ...
 -- string -----> any
 ok_format_change(4, 'any')
@@ -1176,7 +1183,7 @@ ok_format_change(4, 'scalar')
 -- string --X--> boolean
 fail_format_change(4, 'boolean')
 ---
-- 'Tuple field 4 type does not match one required by operation: expected boolean'
+- 'Tuple field [4] type does not match one required by operation: expected boolean'
 ...
 -- number -----> any
 ok_format_change(5, 'any')
@@ -1189,7 +1196,7 @@ ok_format_change(5, 'scalar')
 -- number --X--> integer
 fail_format_change(5, 'integer')
 ---
-- 'Tuple field 5 type does not match one required by operation: expected integer'
+- 'Tuple field [5] type does not match one required by operation: expected integer'
 ...
 -- integer -----> any
 ok_format_change(6, 'any')
@@ -1206,7 +1213,7 @@ ok_format_change(6, 'scalar')
 -- integer --X--> unsigned
 fail_format_change(6, 'unsigned')
 ---
-- 'Tuple field 6 type does not match one required by operation: expected unsigned'
+- 'Tuple field [6] type does not match one required by operation: expected unsigned'
 ...
 -- boolean -----> any
 ok_format_change(7, 'any')
@@ -1219,7 +1226,7 @@ ok_format_change(7, 'scalar')
 -- boolean --X--> string
 fail_format_change(7, 'string')
 ---
-- 'Tuple field 7 type does not match one required by operation: expected string'
+- 'Tuple field [7] type does not match one required by operation: expected string'
 ...
 -- scalar -----> any
 ok_format_change(8, 'any')
@@ -1228,7 +1235,7 @@ ok_format_change(8, 'any')
 -- scalar --X--> unsigned
 fail_format_change(8, 'unsigned')
 ---
-- 'Tuple field 8 type does not match one required by operation: expected unsigned'
+- 'Tuple field [8] type does not match one required by operation: expected unsigned'
 ...
 -- array -----> any
 ok_format_change(9, 'any')
@@ -1237,7 +1244,7 @@ ok_format_change(9, 'any')
 -- array --X--> scalar
 fail_format_change(9, 'scalar')
 ---
-- 'Tuple field 9 type does not match one required by operation: expected scalar'
+- 'Tuple field [9] type does not match one required by operation: expected scalar'
 ...
 -- map -----> any
 ok_format_change(10, 'any')
@@ -1246,7 +1253,7 @@ ok_format_change(10, 'any')
 -- map --X--> scalar
 fail_format_change(10, 'scalar')
 ---
-- 'Tuple field 10 type does not match one required by operation: expected scalar'
+- 'Tuple field [10] type does not match one required by operation: expected scalar'
 ...
 s:drop()
 ---
@@ -1478,7 +1485,8 @@ format[2].is_nullable = false
 ...
 s:format(format)
 ---
-- error: 'Tuple field 2 type does not match one required by operation: expected unsigned'
+- error: 'Tuple field [2] type does not match one required by operation: expected
+    unsigned'
 ...
 _ = s:delete(1)
 ---
@@ -1536,7 +1544,8 @@ s:insert({1, NULL})
 ...
 s.index.secondary:alter({ parts = {{2, 'string', is_nullable = false} }})
 ---
-- error: 'Tuple field 2 type does not match one required by operation: expected string'
+- error: 'Tuple field [2] type does not match one required by operation: expected
+    string'
 ...
 _ = s:delete({1})
 ---
@@ -1546,7 +1555,8 @@ s.index.secondary:alter({ parts = {{2, 'string', is_nullable = false} }})
 ...
 s:insert({1, NULL})
 ---
-- error: 'Tuple field 2 type does not match one required by operation: expected string'
+- error: 'Tuple field [2] type does not match one required by operation: expected
+    string'
 ...
 s:insert({2, 'xxx'})
 ---
@@ -1666,7 +1676,8 @@ s:replace{1, box.NULL, 1}
 ...
 sk1:alter({parts = {{2, 'unsigned', is_nullable = false}}})
 ---
-- error: 'Tuple field 2 type does not match one required by operation: expected unsigned'
+- error: 'Tuple field [2] type does not match one required by operation: expected
+    unsigned'
 ...
 s:replace{1, 1, 1}
 ---
@@ -1677,7 +1688,8 @@ sk1:alter({parts = {{2, 'unsigned', is_nullable = false}}})
 ...
 s:replace{1, 1, box.NULL}
 ---
-- error: 'Tuple field 3 type does not match one required by operation: expected unsigned'
+- error: 'Tuple field [3] type does not match one required by operation: expected
+    unsigned'
 ...
 sk2:alter({parts = {{3, 'unsigned', is_nullable = true}}})
 ---
@@ -1761,11 +1773,13 @@ s:format()
 ...
 s:replace{1, '100', -20.2}
 ---
-- error: 'Tuple field 2 type does not match one required by operation: expected unsigned'
+- error: 'Tuple field [2] type does not match one required by operation: expected
+    unsigned'
 ...
 s:replace{1, 100, -20.2}
 ---
-- error: 'Tuple field 3 type does not match one required by operation: expected integer'
+- error: 'Tuple field [3] type does not match one required by operation: expected
+    integer'
 ...
 s:replace{1, 100, -20}
 ---
@@ -1829,11 +1843,13 @@ sk4:alter{parts = {{3, 'integer'}}}
 ...
 s:replace{1, 50.5, 1.5}
 ---
-- error: 'Tuple field 2 type does not match one required by operation: expected unsigned'
+- error: 'Tuple field [2] type does not match one required by operation: expected
+    unsigned'
 ...
 s:replace{1, 50, 1.5}
 ---
-- error: 'Tuple field 3 type does not match one required by operation: expected integer'
+- error: 'Tuple field [3] type does not match one required by operation: expected
+    integer'
 ...
 s:replace{5, 5, 5}
 ---
@@ -2006,11 +2022,13 @@ s:create_index('sk', {parts = {2, 'string'}}) -- error: unique constraint
 ...
 s:create_index('sk', {parts = {3, 'string'}}) -- error: nullability constraint
 ---
-- error: 'Tuple field 3 type does not match one required by operation: expected string'
+- error: 'Tuple field [3] type does not match one required by operation: expected
+    string'
 ...
 s:create_index('sk', {parts = {4, 'unsigned'}}) -- error: field type
 ---
-- error: 'Tuple field 4 type does not match one required by operation: expected unsigned'
+- error: 'Tuple field [4] type does not match one required by operation: expected
+    unsigned'
 ...
 s:create_index('sk', {parts = {4, 'integer', 5, 'string'}}) -- error: field missing
 ---
@@ -2059,11 +2077,13 @@ i1:alter{unique = true} -- error: unique contraint
 ...
 i2:alter{parts = {3, 'string'}} -- error: nullability contraint
 ---
-- error: 'Tuple field 3 type does not match one required by operation: expected string'
+- error: 'Tuple field [3] type does not match one required by operation: expected
+    string'
 ...
 i3:alter{parts = {4, 'unsigned'}} -- error: field type
 ---
-- error: 'Tuple field 4 type does not match one required by operation: expected unsigned'
+- error: 'Tuple field [4] type does not match one required by operation: expected
+    unsigned'
 ...
 i3:alter{parts = {4, 'integer', 5, 'string'}} -- error: field missing
 ---
diff --git a/test/engine/indices_any_type.result b/test/engine/indices_any_type.result
index 8158bda4e..02c6c96b1 100644
--- a/test/engine/indices_any_type.result
+++ b/test/engine/indices_any_type.result
@@ -698,15 +698,18 @@ i4_1 = s4:create_index('my_space5_idx1', {type='TREE', parts={1, 'scalar', 2, 'i
 ...
 s4:insert({mp.NULL, 1, 1, 1})
 ---
-- error: 'Tuple field 1 type does not match one required by operation: expected scalar'
+- error: 'Tuple field [1] type does not match one required by operation: expected
+    scalar'
 ...
 s4:insert({2, mp.NULL, 2, 2}) -- all nulls must fail
 ---
-- error: 'Tuple field 2 type does not match one required by operation: expected integer'
+- error: 'Tuple field [2] type does not match one required by operation: expected
+    integer'
 ...
 s4:insert({3, 3, mp.NULL, 3})
 ---
-- error: 'Tuple field 3 type does not match one required by operation: expected number'
+- error: 'Tuple field [3] type does not match one required by operation: expected
+    number'
 ...
 s4:insert({4, 4, 4, mp.NULL})
 ---
@@ -782,7 +785,8 @@ s5:insert({7, true})
 ...
 s5:insert({8, mp.NULL}) -- must fail
 ---
-- error: 'Tuple field 2 type does not match one required by operation: expected scalar'
+- error: 'Tuple field [2] type does not match one required by operation: expected
+    scalar'
 ...
 s5:insert({9, -40.5})
 ---
diff --git a/test/engine/null.result b/test/engine/null.result
index 757e63185..05f47332d 100644
--- a/test/engine/null.result
+++ b/test/engine/null.result
@@ -970,7 +970,8 @@ s:replace{50, 50}
 ...
 s:replace{25, box.NULL}
 ---
-- error: 'Tuple field 2 type does not match one required by operation: expected unsigned'
+- error: 'Tuple field [2] type does not match one required by operation: expected
+    unsigned'
 ...
 format[2].is_nullable = true
 ---
@@ -1025,7 +1026,8 @@ s:replace{50, 50}
 ...
 s:replace{25, box.NULL}
 ---
-- error: 'Tuple field 2 type does not match one required by operation: expected unsigned'
+- error: 'Tuple field [2] type does not match one required by operation: expected
+    unsigned'
 ...
 sk:alter({parts = {{2, 'unsigned', is_nullable = true}}})
 ---
@@ -1617,7 +1619,8 @@ s:replace{1, 1}
 ...
 s:replace{2, box.NULL}
 ---
-- error: 'Tuple field 2 type does not match one required by operation: expected unsigned'
+- error: 'Tuple field [2] type does not match one required by operation: expected
+    unsigned'
 ...
 s:select{}
 ---
@@ -1774,7 +1777,8 @@ s:insert{5}
 ...
 s:insert{5, box.NULL}
 ---
-- error: 'Tuple field 2 type does not match one required by operation: expected unsigned'
+- error: 'Tuple field [2] type does not match one required by operation: expected
+    unsigned'
 ...
 s.index.secondary:alter{parts={{2, 'unsigned', is_nullable=true}}} -- This is allowed.
 ---
@@ -1782,7 +1786,8 @@ s.index.secondary:alter{parts={{2, 'unsigned', is_nullable=true}}} -- This is al
 -- Without space format setting this fails.
 s:insert{5, box.NULL}
 ---
-- error: 'Tuple field 2 type does not match one required by operation: expected unsigned'
+- error: 'Tuple field [2] type does not match one required by operation: expected
+    unsigned'
 ...
 s:insert{5}
 ---
@@ -1801,7 +1806,8 @@ s:format(format) -- This is also allowed.
 -- inserts still fail due to not nullable index parts.
 s:insert{5, box.NULL}
 ---
-- error: 'Tuple field 2 type does not match one required by operation: expected unsigned'
+- error: 'Tuple field [2] type does not match one required by operation: expected
+    unsigned'
 ...
 s:insert{5}
 ---
@@ -1838,11 +1844,13 @@ format[2].is_nullable = false
 ...
 s:format(format) -- Fail.
 ---
-- error: 'Tuple field 2 type does not match one required by operation: expected unsigned'
+- error: 'Tuple field [2] type does not match one required by operation: expected
+    unsigned'
 ...
 s.index.secondary:alter{parts={{2, 'unsigned', is_nullable=false}}} -- Fail.
 ---
-- error: 'Tuple field 2 type does not match one required by operation: expected unsigned'
+- error: 'Tuple field [2] type does not match one required by operation: expected
+    unsigned'
 ...
 _ = s:delete{5}
 ---
@@ -1869,7 +1877,8 @@ s:format(format)
 ...
 s:insert{5, box.NULL} -- Fail.
 ---
-- error: 'Tuple field 2 type does not match one required by operation: expected unsigned'
+- error: 'Tuple field [2] type does not match one required by operation: expected
+    unsigned'
 ...
 s:insert{5} -- Fail.
 ---
@@ -1887,7 +1896,8 @@ s.index.secondary:alter{parts={{2, 'unsigned', is_nullable=false}}}
 ...
 s:insert{5, box.NULL} -- Fail.
 ---
-- error: 'Tuple field 2 type does not match one required by operation: expected unsigned'
+- error: 'Tuple field [2] type does not match one required by operation: expected
+    unsigned'
 ...
 s:insert{5} -- Fail.
 ---
@@ -1935,7 +1945,8 @@ sk2 = s:create_index('sk2', {parts={{2, 'number', is_nullable=true}}})
 ...
 s:insert{2, nil, 2} --error
 ---
-- error: 'Tuple field 2 type does not match one required by operation: expected number'
+- error: 'Tuple field [2] type does not match one required by operation: expected
+    number'
 ...
 s:drop()
 ---
diff --git a/test/engine/tree.result b/test/engine/tree.result
index 0645f41ef..e1c1fd927 100644
--- a/test/engine/tree.result
+++ b/test/engine/tree.result
@@ -2877,19 +2877,23 @@ sort(space:select{})
 -- https://bugs.launchpad.net/tarantool/+bug/1072624
 space:insert{'', 1, 2, '', '', '', '', '', 0}
 ---
-- error: 'Tuple field 1 type does not match one required by operation: expected unsigned'
+- error: 'Tuple field [1] type does not match one required by operation: expected
+    unsigned'
 ...
 space:insert{'xxxxxxxx', 1, 2, '', '', '', '', '', 0}
 ---
-- error: 'Tuple field 1 type does not match one required by operation: expected unsigned'
+- error: 'Tuple field [1] type does not match one required by operation: expected
+    unsigned'
 ...
 space:insert{1, '', 2, '', '', '', '', '', 0}
 ---
-- error: 'Tuple field 2 type does not match one required by operation: expected unsigned'
+- error: 'Tuple field [2] type does not match one required by operation: expected
+    unsigned'
 ...
 space:insert{1, 'xxxxxxxxxxx', 2, '', '', '', '', '', 0}
 ---
-- error: 'Tuple field 2 type does not match one required by operation: expected unsigned'
+- error: 'Tuple field [2] type does not match one required by operation: expected
+    unsigned'
 ...
 space:drop()
 ---
diff --git a/test/engine/tree_variants.result b/test/engine/tree_variants.result
index 0b223d252..ad81a239e 100644
--- a/test/engine/tree_variants.result
+++ b/test/engine/tree_variants.result
@@ -184,19 +184,23 @@ sort(space:select{})
 -- https://bugs.launchpad.net/tarantool/+bug/1072624
 space:insert{'', 1, 2, '', '', '', '', '', 0}
 ---
-- error: 'Tuple field 1 type does not match one required by operation: expected unsigned'
+- error: 'Tuple field [1] type does not match one required by operation: expected
+    unsigned'
 ...
 space:insert{'xxxxxxxx', 1, 2, '', '', '', '', '', 0}
 ---
-- error: 'Tuple field 1 type does not match one required by operation: expected unsigned'
+- error: 'Tuple field [1] type does not match one required by operation: expected
+    unsigned'
 ...
 space:insert{1, '', 2, '', '', '', '', '', 0}
 ---
-- error: 'Tuple field 2 type does not match one required by operation: expected unsigned'
+- error: 'Tuple field [2] type does not match one required by operation: expected
+    unsigned'
 ...
 space:insert{1, 'xxxxxxxxxxx', 2, '', '', '', '', '', 0}
 ---
-- error: 'Tuple field 2 type does not match one required by operation: expected unsigned'
+- error: 'Tuple field [2] type does not match one required by operation: expected
+    unsigned'
 ...
 space:drop()
 ---
diff --git a/test/engine/update.result b/test/engine/update.result
index b73037ebc..c3d7394a8 100644
--- a/test/engine/update.result
+++ b/test/engine/update.result
@@ -722,7 +722,8 @@ aa.VAL
 -- invalid update
 aa:update({{'=',2, 666}})
 ---
-- error: 'Tuple field 2 type does not match one required by operation: expected string'
+- error: 'Tuple field [2] type does not match one required by operation: expected
+    string'
 ...
 -- test transform integrity
 aa:transform(-1, 1)
@@ -753,7 +754,8 @@ box.space.tst_sample:get(2).VAL
 -- invalid upsert
 s:upsert({2, 666}, {{'=', 2, 666}})
 ---
-- error: 'Tuple field 2 type does not match one required by operation: expected string'
+- error: 'Tuple field [2] type does not match one required by operation: expected
+    string'
 ...
 s:drop()
 ---
diff --git a/test/engine/upsert.result b/test/engine/upsert.result
index b35545588..f70ebe665 100644
--- a/test/engine/upsert.result
+++ b/test/engine/upsert.result
@@ -1085,7 +1085,8 @@ index = space:create_index('primary', { type = 'tree', parts = {1, 'unsigned', 2
 ...
 space:upsert({0, 'key', 0}, {{'+', 3, 1}})
 ---
-- error: 'Tuple field 2 type does not match one required by operation: expected unsigned'
+- error: 'Tuple field [2] type does not match one required by operation: expected
+    unsigned'
 ...
 space:drop()
 ---
@@ -1805,7 +1806,8 @@ index1 = space:create_index('primary', { parts = {1, 'string'} })
 ...
 space:upsert({1}, {{'!', 2, 100}}) -- must fail on checking tuple
 ---
-- error: 'Tuple field 1 type does not match one required by operation: expected string'
+- error: 'Tuple field [1] type does not match one required by operation: expected
+    string'
 ...
 space:upsert({'a'}, {{'a', 2, 100}}) -- must fail on checking ops
 ---
@@ -1859,7 +1861,8 @@ index2:select{}
 -- test upsert that executes as update
 space:upsert({'a', 100, 100}, {{'=', 3, -200}}) -- must fail on cheking new tuple in secondary index
 ---
-- error: 'Tuple field 3 type does not match one required by operation: expected unsigned'
+- error: 'Tuple field [3] type does not match one required by operation: expected
+    unsigned'
 ...
 space:upsert({'b', 100, 200}, {{'=', 1, 'd'}}) -- must fail with attempt to modify primary index
 ---
diff --git a/test/replication/misc.result b/test/replication/misc.result
index c32681a7a..ede688a01 100644
--- a/test/replication/misc.result
+++ b/test/replication/misc.result
@@ -207,7 +207,8 @@ c = net_box.connect(box.cfg.listen)
 ...
 c.space.space1:insert{box.NULL, "data"} -- fails, but bumps sequence value
 ---
-- error: 'Tuple field 2 type does not match one required by operation: expected unsigned'
+- error: 'Tuple field [2] type does not match one required by operation: expected
+    unsigned'
 ...
 c.space.space1:insert{box.NULL, 1, "data"}
 ---
diff --git a/test/vinyl/constraint.result b/test/vinyl/constraint.result
index 46ed1c9eb..4c533f7f2 100644
--- a/test/vinyl/constraint.result
+++ b/test/vinyl/constraint.result
@@ -7,11 +7,13 @@ index = space:create_index('primary', { type = 'tree', parts = {1, 'string'} })
 ...
 space:insert{1}
 ---
-- error: 'Tuple field 1 type does not match one required by operation: expected string'
+- error: 'Tuple field [1] type does not match one required by operation: expected
+    string'
 ...
 space:replace{1}
 ---
-- error: 'Tuple field 1 type does not match one required by operation: expected string'
+- error: 'Tuple field [1] type does not match one required by operation: expected
+    string'
 ...
 space:delete{1}
 ---
@@ -23,7 +25,8 @@ space:update({1}, {{'=', 1, 101}})
 ...
 space:upsert({1}, {{'+', 1, 10}})
 ---
-- error: 'Tuple field 1 type does not match one required by operation: expected string'
+- error: 'Tuple field [1] type does not match one required by operation: expected
+    string'
 ...
 space:get{1}
 ---
@@ -45,11 +48,13 @@ index = space:create_index('primary', { type = 'tree', parts = {1, 'unsigned'} }
 ...
 space:insert{'A'}
 ---
-- error: 'Tuple field 1 type does not match one required by operation: expected unsigned'
+- error: 'Tuple field [1] type does not match one required by operation: expected
+    unsigned'
 ...
 space:replace{'A'}
 ---
-- error: 'Tuple field 1 type does not match one required by operation: expected unsigned'
+- error: 'Tuple field [1] type does not match one required by operation: expected
+    unsigned'
 ...
 space:delete{'A'}
 ---
@@ -61,7 +66,8 @@ space:update({'A'}, {{'=', 1, 101}})
 ...
 space:upsert({'A'}, {{'+', 1, 10}})
 ---
-- error: 'Tuple field 1 type does not match one required by operation: expected unsigned'
+- error: 'Tuple field [1] type does not match one required by operation: expected
+    unsigned'
 ...
 space:get{'A'}
 ---
diff --git a/test/vinyl/errinj.result b/test/vinyl/errinj.result
index a081575be..dec469423 100644
--- a/test/vinyl/errinj.result
+++ b/test/vinyl/errinj.result
@@ -1449,7 +1449,8 @@ format[2].is_nullable = false
 ...
 s:format(format) -- must fail
 ---
-- error: 'Tuple field 2 type does not match one required by operation: expected string'
+- error: 'Tuple field [2] type does not match one required by operation: expected
+    string'
 ...
 errinj.set("ERRINJ_VY_READ_PAGE_TIMEOUT", 0)
 ---
diff --git a/test/vinyl/gh.result b/test/vinyl/gh.result
index 76beab094..d702b42e7 100644
--- a/test/vinyl/gh.result
+++ b/test/vinyl/gh.result
@@ -158,7 +158,8 @@ i = s:create_index('primary',{parts={1, 'string'}})
 ...
 box.space.t:insert{1,'A'}
 ---
-- error: 'Tuple field 1 type does not match one required by operation: expected string'
+- error: 'Tuple field [1] type does not match one required by operation: expected
+    string'
 ...
 s:drop()
 ---
diff --git a/test/vinyl/savepoint.result b/test/vinyl/savepoint.result
index d7b57a775..fb93b8fe1 100644
--- a/test/vinyl/savepoint.result
+++ b/test/vinyl/savepoint.result
@@ -424,7 +424,8 @@ space:upsert({12}, {})
 ...
 space:insert({'abc'})
 ---
-- error: 'Tuple field 1 type does not match one required by operation: expected unsigned'
+- error: 'Tuple field [1] type does not match one required by operation: expected
+    unsigned'
 ...
 space:update({1}, {{'#', 2, 1}})
 ---
-- 
2.19.2




More information about the Tarantool-patches mailing list