From: Vladimir Davydov <vdavydov.dev@gmail.com> To: tarantool-patches@freelists.org Subject: [PATCH 3/4] schema: allow to set sequence for any index part, not just the first Date: Wed, 15 May 2019 13:33:48 +0300 [thread overview] Message-ID: <924606cabe248b6d1cb8fb126de2c5638537398d.1557916311.git.vdavydov.dev@gmail.com> (raw) In-Reply-To: <cover.1557916311.git.vdavydov.dev@gmail.com> In-Reply-To: <cover.1557916311.git.vdavydov.dev@gmail.com> Closes #4009 @TarantoolBot document Title: Sequence can now be set for an index part other than the first Initially one could attach a sequence (aka autoincrement) only to the first index part. Now it's possible to attach a sequence to any primary index part. The part still must be integer though. Syntax: ``` box.schema.space.create('test') box.space.test:create_index('primary', { parts = {{1, 'string'}, {2, 'unsigned'}, {3, 'unsigned'}}, sequence = true, sequence_part = 2 }) box.space.test:insert{'a', box.null, 1} -- inserts {'a', 1, 1} ``` Note, `sequence_part` option is 1-base. If `sequence_part` is omitted, 1 is used, which assures backward compatibility with the original behavior. One can also attach a sequence to another index part using `index.alter` (the code below continues the example above): ``` box.space.test.index.primary:alter{sequence_part = 3} box.space.test:insert{'a', 1, box.null, 'x'} -- inserts {'a', 1, 2, 'x'} ``` --- src/box/alter.cc | 27 +++++++-- src/box/bootstrap.snap | Bin 4374 -> 4379 bytes src/box/lua/schema.lua | 68 +++++++++++++++------ src/box/lua/space.cc | 7 +++ src/box/lua/upgrade.lua | 35 ++++++++++- src/box/request.c | 2 +- src/box/schema_def.h | 1 + src/box/space.h | 5 ++ src/box/sql/build.c | 7 ++- src/box/sql/insert.c | 2 +- test/box-py/bootstrap.result | 5 +- test/box/access_misc.result | 3 +- test/box/sequence.result | 141 +++++++++++++++++++++++++++++++++++++++++-- test/box/sequence.test.lua | 50 +++++++++++++-- 14 files changed, 312 insertions(+), 41 deletions(-) diff --git a/src/box/alter.cc b/src/box/alter.cc index 9279426d..2d43a9d2 100644 --- a/src/box/alter.cc +++ b/src/box/alter.cc @@ -124,9 +124,14 @@ access_check_ddl(const char *name, uint32_t object_id, uint32_t owner_uid, * is incompatible with a sequence. */ static void -index_def_check_sequence(struct index_def *index_def, const char *space_name) +index_def_check_sequence(struct index_def *index_def, uint32_t sequence_part, + const char *space_name) { - enum field_type type = index_def->key_def->parts[0].type; + if (sequence_part >= index_def->key_def->part_count) { + tnt_raise(ClientError, ER_MODIFY_INDEX, index_def->name, + space_name, "sequence part is out of bounds"); + } + enum field_type type = index_def->key_def->parts[sequence_part].type; if (type != FIELD_TYPE_UNSIGNED && type != FIELD_TYPE_INTEGER) { tnt_raise(ClientError, ER_MODIFY_INDEX, index_def->name, space_name, "sequence cannot be used with " @@ -279,7 +284,8 @@ index_def_new_from_tuple(struct tuple *tuple, struct space *space) index_def_check_xc(index_def, space_name(space)); space_check_index_def_xc(space, index_def); if (index_def->iid == 0 && space->sequence != NULL) - index_def_check_sequence(index_def, space_name(space)); + index_def_check_sequence(index_def, space->sequence_part, + space_name(space)); index_def_guard.is_active = false; return index_def; } @@ -855,6 +861,7 @@ alter_space_do(struct txn *txn, struct alter_space *alter) space_prepare_alter_xc(alter->old_space, alter->new_space); alter->new_space->sequence = alter->old_space->sequence; + alter->new_space->sequence_part = alter->old_space->sequence_part; memcpy(alter->new_space->access, alter->old_space->access, sizeof(alter->old_space->access)); @@ -3333,6 +3340,12 @@ on_replace_dd_space_sequence(struct trigger * /* trigger */, void *event) BOX_SPACE_SEQUENCE_FIELD_SEQUENCE_ID); bool is_generated = tuple_field_bool_xc(tuple, BOX_SPACE_SEQUENCE_FIELD_IS_GENERATED); + /* Sequence part was added in 2.2.1. */ + uint32_t sequence_part = 0; + if (tuple_field_count(tuple) > BOX_SPACE_SEQUENCE_FIELD_PART) { + sequence_part = tuple_field_u32_xc(tuple, + BOX_SPACE_SEQUENCE_FIELD_PART); + } struct space *space = space_cache_find_xc(space_id); struct sequence *seq = sequence_cache_find(sequence_id); @@ -3365,17 +3378,21 @@ on_replace_dd_space_sequence(struct trigger * /* trigger */, void *event) if (stmt->new_tuple != NULL) { /* INSERT, UPDATE */ struct index *pk = index_find_xc(space, 0); - index_def_check_sequence(pk->def, space_name(space)); - if (seq->is_generated) { + index_def_check_sequence(pk->def, sequence_part, + space_name(space)); + if (seq->is_generated && seq != space->sequence) { tnt_raise(ClientError, ER_ALTER_SPACE, space_name(space), "can not attach generated sequence"); } seq->is_generated = is_generated; space->sequence = seq; + space->sequence_part = sequence_part; } else { /* DELETE */ assert(space->sequence == seq); + assert(space->sequence_part == sequence_part); space->sequence = NULL; + space->sequence_part = 0; } } diff --git a/src/box/bootstrap.snap b/src/box/bootstrap.snap index 871a93f9856f97636ad55b7f5260e5c6957fef36..8c3b10e8417494edba07e6eba78377226ee5a31a 100644 GIT binary patch delta 3671 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 delta 3647 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 Rfj#7n<+o@q*9X-Qt?gkf;xqsN diff --git a/src/box/lua/schema.lua b/src/box/lua/schema.lua index 14ad4de1..91900395 100644 --- a/src/box/lua/schema.lua +++ b/src/box/lua/schema.lua @@ -748,6 +748,20 @@ local function simplify_index_parts(parts) return new_parts end +local function check_sequence_part(parts, sequence_part, + index_name, space_name) + if sequence_part <= 0 or sequence_part > #parts then + box.error(box.error.MODIFY_INDEX, index_name, space_name, + "sequence part is out of bounds") + end + sequence_part = parts[sequence_part] + local sequence_part_type = sequence_part.type or sequence_part[2] + if sequence_part_type ~= 'integer' and sequence_part_type ~= 'unsigned' then + box.error(box.error.MODIFY_INDEX, index_name, space_name, + "sequence cannot be used with a non-integer key") + end +end + -- Historically, some properties of an index -- are stored as tuple fields, others in a -- single field containing msgpack map. @@ -773,6 +787,7 @@ local alter_index_template = { type = 'string', parts = 'table', sequence = 'boolean, number, string', + sequence_part = 'number', } for k, v in pairs(index_options) do alter_index_template[k] = v @@ -885,16 +900,18 @@ box.schema.index.create = function(space_id, name, options) local _space_sequence = box.space[box.schema.SPACE_SEQUENCE_ID] local sequence_is_generated = false local sequence = options.sequence or nil -- ignore sequence = false + local sequence_part = options.sequence_part + if sequence_part ~= nil and sequence == nil then + box.error(box.error.MODIFY_INDEX, options.name, space.name, + "sequence part cannot be used without sequence") + end if sequence ~= nil then if iid ~= 0 then box.error(box.error.MODIFY_INDEX, name, space.name, "sequence cannot be used with a secondary key") end - if #parts >= 1 and parts[1].type ~= 'integer' and - parts[1].type ~= 'unsigned' then - box.error(box.error.MODIFY_INDEX, name, space.name, - "sequence cannot be used with a non-integer key") - end + sequence_part = sequence_part or 1 + check_sequence_part(parts, sequence_part, name, space.name) if sequence == true then sequence = box.schema.sequence.create(space.name .. '_seq') sequence = sequence.id @@ -912,7 +929,8 @@ box.schema.index.create = function(space_id, name, options) end _index:insert{space_id, iid, name, options.type, index_opts, parts} if sequence ~= nil then - _space_sequence:insert{space_id, sequence, sequence_is_generated} + _space_sequence:insert{space_id, sequence, sequence_is_generated, + sequence_part - 1} end return space.index[name] end @@ -1028,32 +1046,45 @@ box.schema.index.alter = function(space_id, index_id, options) local _space_sequence = box.space[box.schema.SPACE_SEQUENCE_ID] local sequence_is_generated = false local sequence = options.sequence + local sequence_part = options.sequence_part local sequence_tuple if index_id ~= 0 then - if sequence then + if sequence or sequence_part ~= nil then box.error(box.error.MODIFY_INDEX, options.name, space.name, "sequence cannot be used with a secondary key") end -- ignore 'sequence = false' for secondary indexes sequence = nil - else + end + if sequence ~= nil or sequence_part ~= nil then sequence_tuple = _space_sequence:get(space_id) - if (sequence or (sequence ~= false and sequence_tuple ~= nil)) and - #parts >= 1 and (parts[1].type or parts[1][2]) ~= 'integer' and - (parts[1].type or parts[1][2]) ~= 'unsigned' then - box.error(box.error.MODIFY_INDEX, options.name, space.name, - "sequence cannot be used with a non-integer key") + if sequence_tuple ~= nil then + -- Inherit omitted options from the attached sequence. + if sequence == nil then + sequence = sequence_tuple.sequence_id + sequence_is_generated = sequence_tuple.is_generated + end + if sequence and sequence_part == nil then + sequence_part = sequence_tuple.sequence_part + end end end + if sequence then + sequence_part = sequence_part or 1 + check_sequence_part(parts, sequence_part, options.name, space.name) + elseif sequence_part ~= nil then + box.error(box.error.MODIFY_INDEX, options.name, space.name, + "sequence part cannot be used without sequence") + end if sequence == true then if sequence_tuple == nil or sequence_tuple.is_generated == false then sequence = box.schema.sequence.create(space.name .. '_seq') sequence = sequence.id - sequence_is_generated = true else -- Space already has an automatically generated sequence. - sequence = nil + sequence = sequence_tuple.sequence_id end + sequence_is_generated = true elseif sequence then sequence = sequence_resolve(sequence) if sequence == nil then @@ -1065,8 +1096,11 @@ box.schema.index.alter = function(space_id, index_id, options) end _index:replace{space_id, index_id, options.name, options.type, index_opts, parts} - if sequence then - _space_sequence:replace{space_id, sequence, sequence_is_generated} + if sequence and (sequence_tuple == nil or + sequence_tuple.sequence_id ~= sequence or + sequence_tuple.sequence_part ~= sequence_part) then + _space_sequence:replace{space_id, sequence, sequence_is_generated, + sequence_part - 1} end if sequence ~= nil and sequence_tuple ~= nil and sequence_tuple.is_generated == true and diff --git a/src/box/lua/space.cc b/src/box/lua/space.cc index 100da0a7..e342bfcc 100644 --- a/src/box/lua/space.cc +++ b/src/box/lua/space.cc @@ -309,6 +309,13 @@ lbox_fillspace(struct lua_State *L, struct space *space, int i) */ lua_rawset(L, -3); + lua_pushstring(L, "sequence_part"); + if (k == 0 && space->sequence != NULL) + lua_pushnumber(L, space->sequence_part + 1); + else + lua_pushnil(L); + lua_rawset(L, -3); + if (space_is_vinyl(space)) { lua_pushstring(L, "options"); lua_newtable(L); diff --git a/src/box/lua/upgrade.lua b/src/box/lua/upgrade.lua index 89d6e3d5..23f4df01 100644 --- a/src/box/lua/upgrade.lua +++ b/src/box/lua/upgrade.lua @@ -625,8 +625,12 @@ local function upgrade_to_2_1_2() update_collation_strength_field() end +-------------------------------------------------------------------------------- +-- Tarantool 2.1.3 +-------------------------------------------------------------------------------- + -- Add new collations -local function upgrade_to_2_1_3() +local function upgrade_collation_to_2_1_3() local coll_lst = { {name="af", loc_str="af"}, -- Afrikaans {name="am", loc_str="am"}, -- Amharic (no character changes, just re-ordering) @@ -737,6 +741,34 @@ local function upgrade_to_2_1_3() end end +local function upgrade_to_2_1_3() + upgrade_collation_to_2_1_3() +end + +-------------------------------------------------------------------------------- +-- Tarantool 2.2.1 +-------------------------------------------------------------------------------- + +-- Add sequence part field to _space_sequence table +local function upgrade_sequence_to_2_2_1() + log.info("add key part field to space _space_sequence") + local _space_sequence = box.space[box.schema.SPACE_SEQUENCE_ID] + for _, v in _space_sequence:pairs() do + if #v == 3 then + _space_sequence:update(v[1], {{'!', 4, 0}}) + end + end + local format = _space_sequence:format() + format[4] = {name = 'part', type = 'unsigned'} + _space_sequence:format(format) +end + +local function upgrade_to_2_2_1() + upgrade_sequence_to_2_2_1() +end + +-------------------------------------------------------------------------------- + local function get_version() local version = box.space._schema:get{'version'} if version == nil then @@ -768,6 +800,7 @@ local function upgrade(options) {version = mkversion(2, 1, 1), func = upgrade_to_2_1_1, auto = true}, {version = mkversion(2, 1, 2), func = upgrade_to_2_1_2, auto = true}, {version = mkversion(2, 1, 3), func = upgrade_to_2_1_3, auto = true}, + {version = mkversion(2, 2, 1), func = upgrade_to_2_2_1, auto = true}, } for _, handler in ipairs(handlers) do diff --git a/src/box/request.c b/src/box/request.c index 44a43ee1..9d3287f9 100644 --- a/src/box/request.c +++ b/src/box/request.c @@ -163,7 +163,7 @@ request_handle_sequence(struct request *request, struct space *space) const char *data = request->tuple; const char *data_end = request->tuple_end; int len = mp_decode_array(&data); - int fieldno = pk->def->key_def->parts[0].fieldno; + int fieldno = pk->def->key_def->parts[space->sequence_part].fieldno; if (unlikely(len < fieldno + 1)) return 0; diff --git a/src/box/schema_def.h b/src/box/schema_def.h index eeeeb950..dea3fad1 100644 --- a/src/box/schema_def.h +++ b/src/box/schema_def.h @@ -216,6 +216,7 @@ enum { BOX_SPACE_SEQUENCE_FIELD_ID = 0, BOX_SPACE_SEQUENCE_FIELD_SEQUENCE_ID = 1, BOX_SPACE_SEQUENCE_FIELD_IS_GENERATED = 2, + BOX_SPACE_SEQUENCE_FIELD_PART = 3, }; /** _trigger fields. */ diff --git a/src/box/space.h b/src/box/space.h index 13a220d1..c3eef71c 100644 --- a/src/box/space.h +++ b/src/box/space.h @@ -176,6 +176,11 @@ struct space { struct space_def *def; /** Sequence attached to this space or NULL. */ struct sequence *sequence; + /** + * Auto increment part of the primary index. + * Makes sense only if sequence is set. + */ + uint32_t sequence_part; /** Enable/disable triggers. */ bool run_triggers; /** diff --git a/src/box/sql/build.c b/src/box/sql/build.c index 6051a252..91b977de 100644 --- a/src/box/sql/build.c +++ b/src/box/sql/build.c @@ -951,9 +951,14 @@ emitNewSysSpaceSequenceRecord(Parse *pParse, int space_id, const char reg_seq_id /* 2. Sequence id */ sqlVdbeAddOp2(v, OP_IntCopy, reg_seq_id, first_col + 2); + + /* 3. Autogenerated. */ sqlVdbeAddOp2(v, OP_Bool, true, first_col + 3); - sqlVdbeAddOp3(v, OP_MakeRecord, first_col + 1, 3, first_col); + /* 4. Part id. */ + sqlVdbeAddOp2(v, OP_Integer, 0, first_col + 4); + + sqlVdbeAddOp3(v, OP_MakeRecord, first_col + 1, 4, first_col); return first_col; } diff --git a/src/box/sql/insert.c b/src/box/sql/insert.c index c2aac553..1261ab9c 100644 --- a/src/box/sql/insert.c +++ b/src/box/sql/insert.c @@ -98,7 +98,7 @@ sql_space_autoinc_fieldno(struct space *space) if (pk == NULL || pk->def->key_def->part_count != 1 || space->sequence == NULL) return UINT32_MAX; - return pk->def->key_def->parts[0].fieldno; + return pk->def->key_def->parts[space->sequence_part].fieldno; } /** diff --git a/test/box-py/bootstrap.result b/test/box-py/bootstrap.result index 379f6c51..de90beee 100644 --- a/test/box-py/bootstrap.result +++ b/test/box-py/bootstrap.result @@ -4,7 +4,7 @@ box.internal.bootstrap() box.space._schema:select{} --- - - ['max_id', 511] - - ['version', 2, 1, 3] + - ['version', 2, 2, 1] ... box.space._cluster:select{} --- @@ -72,7 +72,8 @@ box.space._space:select{} - [330, 1, '_truncate', 'memtx', 0, {}, [{'name': 'id', 'type': 'unsigned'}, {'name': 'count', 'type': 'unsigned'}]] - [340, 1, '_space_sequence', 'memtx', 0, {}, [{'name': 'id', 'type': 'unsigned'}, - {'name': 'sequence_id', 'type': 'unsigned'}, {'name': 'is_generated', 'type': 'boolean'}]] + {'name': 'sequence_id', 'type': 'unsigned'}, {'name': 'is_generated', 'type': 'boolean'}, + {'name': 'part', 'type': 'unsigned'}]] - [356, 1, '_fk_constraint', 'memtx', 0, {}, [{'name': 'name', 'type': 'string'}, {'name': 'child_id', 'type': 'unsigned'}, {'name': 'parent_id', 'type': 'unsigned'}, {'name': 'is_deferred', 'type': 'boolean'}, {'name': 'match', 'type': 'string'}, diff --git a/test/box/access_misc.result b/test/box/access_misc.result index 36ebfae0..877a9b53 100644 --- a/test/box/access_misc.result +++ b/test/box/access_misc.result @@ -812,7 +812,8 @@ box.space._space:select() - [330, 1, '_truncate', 'memtx', 0, {}, [{'name': 'id', 'type': 'unsigned'}, {'name': 'count', 'type': 'unsigned'}]] - [340, 1, '_space_sequence', 'memtx', 0, {}, [{'name': 'id', 'type': 'unsigned'}, - {'name': 'sequence_id', 'type': 'unsigned'}, {'name': 'is_generated', 'type': 'boolean'}]] + {'name': 'sequence_id', 'type': 'unsigned'}, {'name': 'is_generated', 'type': 'boolean'}, + {'name': 'part', 'type': 'unsigned'}]] - [356, 1, '_fk_constraint', 'memtx', 0, {}, [{'name': 'name', 'type': 'string'}, {'name': 'child_id', 'type': 'unsigned'}, {'name': 'parent_id', 'type': 'unsigned'}, {'name': 'is_deferred', 'type': 'boolean'}, {'name': 'match', 'type': 'string'}, diff --git a/test/box/sequence.result b/test/box/sequence.result index 5eed0ef4..4f962347 100644 --- a/test/box/sequence.result +++ b/test/box/sequence.result @@ -590,6 +590,48 @@ s:create_index('pk', {parts = {1, 'number'}, sequence = 'test'}) -- error - error: 'Can''t create or modify index ''pk'' in space ''test'': sequence cannot be used with a non-integer key' ... +s:create_index('pk', {sequence_part = 1}) -- error +--- +- error: 'Can''t create or modify index ''nil'' in space ''test'': sequence part cannot + be used without sequence' +... +s:create_index('pk', {sequence = true, sequence_part = 2}) -- error +--- +- error: 'Can''t create or modify index ''pk'' in space ''test'': sequence part is + out of bounds' +... +s:create_index('pk', {parts = {1, 'unsigned', 2, 'string'}, sequence = true, sequence_part = 2}) -- error +--- +- error: 'Can''t create or modify index ''pk'' in space ''test'': sequence cannot + be used with a non-integer key' +... +pk = s:create_index('pk', {parts = {1, 'string', 2, 'unsigned'}}) -- ok +--- +... +pk:alter{sequence_part = 1} -- error +--- +- error: 'Can''t create or modify index ''pk'' in space ''test'': sequence part cannot + be used without sequence' +... +pk:alter{sequence = true, sequence_part = 1} -- error +--- +- error: 'Can''t create or modify index ''pk'' in space ''test'': sequence cannot + be used with a non-integer key' +... +pk:alter{sequence = true, sequence_part = 2} -- ok +--- +... +pk:alter{sequence = false, sequence_part = 2} -- error +--- +- error: 'Can''t create or modify index ''pk'' in space ''test'': sequence part cannot + be used without sequence' +... +pk:alter{sequence = false} -- ok +--- +... +pk:drop() +--- +... pk = s:create_index('pk', {parts = {1, 'integer'}, sequence = 'test'}) -- ok --- ... @@ -615,6 +657,11 @@ s:create_index('secondary', {parts = {2, 'unsigned'}, sequence = true}) -- error - error: 'Can''t create or modify index ''secondary'' in space ''test'': sequence cannot be used with a secondary key' ... +s:create_index('secondary', {parts = {2, 'unsigned'}, sequence_part = 1}) -- error +--- +- error: 'Can''t create or modify index ''nil'' in space ''test'': sequence part cannot + be used without sequence' +... sk = s:create_index('secondary', {parts = {2, 'unsigned'}}) -- ok --- ... @@ -700,18 +747,23 @@ sk:alter{sequence = 'test'} -- error - error: 'Can''t create or modify index ''sk'' in space ''test'': sequence cannot be used with a secondary key' ... -box.space._space_sequence:insert{s.id, sq.id, false} -- error +box.space._space_sequence:insert{s.id, sq.id, false, 0} -- error --- - error: 'Can''t create or modify index ''pk'' in space ''test'': sequence cannot be used with a non-integer key' ... +box.space._space_sequence:insert{s.id, sq.id, false, 2} -- error +--- +- error: 'Can''t create or modify index ''pk'' in space ''test'': sequence part is + out of bounds' +... sk:drop() --- ... pk:drop() --- ... -box.space._space_sequence:insert{s.id, sq.id, false} -- error +box.space._space_sequence:insert{s.id, sq.id, false, 0} -- error --- - error: 'No index #0 is defined in space ''test''' ... @@ -1121,7 +1173,7 @@ _ = s2:create_index('pk', {sequence = 'test1_seq'}) -- error --- - error: 'Can''t modify space ''test2'': can not attach generated sequence' ... -box.space._space_sequence:insert{s2.id, box.sequence.test1_seq.id, false} -- error +box.space._space_sequence:insert{s2.id, box.sequence.test1_seq.id, false, 0} -- error --- - error: 'Can''t modify space ''test2'': can not attach generated sequence' ... @@ -1612,15 +1664,15 @@ s1.index.pk:alter({sequence = 'seq1'}) -- error --- - error: Alter access to space 'space1' is denied for user 'user' ... -box.space._space_sequence:replace{s1.id, sq1.id, false} -- error +box.space._space_sequence:replace{s1.id, sq1.id, false, 0} -- error --- - error: Read access to sequence 'seq1' is denied for user 'user' ... -box.space._space_sequence:replace{s1.id, sq2.id, false} -- error +box.space._space_sequence:replace{s1.id, sq2.id, false, 0} -- error --- - error: Alter access to space 'space1' is denied for user 'user' ... -box.space._space_sequence:replace{s2.id, sq1.id, false} -- error +box.space._space_sequence:replace{s2.id, sq1.id, false, 0} -- error --- - error: Read access to sequence 'seq1' is denied for user 'user' ... @@ -1904,3 +1956,80 @@ sequence_id == s.index.pk.sequence_id s:drop() --- ... +-- +-- gh-4009: setting sequence for an index part other than the first. +-- +s = box.schema.space.create('test') +--- +... +_ = s:create_index('pk', {parts = {1, 'string', 2, 'unsigned', 3, 'unsigned'}, sequence = true, sequence_part = 2}) +--- +... +sequence_id = s.index.pk.sequence_id +--- +... +sequence_id ~= nil +--- +- true +... +s.index.pk.sequence_part == 2 +--- +- true +... +s:insert{'a', box.null, 1} +--- +- ['a', 1, 1] +... +s:insert{'a', box.null, 2} +--- +- ['a', 2, 2] +... +s:insert{'b', 10, 10} +--- +- ['b', 10, 10] +... +s:insert{'b', box.null, 11} +--- +- ['b', 11, 11] +... +s.index.pk:alter{sequence_part = 3} +--- +... +s.index.pk.sequence_part == 3 +--- +- true +... +s.index.pk.sequence_id == sequence_id +--- +- true +... +s:insert{'c', 100, 100, 'x'} +--- +- ['c', 100, 100, 'x'] +... +s:insert{'c', 101, box.null, 'y'} +--- +- ['c', 101, 101, 'y'] +... +s.index.pk:alter{sequence = true, sequence_part = 2} +--- +... +s.index.pk.sequence_part == 2 +--- +- true +... +s.index.pk.sequence_id == sequence_id +--- +- true +... +s:insert{'d', 1000, 1000} +--- +- ['d', 1000, 1000] +... +s:insert{'d', box.null, 1001} +--- +- ['d', 1001, 1001] +... +s:drop() +--- +... diff --git a/test/box/sequence.test.lua b/test/box/sequence.test.lua index 6459419e..d419e369 100644 --- a/test/box/sequence.test.lua +++ b/test/box/sequence.test.lua @@ -196,6 +196,18 @@ s:create_index('pk', {parts = {1, 'string'}, sequence = 'test'}) -- error s:create_index('pk', {parts = {1, 'scalar'}, sequence = 'test'}) -- error s:create_index('pk', {parts = {1, 'number'}, sequence = 'test'}) -- error +s:create_index('pk', {sequence_part = 1}) -- error +s:create_index('pk', {sequence = true, sequence_part = 2}) -- error +s:create_index('pk', {parts = {1, 'unsigned', 2, 'string'}, sequence = true, sequence_part = 2}) -- error + +pk = s:create_index('pk', {parts = {1, 'string', 2, 'unsigned'}}) -- ok +pk:alter{sequence_part = 1} -- error +pk:alter{sequence = true, sequence_part = 1} -- error +pk:alter{sequence = true, sequence_part = 2} -- ok +pk:alter{sequence = false, sequence_part = 2} -- error +pk:alter{sequence = false} -- ok +pk:drop() + pk = s:create_index('pk', {parts = {1, 'integer'}, sequence = 'test'}) -- ok pk:drop() pk = s:create_index('pk', {parts = {1, 'unsigned'}, sequence = 'test'}) -- ok @@ -204,6 +216,7 @@ pk:drop() pk = s:create_index('pk') -- ok s:create_index('secondary', {parts = {2, 'unsigned'}, sequence = 'test'}) -- error s:create_index('secondary', {parts = {2, 'unsigned'}, sequence = true}) -- error +s:create_index('secondary', {parts = {2, 'unsigned'}, sequence_part = 1}) -- error sk = s:create_index('secondary', {parts = {2, 'unsigned'}}) -- ok sk:alter{sequence = 'test'} -- error sk:alter{sequence = true} -- error @@ -227,10 +240,11 @@ box.space._index:delete{s.id, pk.id} -- error pk:alter{parts = {1, 'string'}, sequence = false} -- ok sk = s:create_index('sk', {parts = {2, 'unsigned'}}) sk:alter{sequence = 'test'} -- error -box.space._space_sequence:insert{s.id, sq.id, false} -- error +box.space._space_sequence:insert{s.id, sq.id, false, 0} -- error +box.space._space_sequence:insert{s.id, sq.id, false, 2} -- error sk:drop() pk:drop() -box.space._space_sequence:insert{s.id, sq.id, false} -- error +box.space._space_sequence:insert{s.id, sq.id, false, 0} -- error s:create_index('pk', {sequence = {}}) -- error s:create_index('pk', {sequence = 'abc'}) -- error @@ -358,7 +372,7 @@ s1 = box.schema.space.create('test1') _ = s1:create_index('pk', {sequence = true}) s2 = box.schema.space.create('test2') _ = s2:create_index('pk', {sequence = 'test1_seq'}) -- error -box.space._space_sequence:insert{s2.id, box.sequence.test1_seq.id, false} -- error +box.space._space_sequence:insert{s2.id, box.sequence.test1_seq.id, false, 0} -- error s1:drop() s2:drop() @@ -538,9 +552,9 @@ box.schema.user.grant('user', 'read', 'space', '_space_sequence') box.session.su('user') _ = s2:create_index('pk', {sequence = 'seq1'}) -- error s1.index.pk:alter({sequence = 'seq1'}) -- error -box.space._space_sequence:replace{s1.id, sq1.id, false} -- error -box.space._space_sequence:replace{s1.id, sq2.id, false} -- error -box.space._space_sequence:replace{s2.id, sq1.id, false} -- error +box.space._space_sequence:replace{s1.id, sq1.id, false, 0} -- error +box.space._space_sequence:replace{s1.id, sq2.id, false, 0} -- error +box.space._space_sequence:replace{s2.id, sq1.id, false, 0} -- error s2.index.pk:alter({sequence = 'seq2'}) -- ok box.session.su('admin') @@ -647,3 +661,27 @@ s.index.pk.parts[1].type s.index.pk:alter{sequence = true} sequence_id == s.index.pk.sequence_id s:drop() + +-- +-- gh-4009: setting sequence for an index part other than the first. +-- +s = box.schema.space.create('test') +_ = s:create_index('pk', {parts = {1, 'string', 2, 'unsigned', 3, 'unsigned'}, sequence = true, sequence_part = 2}) +sequence_id = s.index.pk.sequence_id +sequence_id ~= nil +s.index.pk.sequence_part == 2 +s:insert{'a', box.null, 1} +s:insert{'a', box.null, 2} +s:insert{'b', 10, 10} +s:insert{'b', box.null, 11} +s.index.pk:alter{sequence_part = 3} +s.index.pk.sequence_part == 3 +s.index.pk.sequence_id == sequence_id +s:insert{'c', 100, 100, 'x'} +s:insert{'c', 101, box.null, 'y'} +s.index.pk:alter{sequence = true, sequence_part = 2} +s.index.pk.sequence_part == 2 +s.index.pk.sequence_id == sequence_id +s:insert{'d', 1000, 1000} +s:insert{'d', box.null, 1001} +s:drop() -- 2.11.0
next prev parent reply other threads:[~2019-05-15 10:33 UTC|newest] Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top 2019-05-15 10:33 [PATCH 0/4] A few fixes/improvements for autoincrement indexes Vladimir Davydov 2019-05-15 10:33 ` [PATCH 1/4] schema: use tuple field names in Lua Vladimir Davydov 2019-05-15 10:33 ` [PATCH 2/4] schema: fix error while altering index with sequence Vladimir Davydov 2019-05-16 7:45 ` [tarantool-patches] " Konstantin Osipov 2019-05-15 10:33 ` Vladimir Davydov [this message] 2019-05-16 7:45 ` [tarantool-patches] Re: [PATCH 3/4] schema: allow to set sequence for any index part, not just the first Konstantin Osipov 2019-05-16 8:02 ` Vladimir Davydov 2019-05-15 10:33 ` [PATCH 4/4] schema: explicitly forbid setting sequence for json path key part Vladimir Davydov 2019-05-15 13:00 ` [tarantool-patches] " Konstantin Osipov 2019-05-15 13:11 ` Vladimir Davydov 2019-05-15 13:16 ` Vladimir Davydov 2019-05-15 13:44 ` [PATCH] box: fix autoincrement for json path indexes Vladimir Davydov 2019-05-16 7:42 ` [tarantool-patches] " Konstantin Osipov 2019-05-21 13:28 ` Vladimir Davydov 2019-05-21 10:42 ` [tarantool-patches] Re: [PATCH 0/4] A few fixes/improvements for autoincrement indexes Kirill Yukhin 2019-05-21 14:58 ` Konstantin Osipov 2019-05-21 16:02 ` Kirill Yukhin
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=924606cabe248b6d1cb8fb126de2c5638537398d.1557916311.git.vdavydov.dev@gmail.com \ --to=vdavydov.dev@gmail.com \ --cc=tarantool-patches@freelists.org \ --subject='Re: [PATCH 3/4] schema: allow to set sequence for any index part, not just the first' \ /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