From: Kirill Shcherbatov <kshcherbatov@tarantool.org> To: tarantool-patches@freelists.org, vdavydov.dev@gmail.com Cc: kostja@tarantool.org, Kirill Shcherbatov <kshcherbatov@tarantool.org> Subject: [PATCH v1 5/5] box: refactor tuple_init_field_map to use bitmap Date: Sun, 23 Dec 2018 15:40:40 +0300 [thread overview] Message-ID: <9009e7b9b9954231c29fc904a5ddf88041907a74.1545567929.git.kshcherbatov@tarantool.org> (raw) In-Reply-To: <cover.1545567929.git.kshcherbatov@tarantool.org> Refactored tuple_init_field_map to fill temporal bitmap and compare it with template req_fields_bitmap containing information about required fields. Each field is mapped to bitmap using unique field identifier. This approach to check the required fields will work even after the introduction of JSON paths, when the field tree becomes multilevel. Needed for #1012 --- src/box/errcode.h | 2 +- src/box/tuple_format.c | 183 +++++++++++++++++++++++------- src/box/tuple_format.h | 23 ++++ test/box/alter_limits.result | 8 +- test/box/ddl.result | 24 ++-- test/box/misc.result | 2 +- test/box/sql.result | 12 +- test/box/tree_pk_multipart.result | 8 +- test/engine/ddl.result | 28 ++--- test/engine/null.result | 52 ++++----- test/vinyl/constraint.result | 12 +- test/vinyl/errinj.result | 12 +- test/vinyl/savepoint.result | 8 +- 13 files changed, 250 insertions(+), 124 deletions(-) diff --git a/src/box/errcode.h b/src/box/errcode.h index 7d1f8ddc7..812e643d8 100644 --- a/src/box/errcode.h +++ b/src/box/errcode.h @@ -91,7 +91,7 @@ struct errcode_record { /* 36 */_(ER_NO_SUCH_SPACE, "Space '%s' does not exist") \ /* 37 */_(ER_NO_SUCH_FIELD, "Field %d was not found in the tuple") \ /* 38 */_(ER_EXACT_FIELD_COUNT, "Tuple field count %u does not match space field count %u") \ - /* 39 */_(ER_MIN_FIELD_COUNT, "Tuple field count %u is less than required by space format or defined indexes (expected at least %u)") \ + /* 39 */_(ER_FIELD_STRUCTURE_MISMATCH, "Tuple field %s does not math document structure defined by space format or index: %s") \ /* 40 */_(ER_WAL_IO, "Failed to write to disk") \ /* 41 */_(ER_MORE_THAN_ONE_TUPLE, "Get() doesn't support partial keys and non-unique indexes") \ /* 42 */_(ER_ACCESS_DENIED, "%s access to %s '%s' is denied for user '%s'") \ diff --git a/src/box/tuple_format.c b/src/box/tuple_format.c index e29f84dc5..6e269fd77 100644 --- a/src/box/tuple_format.c +++ b/src/box/tuple_format.c @@ -28,6 +28,8 @@ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ +#include "bit/bit.h" +#include "fiber.h" #include "json/json.h" #include "tuple_format.h" #include "coll_id_cache.h" @@ -206,6 +208,30 @@ tuple_format_create(struct tuple_format *format, struct key_def * const *keys, return -1; } format->field_map_size = field_map_size; + + /* Allocate required fields bitmap. */ + uint32_t req_fields_bitmap_sz = (format->total_field_count + + CHAR_BIT * sizeof(unsigned long) - 1) / + CHAR_BIT * sizeof(unsigned long); + format->req_fields_bitmap = calloc(1, req_fields_bitmap_sz); + if (format->req_fields_bitmap == NULL) { + diag_set(OutOfMemory, req_fields_bitmap_sz, "calloc", + "format->req_fields_bitmap"); + return -1; + } + struct tuple_field *field; + struct json_token *root = (struct json_token *)&format->fields.root; + json_tree_foreach_entry_preorder(field, root, struct tuple_field, + token) { + /* + * Mark all leaf non-nullable fields as required + * setting corresponding bit 1 in format + * req_fields_bitmap. + */ + if (tuple_field_is_leaf(field) && + !tuple_field_is_nullable(field)) + bit_set(format->req_fields_bitmap, field->id); + } return 0; } @@ -304,6 +330,7 @@ tuple_format_alloc(struct key_def * const *keys, uint16_t key_count, struct tuple_field *field = tuple_field_new(); if (field == NULL) goto error; + field->id = fieldno; field->token.num = fieldno; field->token.type = JSON_TOKEN_NUM; if (json_tree_add(&format->fields, &format->fields.root, @@ -323,6 +350,8 @@ tuple_format_alloc(struct key_def * const *keys, uint16_t key_count, format->dict = dict; tuple_dictionary_ref(dict); } + format->total_field_count = field_count; + format->req_fields_bitmap = NULL; format->refs = 0; format->id = FORMAT_ID_NIL; format->index_field_count = index_field_count; @@ -339,6 +368,7 @@ error: static inline void tuple_format_destroy(struct tuple_format *format) { + free(format->req_fields_bitmap); tuple_format_destroy_fields(format); tuple_dictionary_unref(format->dict); } @@ -422,6 +452,74 @@ tuple_format1_can_store_format2_tuples(struct tuple_format *format1, return true; } +/** + * Return meta information of a tuple field given a format + * and a unique field identifier. + */ +static struct tuple_field * +tuple_format_field_by_id(const struct tuple_format *format, uint32_t id) +{ + struct tuple_field *field; + struct json_token *root = (struct json_token *)&format->fields.root; + json_tree_foreach_entry_preorder(field, root, struct tuple_field, + token) { + if (field->id == id) + return field; + } + return NULL; +} + +/** + * Analyze fields_bitmap to ensure that all required fields + * present in tuple. Routine relies on req_fields_bitmap is + * initialized on tuple_format_create and all required field's + * id bits are set 1. + */ +static int +tuple_format_fields_bitmap_test(const struct tuple_format *format, + const char *fields_bitmap) +{ + struct tuple_field *missed_field = NULL; + const char *req_fields_bitmap = format->req_fields_bitmap; + for (uint32_t i = 0; i < format->total_field_count; i++) { + bool is_required = bit_test(req_fields_bitmap, i); + if (is_required && is_required != bit_test(fields_bitmap, i)) { + missed_field = tuple_format_field_by_id(format, i); + assert(missed_field != NULL); + break; + } + } + if (missed_field == NULL) + return 0; + + struct json_token *token = &missed_field->token; + const char *err; + if (missed_field->token.type == JSON_TOKEN_STR) { + err = tt_sprintf("map does not contain a key \"%.*s\"", + token->len, token->str); + } else if (missed_field->token.type == JSON_TOKEN_NUM) { + struct json_token *parent = token->parent; + /* + * Determine minimal field size looking for + * the greatest fieldno between non-nullable + * missed_field neighbors. + */ + uint32_t expected_size; + for (int i = 0; i <= parent->max_child_idx; i++) { + struct tuple_field *field = + tuple_format_field((struct tuple_format *)format, + i); + if (!tuple_field_is_nullable(field)) + expected_size = i + 1; + } + err = tt_sprintf("invalid array size %d (expected at least %d)", + token->num, expected_size); + } + diag_set(ClientError, ER_FIELD_STRUCTURE_MISMATCH, + tuple_field_path(missed_field), err); + return -1; +} + /** @sa declaration for details. */ int tuple_init_field_map(const struct tuple_format *format, uint32_t *field_map, @@ -441,54 +539,59 @@ tuple_init_field_map(const struct tuple_format *format, uint32_t *field_map, (unsigned) format->exact_field_count); return -1; } - if (validate && field_count < format->min_field_count) { - diag_set(ClientError, ER_MIN_FIELD_COUNT, - (unsigned) field_count, - (unsigned) format->min_field_count); - return -1; - } - - /* first field is simply accessible, so we do not store offset to it */ - const struct tuple_field *field = - tuple_format_field((struct tuple_format *)format, 0); - if (validate && - !field_mp_type_is_compatible(field->type, mp_typeof(*pos), - tuple_field_is_nullable(field))) { - diag_set(ClientError, ER_FIELD_TYPE, tuple_field_path(field), - field_type_strs[field->type]); - return -1; - } - mp_next(&pos); - /* other fields...*/ - uint32_t i = 1; uint32_t defined_field_count = MIN(field_count, validate ? tuple_format_field_count(format) : format->index_field_count); - if (field_count < format->index_field_count) { - /* - * Nullify field map to be able to detect by 0, - * which key fields are absent in tuple_field(). - */ - memset((char *)field_map - format->field_map_size, 0, - format->field_map_size); - } - for (; i < defined_field_count; ++i) { - field = tuple_format_field((struct tuple_format *)format, i); - if (validate && - !field_mp_type_is_compatible(field->type, mp_typeof(*pos), - tuple_field_is_nullable(field))) { - diag_set(ClientError, ER_FIELD_TYPE, - tuple_field_path(field), - field_type_strs[field->type]); + struct region *region = &fiber()->gc; + char *fields_bitmap = NULL; + if (validate) { + uint32_t fields_bitmap_sz = (format->total_field_count + + CHAR_BIT * + sizeof(unsigned long) - 1) / + CHAR_BIT * sizeof(unsigned long); + fields_bitmap = region_alloc(region, fields_bitmap_sz); + if (fields_bitmap == NULL) { + diag_set(OutOfMemory, fields_bitmap_sz, "calloc", + "fields_bitmap"); return -1; } - if (field->offset_slot != TUPLE_OFFSET_SLOT_NIL) { - field_map[field->offset_slot] = - (uint32_t) (pos - tuple); + memset(fields_bitmap, 0, fields_bitmap_sz); + } + memset((char *)field_map - format->field_map_size, 0, + format->field_map_size); + struct json_tree *tree = (struct json_tree *)&format->fields; + struct json_token *parent = &tree->root; + struct json_token token; + token.parent = NULL; + token.type = JSON_TOKEN_NUM; + token.num = 0; + while ((uint32_t)token.num < defined_field_count) { + struct tuple_field *field = + json_tree_lookup_entry(tree, parent, &token, + struct tuple_field, token); + if (field != NULL) { + bool is_nullable = tuple_field_is_nullable(field); + if (validate && + !field_mp_type_is_compatible(field->type, + mp_typeof(*pos), + is_nullable) != 0) { + diag_set(ClientError, ER_FIELD_TYPE, + tuple_field_path(field), + field_type_strs[field->type]); + return -1; + } + if (field->offset_slot != TUPLE_OFFSET_SLOT_NIL) { + field_map[field->offset_slot] = + (uint32_t)(pos - tuple); + } + if (validate) + bit_set(fields_bitmap, field->id); } + token.num++; mp_next(&pos); } - return 0; + return validate ? + tuple_format_fields_bitmap_test(format, fields_bitmap) : 0; } uint32_t diff --git a/src/box/tuple_format.h b/src/box/tuple_format.h index 949337807..947d0d8a5 100644 --- a/src/box/tuple_format.h +++ b/src/box/tuple_format.h @@ -31,6 +31,7 @@ * SUCH DAMAGE. */ +#include "bit/bit.h" #include "key_def.h" #include "field_def.h" #include "errinj.h" @@ -114,6 +115,8 @@ struct tuple_field { struct coll *coll; /** Collation identifier. */ uint32_t coll_id; + /** Field unique identifier in tuple_format. */ + uint32_t id; /** Link in tuple_format::fields. */ struct json_token token; }; @@ -173,6 +176,20 @@ struct tuple_format { * Shared names storage used by all formats of a space. */ struct tuple_dictionary *dict; + /** + * This bitmap of "required fields" contains information + * about fields that must present in tuple to be inserted. + * Look for tuple_format_fields_bitmap_test comment for + * more details. + */ + char *req_fields_bitmap; + /** + * Total count of format fields in fields subtree. + * Required to allocate temporal objects containing + * attributes for all fields. Particularly to allocate + * temporal req_fields_bitmap on region. + */ + uint32_t total_field_count; /** * Fields comprising the format, organized in a tree. * First level nodes correspond to tuple fields. @@ -194,6 +211,12 @@ tuple_format_field_count(const struct tuple_format *format) return root->children != NULL ? root->max_child_idx + 1 : 0; } +static inline bool +tuple_field_is_leaf(struct tuple_field *field) +{ + return field->token.max_child_idx == -1; +} + /** * Return meta information of a top-level tuple field given * a format and a field index. diff --git a/test/box/alter_limits.result b/test/box/alter_limits.result index 7f7e5a24e..d32b7bed5 100644 --- a/test/box/alter_limits.result +++ b/test/box/alter_limits.result @@ -842,8 +842,8 @@ index = s:create_index('string', { type = 'tree', unique = false, parts = { 2, -- create index on a non-existing field index = s:create_index('nosuchfield', { type = 'tree', unique = true, parts = { 3, 'string'}}) --- -- error: Tuple field count 2 is less than required by space format or defined indexes - (expected at least 3) +- error: 'Tuple field [3] does not math document structure defined by space format + or index: invalid array size 2 (expected at least 3)' ... s.index.year:drop() --- @@ -865,8 +865,8 @@ s:replace{'Der Baader Meinhof Komplex'} ... index = s:create_index('year', { type = 'tree', unique = false, parts = { 2, 'unsigned'}}) --- -- error: Tuple field count 1 is less than required by space format or defined indexes - (expected at least 2) +- error: 'Tuple field [2] does not math document structure defined by space format + or index: invalid array size 1 (expected at least 2)' ... s:drop() --- diff --git a/test/box/ddl.result b/test/box/ddl.result index 7b4aba156..eaf58fe78 100644 --- a/test/box/ddl.result +++ b/test/box/ddl.result @@ -326,33 +326,33 @@ box.internal.collation.drop('test') ... box.space._collation:auto_increment{'test'} --- -- error: Tuple field count 2 is less than required by space format or defined indexes - (expected at least 6) +- error: 'Tuple field [3] does not math document structure defined by space format + or index: invalid array size 2 (expected at least 6)' ... box.space._collation:auto_increment{'test', 0, 'ICU'} --- -- error: Tuple field count 4 is less than required by space format or defined indexes - (expected at least 6) +- error: 'Tuple field [5] does not math document structure defined by space format + or index: invalid array size 4 (expected at least 6)' ... box.space._collation:auto_increment{'test', 'ADMIN', 'ICU', 'ru_RU'} --- -- error: Tuple field count 5 is less than required by space format or defined indexes - (expected at least 6) +- error: 'Tuple field [3] type does not match one required by operation: expected + unsigned' ... box.space._collation:auto_increment{42, 0, 'ICU', 'ru_RU'} --- -- error: Tuple field count 5 is less than required by space format or defined indexes - (expected at least 6) +- error: 'Tuple field [2] type does not match one required by operation: expected + string' ... box.space._collation:auto_increment{'test', 0, 42, 'ru_RU'} --- -- error: Tuple field count 5 is less than required by space format or defined indexes - (expected at least 6) +- error: 'Tuple field [4] type does not match one required by operation: expected + string' ... box.space._collation:auto_increment{'test', 0, 'ICU', 42} --- -- error: Tuple field count 5 is less than required by space format or defined indexes - (expected at least 6) +- error: 'Tuple field [5] type does not match one required by operation: expected + string' ... box.space._collation:auto_increment{'test', 0, 'ICU', 'ru_RU', setmap{}} --ok --- diff --git a/test/box/misc.result b/test/box/misc.result index d266bb334..479a401ea 100644 --- a/test/box/misc.result +++ b/test/box/misc.result @@ -369,7 +369,7 @@ t; 36: box.error.NO_SUCH_SPACE 37: box.error.NO_SUCH_FIELD 38: box.error.EXACT_FIELD_COUNT - 39: box.error.MIN_FIELD_COUNT + 39: box.error.FIELD_STRUCTURE_MISMATCH 40: box.error.WAL_IO 41: box.error.MORE_THAN_ONE_TUPLE 42: box.error.ACCESS_DENIED diff --git a/test/box/sql.result b/test/box/sql.result index 1818b294d..cfbe3fe41 100644 --- a/test/box/sql.result +++ b/test/box/sql.result @@ -299,8 +299,8 @@ s:truncate() -- get away with it. space:insert{'Britney'} --- -- error: Tuple field count 1 is less than required by space format or defined indexes - (expected at least 2) +- error: 'Tuple field [2] does not math document structure defined by space format + or index: invalid array size 1 (expected at least 2)' ... sorted(space.index.secondary:select('Anything')) --- @@ -308,8 +308,8 @@ sorted(space.index.secondary:select('Anything')) ... space:insert{'Stephanie'} --- -- error: Tuple field count 1 is less than required by space format or defined indexes - (expected at least 2) +- error: 'Tuple field [2] does not math document structure defined by space format + or index: invalid array size 1 (expected at least 2)' ... sorted(space.index.secondary:select('Anything')) --- @@ -638,8 +638,8 @@ sorted(space.index.secondary:select('Britney')) -- try to insert the incoplete tuple space:replace{'Spears'} --- -- error: Tuple field count 1 is less than required by space format or defined indexes - (expected at least 2) +- error: 'Tuple field [2] does not math document structure defined by space format + or index: invalid array size 1 (expected at least 2)' ... -- check that nothing has been updated space:select{'Spears'} diff --git a/test/box/tree_pk_multipart.result b/test/box/tree_pk_multipart.result index 28cab3f94..e05d3ed00 100644 --- a/test/box/tree_pk_multipart.result +++ b/test/box/tree_pk_multipart.result @@ -490,13 +490,13 @@ i1 = space:create_index('primary', { type = 'tree', parts = {1, 'unsigned', 3, ' ... space:insert{1, 1} --- -- error: Tuple field count 2 is less than required by space format or defined indexes - (expected at least 3) +- error: 'Tuple field [3] does not math document structure defined by space format + or index: invalid array size 2 (expected at least 3)' ... space:replace{1, 1} --- -- error: Tuple field count 2 is less than required by space format or defined indexes - (expected at least 3) +- error: 'Tuple field [3] does not math document structure defined by space format + or index: invalid array size 2 (expected at least 3)' ... space:drop() --- diff --git a/test/engine/ddl.result b/test/engine/ddl.result index 09001c9a1..5f9bd7fa9 100644 --- a/test/engine/ddl.result +++ b/test/engine/ddl.result @@ -77,8 +77,8 @@ index = space:create_index('primary', {type = 'tree', parts = {1, 'unsigned', 2, ... space:insert({13}) --- -- error: Tuple field count 1 is less than required by space format or defined indexes - (expected at least 2) +- error: 'Tuple field [2] does not math document structure defined by space format + or index: invalid array size 1 (expected at least 2)' ... space:drop() --- @@ -853,13 +853,13 @@ s:replace{1, '2', {3, 3}, 4.4, -5, true, {7}, 8, 9} ... s:replace{1, '2', {3, 3}, 4.4, -5, true, {value=7}} --- -- error: Tuple field count 7 is less than required by space format or defined indexes - (expected at least 9) +- error: 'Tuple field [8] does not math document structure defined by space format + or index: invalid array size 7 (expected at least 9)' ... s:replace{1, '2', {3, 3}, 4.4, -5, true, {value=7}, 8} --- -- error: Tuple field count 8 is less than required by space format or defined indexes - (expected at least 9) +- error: 'Tuple field [9] does not math document structure defined by space format + or index: invalid array size 8 (expected at least 9)' ... s:truncate() --- @@ -1343,8 +1343,8 @@ s:format(format) -- Fail, not enough fields. s:replace{2, 2, 2, 2, 2} --- -- error: Tuple field count 5 is less than required by space format or defined indexes - (expected at least 6) +- error: 'Tuple field [6] does not math document structure defined by space format + or index: invalid array size 5 (expected at least 6)' ... s:replace{2, 2, 2, 2, 2, 2, 2} --- @@ -1356,8 +1356,8 @@ format[7] = {name = 'field7', type = 'unsigned'} -- Fail, the tuple {1, ... 1} is invalid for a new format. s:format(format) --- -- error: Tuple field count 6 is less than required by space format or defined indexes - (expected at least 7) +- error: 'Tuple field [7] does not math document structure defined by space format + or index: invalid array size 6 (expected at least 7)' ... s:drop() --- @@ -2032,8 +2032,8 @@ s:create_index('sk', {parts = {4, 'unsigned'}}) -- error: field type ... s:create_index('sk', {parts = {4, 'integer', 5, 'string'}}) -- error: field missing --- -- error: Tuple field count 4 is less than required by space format or defined indexes - (expected at least 5) +- error: 'Tuple field [5] does not math document structure defined by space format + or index: invalid array size 4 (expected at least 5)' ... i1 = s:create_index('i1', {parts = {2, 'string'}, unique = false}) --- @@ -2087,8 +2087,8 @@ i3:alter{parts = {4, 'unsigned'}} -- error: field type ... i3:alter{parts = {4, 'integer', 5, 'string'}} -- error: field missing --- -- error: Tuple field count 4 is less than required by space format or defined indexes - (expected at least 5) +- error: 'Tuple field [5] does not math document structure defined by space format + or index: invalid array size 4 (expected at least 5)' ... i3:alter{parts = {2, 'string', 4, 'integer'}} -- ok --- diff --git a/test/engine/null.result b/test/engine/null.result index 05f47332d..797a525dc 100644 --- a/test/engine/null.result +++ b/test/engine/null.result @@ -458,8 +458,8 @@ sk = s:create_index('sk', {parts = {2, 'unsigned'}}) ... s:replace{1, 2} -- error --- -- error: Tuple field count 2 is less than required by space format or defined indexes - (expected at least 3) +- error: 'Tuple field [3] does not math document structure defined by space format + or index: invalid array size 2 (expected at least 3)' ... t1 = s:replace{2, 3, 4} --- @@ -530,18 +530,18 @@ sk = s:create_index('sk', {parts = {2, 'unsigned'}}) ... s:replace{1, 2} -- error --- -- error: Tuple field count 2 is less than required by space format or defined indexes - (expected at least 5) +- error: 'Tuple field [3] does not math document structure defined by space format + or index: invalid array size 2 (expected at least 5)' ... s:replace{2, 3, 4} -- error --- -- error: Tuple field count 3 is less than required by space format or defined indexes - (expected at least 5) +- error: 'Tuple field [5] does not math document structure defined by space format + or index: invalid array size 4 (expected at least 5)' ... s:replace{3, 4, 5, 6} -- error --- -- error: Tuple field count 4 is less than required by space format or defined indexes - (expected at least 5) +- error: 'Tuple field [5] does not math document structure defined by space format + or index: invalid array size 4 (expected at least 5)' ... t1 = s:replace{4, 5, 6, 7, 8} --- @@ -1071,8 +1071,8 @@ sk = s:create_index('sk', {parts = {{2, 'unsigned', is_nullable = true}}}) -- Test tuple_compare_slowpath, tuple_compare_with_key_slowpath. s:replace{} -- Fail --- -- error: Tuple field count 0 is less than required by space format or defined indexes - (expected at least 1) +- error: 'Tuple field [1] does not math document structure defined by space format + or index: invalid array size 0 (expected at least 1)' ... -- Compare full vs not full. s:replace{2} @@ -1772,8 +1772,8 @@ s:format(format) -- Field 2 is not nullable. s:insert{5} --- -- error: Tuple field count 1 is less than required by space format or defined indexes - (expected at least 2) +- error: 'Tuple field [2] does not math document structure defined by space format + or index: invalid array size 1 (expected at least 2)' ... s:insert{5, box.NULL} --- @@ -1791,8 +1791,8 @@ s:insert{5, box.NULL} ... s:insert{5} --- -- error: Tuple field count 1 is less than required by space format or defined indexes - (expected at least 2) +- error: 'Tuple field [2] does not math document structure defined by space format + or index: invalid array size 1 (expected at least 2)' ... s.index.secondary:alter{parts={{2, 'unsigned', is_nullable=false}}} --- @@ -1811,8 +1811,8 @@ s:insert{5, box.NULL} ... s:insert{5} --- -- error: Tuple field count 1 is less than required by space format or defined indexes - (expected at least 2) +- error: 'Tuple field [2] does not math document structure defined by space format + or index: invalid array size 1 (expected at least 2)' ... s.index.secondary:alter{parts={{2, 'unsigned', is_nullable=true}}} --- @@ -1857,13 +1857,13 @@ _ = s:delete{5} ... s:format(format) -- Still fail. --- -- error: Tuple field count 1 is less than required by space format or defined indexes - (expected at least 2) +- error: 'Tuple field [2] does not math document structure defined by space format + or index: invalid array size 1 (expected at least 2)' ... s.index.secondary:alter{parts={{2, 'unsigned', is_nullable=false}}} -- Still fail. --- -- error: Tuple field count 1 is less than required by space format or defined indexes - (expected at least 2) +- error: 'Tuple field [2] does not math document structure defined by space format + or index: invalid array size 1 (expected at least 2)' ... -- Now check we can set nullability to false step by step. _ = s:delete{6} @@ -1882,8 +1882,8 @@ s:insert{5, box.NULL} -- Fail. ... s:insert{5} -- Fail. --- -- error: Tuple field count 1 is less than required by space format or defined indexes - (expected at least 2) +- error: 'Tuple field [2] does not math document structure defined by space format + or index: invalid array size 1 (expected at least 2)' ... format[2].is_nullable = true --- @@ -1901,8 +1901,8 @@ s:insert{5, box.NULL} -- Fail. ... s:insert{5} -- Fail. --- -- error: Tuple field count 1 is less than required by space format or defined indexes - (expected at least 2) +- error: 'Tuple field [2] does not math document structure defined by space format + or index: invalid array size 1 (expected at least 2)' ... format[2].is_nullable = false --- @@ -1916,8 +1916,8 @@ s:select{} ... s:insert{5} -- Fail. --- -- error: Tuple field count 1 is less than required by space format or defined indexes - (expected at least 2) +- error: 'Tuple field [2] does not math document structure defined by space format + or index: invalid array size 1 (expected at least 2)' ... s:insert{9, 10} -- Success. --- diff --git a/test/vinyl/constraint.result b/test/vinyl/constraint.result index 4c533f7f2..61161ee98 100644 --- a/test/vinyl/constraint.result +++ b/test/vinyl/constraint.result @@ -89,13 +89,13 @@ index = space:create_index('primary', { type = 'tree', parts = {1,'unsigned',2,' ... space:insert{1} --- -- error: Tuple field count 1 is less than required by space format or defined indexes - (expected at least 2) +- error: 'Tuple field [2] does not math document structure defined by space format + or index: invalid array size 1 (expected at least 2)' ... space:replace{1} --- -- error: Tuple field count 1 is less than required by space format or defined indexes - (expected at least 2) +- error: 'Tuple field [2] does not math document structure defined by space format + or index: invalid array size 1 (expected at least 2)' ... space:delete{1} --- @@ -107,8 +107,8 @@ space:update(1, {{'=', 1, 101}}) ... space:upsert({1}, {{'+', 1, 10}}) --- -- error: Tuple field count 1 is less than required by space format or defined indexes - (expected at least 2) +- error: 'Tuple field [2] does not math document structure defined by space format + or index: invalid array size 1 (expected at least 2)' ... space:get{1} --- diff --git a/test/vinyl/errinj.result b/test/vinyl/errinj.result index dec469423..f176cc029 100644 --- a/test/vinyl/errinj.result +++ b/test/vinyl/errinj.result @@ -1635,8 +1635,8 @@ errinj.set("ERRINJ_VY_READ_PAGE_TIMEOUT", 0.001) ... s:create_index('sk', {parts = {2, 'unsigned'}}) -- must fail --- -- error: Tuple field count 1 is less than required by space format or defined indexes - (expected at least 2) +- error: 'Tuple field [2] does not math document structure defined by space format + or index: invalid array size 1 (expected at least 2)' ... errinj.set("ERRINJ_VY_READ_PAGE_TIMEOUT", 0) --- @@ -2088,8 +2088,8 @@ fiber.sleep(0) ... s:format{{'key', 'unsigned'}, {'value', 'unsigned'}} -- must fail --- -- error: Tuple field count 1 is less than required by space format or defined indexes - (expected at least 2) +- error: 'Tuple field [2] does not math document structure defined by space format + or index: invalid array size 1 (expected at least 2)' ... s:select() --- @@ -2113,8 +2113,8 @@ fiber.sleep(0) ... s:create_index('sk', {parts = {2, 'unsigned'}}) --- -- error: Tuple field count 1 is less than required by space format or defined indexes - (expected at least 2) +- error: 'Tuple field [2] does not math document structure defined by space format + or index: invalid array size 1 (expected at least 2)' ... s:select() --- diff --git a/test/vinyl/savepoint.result b/test/vinyl/savepoint.result index fb93b8fe1..e80f21a8c 100644 --- a/test/vinyl/savepoint.result +++ b/test/vinyl/savepoint.result @@ -124,8 +124,8 @@ index2 = space:create_index('secondary', { parts = {2, 'int', 3, 'str'} }) ... space:insert({1}) --- -- error: Tuple field count 1 is less than required by space format or defined indexes - (expected at least 3) +- error: 'Tuple field [2] does not math document structure defined by space format + or index: invalid array size 1 (expected at least 3)' ... space:insert({1, 1, 'a'}) --- @@ -624,8 +624,8 @@ space:insert({4, 2, 'b'}) ... space:upsert({2}, {{'=', 4, 1000}}) --- -- error: Tuple field count 1 is less than required by space format or defined indexes - (expected at least 3) +- error: 'Tuple field [2] does not math document structure defined by space format + or index: invalid array size 1 (expected at least 3)' ... index3:delete({3, 'a'}) --- -- 2.19.2
next prev parent reply other threads:[~2018-12-23 12:40 UTC|newest] Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top 2018-12-23 12:40 [PATCH v1 0/5] box: JSON preparatory patchset Kirill Shcherbatov 2018-12-23 12:40 ` [PATCH v1 1/5] box: refactor tuple_validate_raw Kirill Shcherbatov 2018-12-24 16:40 ` Vladimir Davydov 2018-12-23 12:40 ` [PATCH v1 2/5] box: refactor field type and nullability checks Kirill Shcherbatov 2018-12-24 16:40 ` Vladimir Davydov 2018-12-23 12:40 ` [PATCH v1 3/5] lib: introduce json_token_path_snprint Kirill Shcherbatov 2018-12-24 19:13 ` Vladimir Davydov 2018-12-25 8:53 ` [tarantool-patches] " Kirill Shcherbatov 2018-12-25 16:09 ` Vladimir Davydov 2018-12-23 12:40 ` [PATCH v1 4/5] box: refactor ER_{FIELD_TYPE, ACTION_MISMATCH} Kirill Shcherbatov 2018-12-24 19:36 ` Vladimir Davydov 2018-12-25 8:53 ` [tarantool-patches] " Kirill Shcherbatov 2018-12-25 9:55 ` Vladimir Davydov 2018-12-23 12:40 ` Kirill Shcherbatov [this message] 2018-12-25 17:04 ` [PATCH v1 5/5] box: refactor tuple_init_field_map to use bitmap Vladimir Davydov
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=9009e7b9b9954231c29fc904a5ddf88041907a74.1545567929.git.kshcherbatov@tarantool.org \ --to=kshcherbatov@tarantool.org \ --cc=kostja@tarantool.org \ --cc=tarantool-patches@freelists.org \ --cc=vdavydov.dev@gmail.com \ --subject='Re: [PATCH v1 5/5] box: refactor tuple_init_field_map to use bitmap' \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox