* [PATCH 0/4] A few fixes/improvements for autoincrement indexes
@ 2019-05-15 10:33 Vladimir Davydov
2019-05-15 10:33 ` [PATCH 1/4] schema: use tuple field names in Lua Vladimir Davydov
` (4 more replies)
0 siblings, 5 replies; 17+ messages in thread
From: Vladimir Davydov @ 2019-05-15 10:33 UTC (permalink / raw)
To: tarantool-patches
See comments to individual patches for more details.
https://github.com/tarantool/tarantool/issues/4009
https://github.com/tarantool/tarantool/issues/4210
https://github.com/tarantool/tarantool/issues/4214
https://github.com/tarantool/tarantool/commits/dv/sequence-fixes
Vladimir Davydov (4):
schema: use tuple field names in Lua
schema: fix error while altering index with sequence
schema: allow to set sequence for any index part, not just the first
schema: explicitly forbid setting sequence for json path key part
src/box/alter.cc | 33 +++++-
src/box/bootstrap.snap | Bin 4374 -> 4379 bytes
src/box/lua/schema.lua | 171 ++++++++++++++++++------------
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/alter.result | 15 ---
test/box/alter.test.lua | 6 --
test/box/sequence.result | 243 +++++++++++++++++++++++++++++++++++++++++--
test/box/sequence.test.lua | 83 +++++++++++++--
16 files changed, 507 insertions(+), 111 deletions(-)
--
2.11.0
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH 1/4] schema: use tuple field names in Lua
2019-05-15 10:33 [PATCH 0/4] A few fixes/improvements for autoincrement indexes Vladimir Davydov
@ 2019-05-15 10:33 ` Vladimir Davydov
2019-05-15 10:33 ` [PATCH 2/4] schema: fix error while altering index with sequence Vladimir Davydov
` (3 subsequent siblings)
4 siblings, 0 replies; 17+ messages in thread
From: Vladimir Davydov @ 2019-05-15 10:33 UTC (permalink / raw)
To: tarantool-patches
When schema.lua was introduced, there was no such thing as space format
and we had to access tuple fields by no. Now we can use human readable
names. Let's do it - this should improve code readability.
A note about box/alter.test.lua: for some reason it clears format of
_space and _index system spaces, which apparently breaks our assumption
about field names. Let's zap those pointless test cases.
---
src/box/lua/schema.lua | 98 ++++++++++++++++++++++++-------------------------
test/box/alter.result | 15 --------
test/box/alter.test.lua | 6 ---
3 files changed, 49 insertions(+), 70 deletions(-)
diff --git a/src/box/lua/schema.lua b/src/box/lua/schema.lua
index f31cf7f2..036e5f2d 100644
--- a/src/box/lua/schema.lua
+++ b/src/box/lua/schema.lua
@@ -155,7 +155,7 @@ local function user_or_role_resolve(user)
if tuple == nil then
return nil
end
- return tuple[1]
+ return tuple.id
end
local function role_resolve(name_or_id)
@@ -166,10 +166,10 @@ local function role_resolve(name_or_id)
elseif type(name_or_id) ~= 'nil' then
tuple = _vuser:get{name_or_id}
end
- if tuple == nil or tuple[4] ~= 'role' then
+ if tuple == nil or tuple.type ~= 'role' then
return nil
else
- return tuple[1]
+ return tuple.id
end
end
@@ -181,10 +181,10 @@ local function user_resolve(name_or_id)
elseif type(name_or_id) ~= 'nil' then
tuple = _vuser:get{name_or_id}
end
- if tuple == nil or tuple[4] ~= 'user' then
+ if tuple == nil or tuple.type ~= 'user' then
return nil
else
- return tuple[1]
+ return tuple.id
end
end
@@ -197,7 +197,7 @@ local function sequence_resolve(name_or_id)
tuple = _vsequence:get{name_or_id}
end
if tuple ~= nil then
- return tuple[1], tuple
+ return tuple.id, tuple
else
return nil
end
@@ -209,7 +209,7 @@ local function revoke_object_privs(object_type, object_id)
local _priv = box.space[box.schema.PRIV_ID]
local privs = _vpriv.index.object:select{object_type, object_id}
for k, tuple in pairs(privs) do
- local uid = tuple[2]
+ local uid = tuple.grantee
_priv:delete{uid, object_type, object_id}
end
end
@@ -453,13 +453,13 @@ box.schema.space.create = function(name, options)
local _schema = box.space._schema
local max_id = _schema:update({'max_id'}, {{'+', 2, 1}})
if max_id == nil then
- id = _space.index.primary:max()[1]
+ id = _space.index.primary:max().id
if id < box.schema.SYSTEM_ID_MAX then
id = box.schema.SYSTEM_ID_MAX
end
max_id = _schema:insert{'max_id', id + 1}
end
- id = max_id[2]
+ id = max_id.value
end
local uid = session.euid()
if options.user then
@@ -492,7 +492,7 @@ function box.schema.space.format(id, format)
if tuple == nil then
box.error(box.error.NO_SUCH_SPACE, '#' .. tostring(id))
end
- return tuple[7]
+ return tuple.format
else
check_param(format, 'format', 'table')
format = update_format(format)
@@ -514,9 +514,9 @@ box.schema.space.drop = function(space_id, space_name, opts)
local _space_sequence = box.space[box.schema.SPACE_SEQUENCE_ID]
local _fk_constraint = box.space[box.schema.FK_CONSTRAINT_ID]
local sequence_tuple = _space_sequence:delete{space_id}
- if sequence_tuple ~= nil and sequence_tuple[3] == true then
+ if sequence_tuple ~= nil and sequence_tuple.is_generated == true then
-- Delete automatically generated sequence.
- box.schema.sequence.drop(sequence_tuple[2])
+ box.schema.sequence.drop(sequence_tuple.sequence_id)
end
for _, t in _trigger.index.space_id:pairs({space_id}) do
_trigger:delete({t.name})
@@ -527,7 +527,7 @@ box.schema.space.drop = function(space_id, space_name, opts)
local keys = _vindex:select(space_id)
for i = #keys, 1, -1 do
local v = keys[i]
- _index:delete{v[1], v[2]}
+ _index:delete{v.id, v.iid}
end
revoke_object_privs('space', space_id)
_truncate:delete{space_id}
@@ -847,9 +847,9 @@ box.schema.index.create = function(space_id, name, options)
local tuple = _vindex.index[0]
:select(space_id, { limit = 1, iterator = 'LE' })[1]
if tuple then
- local id = tuple[1]
+ local id = tuple.id
if id == space_id then
- iid = tuple[2] + 1
+ iid = tuple.iid + 1
end
end
end
@@ -923,9 +923,9 @@ box.schema.index.drop = function(space_id, index_id)
if index_id == 0 then
local _space_sequence = box.space[box.schema.SPACE_SEQUENCE_ID]
local sequence_tuple = _space_sequence:delete{space_id}
- if sequence_tuple ~= nil and sequence_tuple[3] == true then
+ if sequence_tuple ~= nil and sequence_tuple.is_generated == true then
-- Delete automatically generated sequence.
- box.schema.sequence.drop(sequence_tuple[2])
+ box.schema.sequence.drop(sequence_tuple.sequence_id)
end
end
local _index = box.space[box.schema.INDEX_ID]
@@ -993,25 +993,23 @@ box.schema.index.alter = function(space_id, index_id, options)
local tuple = _index:get{space_id, index_id }
local parts = {}
local index_opts = {}
- local OPTS = 5
- local PARTS = 6
- if type(tuple[OPTS]) == 'number' then
+ if type(tuple.opts) == 'number' then
-- old format
- index_opts.unique = tuple[OPTS] == 1
- local part_count = tuple[PARTS]
+ index_opts.unique = tuple[5] == 1
+ local part_count = tuple[6]
for i = 1, part_count do
table.insert(parts, {tuple[2 * i + 4], tuple[2 * i + 5]});
end
else
-- new format
- index_opts = tuple[OPTS]
- parts = tuple[PARTS]
+ index_opts = tuple.opts
+ parts = tuple.parts
end
if options.name == nil then
- options.name = tuple[3]
+ options.name = tuple.name
end
if options.type == nil then
- options.type = tuple[4]
+ options.type = tuple.type
end
for k, t in pairs(index_options) do
if options[k] ~= nil then
@@ -1048,7 +1046,7 @@ box.schema.index.alter = function(space_id, index_id, options)
end
end
if sequence == true then
- if sequence_tuple == nil or sequence_tuple[3] == false 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
@@ -1070,10 +1068,10 @@ box.schema.index.alter = function(space_id, index_id, options)
if sequence then
_space_sequence:replace{space_id, sequence, sequence_is_generated}
end
- if sequence_tuple ~= nil and sequence_tuple[3] == true and
- sequence_tuple[2] ~= sequence then
+ if sequence_tuple ~= nil and sequence_tuple.is_generated == true and
+ sequence_tuple.sequence_id ~= sequence then
-- Delete automatically generated sequence.
- box.schema.sequence.drop(sequence_tuple[2])
+ box.schema.sequence.drop(sequence_tuple.sequence_id)
end
end
@@ -1662,13 +1660,13 @@ end
local function sequence_on_alter(old_tuple, new_tuple)
if old_tuple and not new_tuple then
- local old_name = old_tuple[3]
+ local old_name = old_tuple.name
box.sequence[old_name] = nil
elseif not old_tuple and new_tuple then
local seq = sequence_new(new_tuple)
box.sequence[seq.name] = seq
else
- local old_name = old_tuple[3]
+ local old_name = old_tuple.name
local seq = box.sequence[old_name]
if not seq then
seq = sequence_new(seq, new_tuple)
@@ -1919,7 +1917,7 @@ local function object_resolve(object_type, object_name)
func = _vfunc:get{object_name}
end
if func then
- return func[1]
+ return func.id
else
box.error(box.error.NO_SUCH_FUNCTION, object_name)
end
@@ -1945,8 +1943,8 @@ local function object_resolve(object_type, object_name)
else
role_or_user = _vuser:get{object_name}
end
- if role_or_user and role_or_user[4] == object_type then
- return role_or_user[1]
+ if role_or_user and role_or_user.type == object_type then
+ return role_or_user.id
elseif object_type == 'role' then
box.error(box.error.NO_SUCH_ROLE, object_name)
else
@@ -1973,7 +1971,7 @@ local function object_name(object_type, object_id)
else
box.error(box.error.UNKNOWN_SCHEMA_OBJECT, object_type)
end
- return space:get{object_id}[3]
+ return space:get{object_id}.name
end
box.schema.func = {}
@@ -2010,7 +2008,7 @@ box.schema.func.drop = function(name, opts)
tuple = _vfunc:get{name}
end
if tuple then
- fid = tuple[1]
+ fid = tuple.id
end
if fid == nil then
if not opts.if_exists then
@@ -2096,7 +2094,7 @@ end
box.internal.collation.id_by_name = function(name)
local _coll = box.space[box.schema.COLLATION_ID]
local coll = _coll.index.name:get{name}
- return coll[1]
+ return coll.id
end
box.schema.user = {}
@@ -2148,7 +2146,7 @@ box.schema.user.create = function(name, opts)
auth_mech_list["chap-sha1"] = box.schema.user.password(opts.password)
end
local _user = box.space[box.schema.USER_ID]
- uid = _user:auto_increment{session.euid(), name, 'user', auth_mech_list}[1]
+ uid = _user:auto_increment{session.euid(), name, 'user', auth_mech_list}.id
-- grant role 'public' to the user
box.schema.user.grant(uid, 'public')
-- Grant privilege 'alter' on itself, so that it can
@@ -2201,7 +2199,7 @@ local function grant(uid, name, privilege, object_type,
local tuple = _vpriv:get{uid, object_type, oid}
local old_privilege
if tuple ~= nil then
- old_privilege = tuple[5]
+ old_privilege = tuple.privilege
else
old_privilege = 0
end
@@ -2255,8 +2253,8 @@ local function revoke(uid, name, privilege, object_type, object_name, options)
object_type, object_name)
end
end
- local old_privilege = tuple[5]
- local grantor = tuple[1]
+ local old_privilege = tuple.privilege
+ local grantor = tuple.grantor
-- sic:
-- a user may revoke more than he/she granted
-- (erroneous user input)
@@ -2282,25 +2280,25 @@ local function drop(uid, opts)
local _vpriv = box.space[box.schema.VPRIV_ID]
local spaces = box.space[box.schema.VSPACE_ID].index.owner:select{uid}
for k, tuple in pairs(spaces) do
- box.space[tuple[1]]:drop()
+ box.space[tuple.id]:drop()
end
local funcs = box.space[box.schema.VFUNC_ID].index.owner:select{uid}
for k, tuple in pairs(funcs) do
- box.schema.func.drop(tuple[1])
+ box.schema.func.drop(tuple.id)
end
-- if this is a role, revoke this role from whoever it was granted to
local grants = _vpriv.index.object:select{'role', uid}
for k, tuple in pairs(grants) do
- revoke(tuple[2], tuple[2], uid)
+ revoke(tuple.grantee, tuple.grantee, uid)
end
local sequences = box.space[box.schema.VSEQUENCE_ID].index.owner:select{uid}
for k, tuple in pairs(sequences) do
- box.schema.sequence.drop(tuple[1])
+ box.schema.sequence.drop(tuple.id)
end
-- xxx: hack, we have to revoke session and usage privileges
-- of a user using a setuid function in absence of create/drop
-- privileges and grant option
- if box.space._vuser:get{uid}[4] == 'user' then
+ if box.space._vuser:get{uid}.type == 'user' then
box.session.su('admin', box.schema.user.revoke, uid,
'session,usage', 'universe', nil, {if_exists = true})
end
@@ -2309,7 +2307,8 @@ local function drop(uid, opts)
for k, tuple in pairs(privs) do
-- we need an additional box.session.su() here, because of
-- unnecessary check for privilege PRIV_REVOKE in priv_def_check()
- box.session.su("admin", revoke, uid, uid, tuple[5], tuple[3], tuple[4])
+ box.session.su("admin", revoke, uid, uid, tuple.privilege,
+ tuple.object_type, tuple.object_id)
end
box.space[box.schema.USER_ID]:delete{uid}
end
@@ -2369,7 +2368,8 @@ local function info(id)
for _, v in pairs(_priv:select{id}) do
table.insert(
privs,
- {privilege_name(v[5]), v[3], object_name(v[3], v[4])}
+ {privilege_name(v.privilege), v.object_type,
+ object_name(v.object_type, v.object_id)}
)
end
return privs
diff --git a/test/box/alter.result b/test/box/alter.result
index c1b1de13..75d6dae2 100644
--- a/test/box/alter.result
+++ b/test/box/alter.result
@@ -52,25 +52,10 @@ _space:insert{_space.id, ADMIN, '_space', 'memtx', 0, EMPTY_MAP, {}}
---
- error: Duplicate key exists in unique index 'primary' in space '_space'
...
-_space:replace{_space.id, ADMIN, '_space', 'memtx', 0, EMPTY_MAP, {}}
----
-- [280, 1, '_space', 'memtx', 0, {}, []]
-...
_space:insert{_index.id, ADMIN, '_index', 'memtx', 0, EMPTY_MAP, {}}
---
- error: Duplicate key exists in unique index 'primary' in space '_space'
...
-_space:replace{_index.id, ADMIN, '_index', 'memtx', 0, EMPTY_MAP, {}}
----
-- [288, 1, '_index', 'memtx', 0, {}, []]
-...
---
--- Can't change properties of a space
---
-_space:replace{_space.id, ADMIN, '_space', 'memtx', 0, EMPTY_MAP, {}}
----
-- [280, 1, '_space', 'memtx', 0, {}, []]
-...
--
-- Can't drop a system space
--
diff --git a/test/box/alter.test.lua b/test/box/alter.test.lua
index 733d27c5..3cb0c4f8 100644
--- a/test/box/alter.test.lua
+++ b/test/box/alter.test.lua
@@ -24,13 +24,7 @@ _space:insert{_space.id, ADMIN, 'test', 'world', 0, EMPTY_MAP, {}}
-- There is already a tuple for the system space
--
_space:insert{_space.id, ADMIN, '_space', 'memtx', 0, EMPTY_MAP, {}}
-_space:replace{_space.id, ADMIN, '_space', 'memtx', 0, EMPTY_MAP, {}}
_space:insert{_index.id, ADMIN, '_index', 'memtx', 0, EMPTY_MAP, {}}
-_space:replace{_index.id, ADMIN, '_index', 'memtx', 0, EMPTY_MAP, {}}
---
--- Can't change properties of a space
---
-_space:replace{_space.id, ADMIN, '_space', 'memtx', 0, EMPTY_MAP, {}}
--
-- Can't drop a system space
--
--
2.11.0
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH 2/4] schema: fix error while altering index with sequence
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 ` Vladimir Davydov
2019-05-16 7:45 ` [tarantool-patches] " Konstantin Osipov
2019-05-15 10:33 ` [PATCH 3/4] schema: allow to set sequence for any index part, not just the first Vladimir Davydov
` (2 subsequent siblings)
4 siblings, 1 reply; 17+ messages in thread
From: Vladimir Davydov @ 2019-05-15 10:33 UTC (permalink / raw)
To: tarantool-patches
A check was missing in index.alter. This resulted in an attempt to drop
the sequence attached to the altered index even if the sequence was not
modified.
Closes #4214
---
src/box/lua/schema.lua | 3 ++-
test/box/sequence.result | 33 +++++++++++++++++++++++++++++++++
test/box/sequence.test.lua | 13 +++++++++++++
3 files changed, 48 insertions(+), 1 deletion(-)
diff --git a/src/box/lua/schema.lua b/src/box/lua/schema.lua
index 036e5f2d..14ad4de1 100644
--- a/src/box/lua/schema.lua
+++ b/src/box/lua/schema.lua
@@ -1068,7 +1068,8 @@ box.schema.index.alter = function(space_id, index_id, options)
if sequence then
_space_sequence:replace{space_id, sequence, sequence_is_generated}
end
- if sequence_tuple ~= nil and sequence_tuple.is_generated == true and
+ if sequence ~= nil and sequence_tuple ~= nil and
+ sequence_tuple.is_generated == true and
sequence_tuple.sequence_id ~= sequence then
-- Delete automatically generated sequence.
box.schema.sequence.drop(sequence_tuple.sequence_id)
diff --git a/test/box/sequence.result b/test/box/sequence.result
index b3907659..5eed0ef4 100644
--- a/test/box/sequence.result
+++ b/test/box/sequence.result
@@ -1871,3 +1871,36 @@ test_run:cmd("setopt delimiter ''");
---
- true
...
+--
+-- gh-4214: error while altering an index with attached sequence.
+--
+s = box.schema.space.create('test')
+---
+...
+_ = s:create_index('pk', {sequence = true})
+---
+...
+sequence_id = s.index.pk.sequence_id
+---
+...
+sequence_id ~= nil
+---
+- true
+...
+s.index.pk:alter{parts = {1, 'integer'}}
+---
+...
+s.index.pk.parts[1].type
+---
+- integer
+...
+s.index.pk:alter{sequence = true}
+---
+...
+sequence_id == s.index.pk.sequence_id
+---
+- true
+...
+s:drop()
+---
+...
diff --git a/test/box/sequence.test.lua b/test/box/sequence.test.lua
index 96297d6f..6459419e 100644
--- a/test/box/sequence.test.lua
+++ b/test/box/sequence.test.lua
@@ -634,3 +634,16 @@ identifier.run_test(
function (identifier) box.schema.sequence.drop(identifier) end
);
test_run:cmd("setopt delimiter ''");
+
+--
+-- gh-4214: error while altering an index with attached sequence.
+--
+s = box.schema.space.create('test')
+_ = s:create_index('pk', {sequence = true})
+sequence_id = s.index.pk.sequence_id
+sequence_id ~= nil
+s.index.pk:alter{parts = {1, 'integer'}}
+s.index.pk.parts[1].type
+s.index.pk:alter{sequence = true}
+sequence_id == s.index.pk.sequence_id
+s:drop()
--
2.11.0
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH 3/4] schema: allow to set sequence for any index part, not just the first
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-15 10:33 ` Vladimir Davydov
2019-05-16 7:45 ` [tarantool-patches] " Konstantin Osipov
2019-05-15 10:33 ` [PATCH 4/4] schema: explicitly forbid setting sequence for json path key part Vladimir Davydov
2019-05-21 10:42 ` [tarantool-patches] Re: [PATCH 0/4] A few fixes/improvements for autoincrement indexes Kirill Yukhin
4 siblings, 1 reply; 17+ messages in thread
From: Vladimir Davydov @ 2019-05-15 10:33 UTC (permalink / raw)
To: tarantool-patches
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
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH 4/4] schema: explicitly forbid setting sequence for json path key part
2019-05-15 10:33 [PATCH 0/4] A few fixes/improvements for autoincrement indexes Vladimir Davydov
` (2 preceding siblings ...)
2019-05-15 10:33 ` [PATCH 3/4] schema: allow to set sequence for any index part, not just the first Vladimir Davydov
@ 2019-05-15 10:33 ` Vladimir Davydov
2019-05-15 13:00 ` [tarantool-patches] " Konstantin Osipov
2019-05-21 10:42 ` [tarantool-patches] Re: [PATCH 0/4] A few fixes/improvements for autoincrement indexes Kirill Yukhin
4 siblings, 1 reply; 17+ messages in thread
From: Vladimir Davydov @ 2019-05-15 10:33 UTC (permalink / raw)
To: tarantool-patches
When a space has a sequence, we substitute NULL in the corresponding
primary index part with the next value generated by the sequence. We do
this by patching raw msgpack, see request_handle_sequence. The problem
is we can't do it easily if the field is nested. For example, consider
field [1].a.b. In Lua it is impossible to create tuple {{a = {b = nil}}}
so we would need to restore the whole path from an empty tuple. This
isn't trivial to do. Let's forbid it for now as nobody has requested
this feature yet.
See #4210
@TarantoolBot document
Title: Document that a sequence can't be used with json path key part
This will result in index create/alter error:
```
box.schema.space.create('test')
box.space.test:create_index('primary', {
parts = {{'[1][1]', 'unsigned'}},
sequence = true
})
```
One can set a sequence for a plain part of a json path index though,
i.e. this is okay:
```
box.schema.space.create('test')
box.space.test:create_index('primary', {
parts = {{'[1][1]', 'unsigned'}, {2, 'unsigned}},
sequence = true, sequence_part = 2
})
```
---
src/box/alter.cc | 8 +++++-
src/box/lua/schema.lua | 4 +++
test/box/sequence.result | 69 ++++++++++++++++++++++++++++++++++++++++++++++
test/box/sequence.test.lua | 20 ++++++++++++++
4 files changed, 100 insertions(+), 1 deletion(-)
diff --git a/src/box/alter.cc b/src/box/alter.cc
index 2d43a9d2..a07a0845 100644
--- a/src/box/alter.cc
+++ b/src/box/alter.cc
@@ -131,7 +131,13 @@ index_def_check_sequence(struct index_def *index_def, uint32_t sequence_part,
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;
+ struct key_part *part = &index_def->key_def->parts[sequence_part];
+ if (part->path != NULL) {
+ tnt_raise(ClientError, ER_MODIFY_INDEX, index_def->name,
+ space_name, "sequence cannot be used with "
+ "a json path key");
+ }
+ enum field_type type = 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 "
diff --git a/src/box/lua/schema.lua b/src/box/lua/schema.lua
index 91900395..8f54f444 100644
--- a/src/box/lua/schema.lua
+++ b/src/box/lua/schema.lua
@@ -755,6 +755,10 @@ local function check_sequence_part(parts, sequence_part,
"sequence part is out of bounds")
end
sequence_part = parts[sequence_part]
+ if sequence_part.path ~= nil then
+ box.error(box.error.MODIFY_INDEX, index_name, space_name,
+ "sequence cannot be used with a json path key")
+ end
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,
diff --git a/test/box/sequence.result b/test/box/sequence.result
index 4f962347..5d2d8a4f 100644
--- a/test/box/sequence.result
+++ b/test/box/sequence.result
@@ -2033,3 +2033,72 @@ s:insert{'d', box.null, 1001}
s:drop()
---
...
+--
+-- gh-4210: sequence cannot be used with json path indexes.
+--
+sq = box.schema.sequence.create('test')
+---
+...
+s = box.schema.space.create('test')
+---
+...
+s:create_index('pk', {parts = {{'[1][1]', 'unsigned'}}, sequence = true}) -- error
+---
+- error: 'Can''t create or modify index ''pk'' in space ''test'': sequence cannot
+ be used with a json path key'
+...
+s:create_index('pk', {parts = {{1, 'unsigned', path = '[1]'}}, sequence = true}) -- error
+---
+- error: 'Can''t create or modify index ''pk'' in space ''test'': sequence cannot
+ be used with a json path key'
+...
+_ = s:create_index('pk', {parts = {{1, 'unsigned'}, {'[2][1]', 'unsigned'}}, sequence = true}) -- ok
+---
+...
+s.index.pk:alter{sequence_part = 2} -- error
+---
+- error: 'Can''t create or modify index ''pk'' in space ''test'': sequence cannot
+ be used with a json path key'
+...
+box.space._space_sequence:update(s.id, {{'=', 4, 1}}) -- error
+---
+- error: 'Can''t create or modify index ''pk'' in space ''test'': sequence cannot
+ be used with a json path key'
+...
+s.index.pk:alter{parts = {{'[1][1]', 'unsigned'}}} -- error
+---
+- error: 'Can''t create or modify index ''pk'' in space ''test'': sequence cannot
+ be used with a json path key'
+...
+s.index.pk:alter{parts = {{1, 'unsigned', path = '[1]'}}} -- error
+---
+- error: 'Can''t create or modify index ''pk'' in space ''test'': sequence cannot
+ be used with a json path key'
+...
+box.space._index:update({s.id, 0}, {{'=', 6, {{field = 1, type = 'unsigned', path = '[1]'}}}}) -- error
+---
+- error: 'Can''t create or modify index ''pk'' in space ''test'': sequence cannot
+ be used with a json path key'
+...
+s.index.pk:alter{sequence = false} -- ok
+---
+...
+s.index.pk:alter{sequence = true, sequence_part = 2} -- error
+---
+- error: 'Can''t create or modify index ''pk'' in space ''test'': sequence cannot
+ be used with a json path key'
+...
+box.space._space_sequence:insert{s.id, sq.id, false, 1} -- error
+---
+- error: 'Can''t create or modify index ''pk'' in space ''test'': sequence cannot
+ be used with a json path key'
+...
+s.index.pk:alter{sequence = true} -- ok
+---
+...
+s:drop()
+---
+...
+sq:drop()
+---
+...
diff --git a/test/box/sequence.test.lua b/test/box/sequence.test.lua
index d419e369..3fa0bef7 100644
--- a/test/box/sequence.test.lua
+++ b/test/box/sequence.test.lua
@@ -685,3 +685,23 @@ s.index.pk.sequence_id == sequence_id
s:insert{'d', 1000, 1000}
s:insert{'d', box.null, 1001}
s:drop()
+
+--
+-- gh-4210: sequence cannot be used with json path indexes.
+--
+sq = box.schema.sequence.create('test')
+s = box.schema.space.create('test')
+s:create_index('pk', {parts = {{'[1][1]', 'unsigned'}}, sequence = true}) -- error
+s:create_index('pk', {parts = {{1, 'unsigned', path = '[1]'}}, sequence = true}) -- error
+_ = s:create_index('pk', {parts = {{1, 'unsigned'}, {'[2][1]', 'unsigned'}}, sequence = true}) -- ok
+s.index.pk:alter{sequence_part = 2} -- error
+box.space._space_sequence:update(s.id, {{'=', 4, 1}}) -- error
+s.index.pk:alter{parts = {{'[1][1]', 'unsigned'}}} -- error
+s.index.pk:alter{parts = {{1, 'unsigned', path = '[1]'}}} -- error
+box.space._index:update({s.id, 0}, {{'=', 6, {{field = 1, type = 'unsigned', path = '[1]'}}}}) -- error
+s.index.pk:alter{sequence = false} -- ok
+s.index.pk:alter{sequence = true, sequence_part = 2} -- error
+box.space._space_sequence:insert{s.id, sq.id, false, 1} -- error
+s.index.pk:alter{sequence = true} -- ok
+s:drop()
+sq:drop()
--
2.11.0
^ permalink raw reply [flat|nested] 17+ messages in thread
* [tarantool-patches] Re: [PATCH 4/4] schema: explicitly forbid setting sequence for json path key part
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 ` Konstantin Osipov
2019-05-15 13:11 ` Vladimir Davydov
0 siblings, 1 reply; 17+ messages in thread
From: Konstantin Osipov @ 2019-05-15 13:00 UTC (permalink / raw)
To: tarantool-patches
* Vladimir Davydov <vdavydov.dev@gmail.com> [19/05/15 14:16]:
> When a space has a sequence, we substitute NULL in the corresponding
> primary index part with the next value generated by the sequence. We do
> this by patching raw msgpack, see request_handle_sequence. The problem
> is we can't do it easily if the field is nested. For example, consider
> field [1].a.b. In Lua it is impossible to create tuple {{a = {b = nil}}}
It is trivial to do, use msgpack.NULL
> so we would need to restore the whole path from an empty tuple.
No, it's not the job of the sequence to fill in the entire path.
You can expect the right prefix to be there.
--
Konstantin Osipov, Moscow, Russia, +7 903 626 22 32
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [tarantool-patches] Re: [PATCH 4/4] schema: explicitly forbid setting sequence for json path key part
2019-05-15 13:00 ` [tarantool-patches] " Konstantin Osipov
@ 2019-05-15 13:11 ` Vladimir Davydov
2019-05-15 13:16 ` Vladimir Davydov
0 siblings, 1 reply; 17+ messages in thread
From: Vladimir Davydov @ 2019-05-15 13:11 UTC (permalink / raw)
To: Konstantin Osipov; +Cc: tarantool-patches
On Wed, May 15, 2019 at 04:00:26PM +0300, Konstantin Osipov wrote:
> * Vladimir Davydov <vdavydov.dev@gmail.com> [19/05/15 14:16]:
> > When a space has a sequence, we substitute NULL in the corresponding
> > primary index part with the next value generated by the sequence. We do
> > this by patching raw msgpack, see request_handle_sequence. The problem
> > is we can't do it easily if the field is nested. For example, consider
> > field [1].a.b. In Lua it is impossible to create tuple {{a = {b = nil}}}
>
> It is trivial to do, use msgpack.NULL
Hmm, I tried box.NULL and it didn't work out.
msgpack.NULL seems to be different.
>
> > so we would need to restore the whole path from an empty tuple.
>
> No, it's not the job of the sequence to fill in the entire path.
> You can expect the right prefix to be there.
Okay, will try to address.
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [tarantool-patches] Re: [PATCH 4/4] schema: explicitly forbid setting sequence for json path key part
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
0 siblings, 1 reply; 17+ messages in thread
From: Vladimir Davydov @ 2019-05-15 13:16 UTC (permalink / raw)
To: Konstantin Osipov; +Cc: tarantool-patches
On Wed, May 15, 2019 at 04:11:21PM +0300, Vladimir Davydov wrote:
> On Wed, May 15, 2019 at 04:00:26PM +0300, Konstantin Osipov wrote:
> > * Vladimir Davydov <vdavydov.dev@gmail.com> [19/05/15 14:16]:
> > > When a space has a sequence, we substitute NULL in the corresponding
> > > primary index part with the next value generated by the sequence. We do
> > > this by patching raw msgpack, see request_handle_sequence. The problem
> > > is we can't do it easily if the field is nested. For example, consider
> > > field [1].a.b. In Lua it is impossible to create tuple {{a = {b = nil}}}
> >
> > It is trivial to do, use msgpack.NULL
>
> Hmm, I tried box.NULL and it didn't work out.
Oops, box.NULL is fine, too. It's just I tried box.null :)
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH] box: fix autoincrement for json path indexes
2019-05-15 13:16 ` Vladimir Davydov
@ 2019-05-15 13:44 ` Vladimir Davydov
2019-05-16 7:42 ` [tarantool-patches] " Konstantin Osipov
0 siblings, 1 reply; 17+ messages in thread
From: Vladimir Davydov @ 2019-05-15 13:44 UTC (permalink / raw)
To: tarantool-patches
The autoincrement code was written when there were no nested field.
Now, it isn't enough to just skip to the autoincrement field - we also
need to descend deeper if key_part->path is set.
Note, the code expects the nested field to be present and set to NULL.
That is, if field path is [1].a.b, the tuple must have all intermediate
fields set: {{a = {b = box.NULL}}} (usage of box.NULL is mandatory to
create a tuple like that in Lua).
Closes #4210
---
src/box/request.c | 10 +++++++++-
test/box/sequence.result | 32 ++++++++++++++++++++++++++++++++
test/box/sequence.test.lua | 12 ++++++++++++
3 files changed, 53 insertions(+), 1 deletion(-)
diff --git a/src/box/request.c b/src/box/request.c
index 9d3287f9..041a8d54 100644
--- a/src/box/request.c
+++ b/src/box/request.c
@@ -163,7 +163,8 @@ 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[space->sequence_part].fieldno;
+ struct key_part *part = &pk->def->key_def->parts[space->sequence_part];
+ int fieldno = part->fieldno;
if (unlikely(len < fieldno + 1))
return 0;
@@ -174,6 +175,13 @@ request_handle_sequence(struct request *request, struct space *space)
} while (--fieldno > 0);
}
+ if (part->path != NULL) {
+ tuple_go_to_path(&key, part->path, part->path_len,
+ MULTIKEY_NONE);
+ if (key == NULL)
+ return 0; /* field not found */
+ }
+
int64_t value;
if (mp_typeof(*key) == MP_NIL) {
/*
diff --git a/test/box/sequence.result b/test/box/sequence.result
index 8a7c349c..3cac4dc9 100644
--- a/test/box/sequence.result
+++ b/test/box/sequence.result
@@ -2033,3 +2033,35 @@ s:insert{'d', box.NULL, 1001}
s:drop()
---
...
+--
+-- gh-4210: using sequence with a json path key part.
+--
+s = box.schema.space.create('test')
+---
+...
+_ = s:create_index('pk', {parts = {{'[1].a.b[1]', 'unsigned'}}, sequence = true})
+---
+...
+s:replace{} -- error
+---
+- error: Tuple field [1]["a"]["b"][1] required by space format is missing
+...
+s:replace{{c = {}}} -- error
+---
+- error: Tuple field [1]["a"]["b"][1] required by space format is missing
+...
+s:replace{{a = {c = {}}}} -- error
+---
+- error: Tuple field [1]["a"]["b"][1] required by space format is missing
+...
+s:replace{{a = {b = {}}}} -- error
+---
+- error: Tuple field [1]["a"]["b"][1] required by space format is missing
+...
+s:replace{{a = {b = {box.NULL}}}} -- ok
+---
+- [{'a': {'b': [1]}}]
+...
+s:drop()
+---
+...
diff --git a/test/box/sequence.test.lua b/test/box/sequence.test.lua
index d931a94e..c39f1d41 100644
--- a/test/box/sequence.test.lua
+++ b/test/box/sequence.test.lua
@@ -685,3 +685,15 @@ s.index.pk.sequence_id == sequence_id
s:insert{'d', 1000, 1000}
s:insert{'d', box.NULL, 1001}
s:drop()
+
+--
+-- gh-4210: using sequence with a json path key part.
+--
+s = box.schema.space.create('test')
+_ = s:create_index('pk', {parts = {{'[1].a.b[1]', 'unsigned'}}, sequence = true})
+s:replace{} -- error
+s:replace{{c = {}}} -- error
+s:replace{{a = {c = {}}}} -- error
+s:replace{{a = {b = {}}}} -- error
+s:replace{{a = {b = {box.NULL}}}} -- ok
+s:drop()
--
2.11.0
^ permalink raw reply [flat|nested] 17+ messages in thread
* [tarantool-patches] Re: [PATCH] box: fix autoincrement for json path indexes
2019-05-15 13:44 ` [PATCH] box: fix autoincrement for json path indexes Vladimir Davydov
@ 2019-05-16 7:42 ` Konstantin Osipov
2019-05-21 13:28 ` Vladimir Davydov
0 siblings, 1 reply; 17+ messages in thread
From: Konstantin Osipov @ 2019-05-16 7:42 UTC (permalink / raw)
To: tarantool-patches
* Vladimir Davydov <vdavydov.dev@gmail.com> [19/05/15 16:50]:
> The autoincrement code was written when there were no nested field.
> Now, it isn't enough to just skip to the autoincrement field - we also
> need to descend deeper if key_part->path is set.
>
> Note, the code expects the nested field to be present and set to NULL.
> That is, if field path is [1].a.b, the tuple must have all intermediate
> fields set: {{a = {b = box.NULL}}} (usage of box.NULL is mandatory to
> create a tuple like that in Lua).
Please write a request to docs since this part deserves a spetial
mention in the sequences docs. The patch itself is OK to push.
--
Konstantin Osipov, Moscow, Russia, +7 903 626 22 32
^ permalink raw reply [flat|nested] 17+ messages in thread
* [tarantool-patches] Re: [PATCH 3/4] schema: allow to set sequence for any index part, not just the first
2019-05-15 10:33 ` [PATCH 3/4] schema: allow to set sequence for any index part, not just the first Vladimir Davydov
@ 2019-05-16 7:45 ` Konstantin Osipov
2019-05-16 8:02 ` Vladimir Davydov
0 siblings, 1 reply; 17+ messages in thread
From: Konstantin Osipov @ 2019-05-16 7:45 UTC (permalink / raw)
To: tarantool-patches
* Vladimir Davydov <vdavydov.dev@gmail.com> [19/05/15 14:16]:
> 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}
How about allowing column names? We already allow column names in
the parts definition.
Do we really need a separate sequence_part option, why not make
a scalar (bool = true/false, numeric, string - column number or
id).
--
Konstantin Osipov, Moscow, Russia, +7 903 626 22 32
^ permalink raw reply [flat|nested] 17+ messages in thread
* [tarantool-patches] Re: [PATCH 2/4] schema: fix error while altering index with sequence
2019-05-15 10:33 ` [PATCH 2/4] schema: fix error while altering index with sequence Vladimir Davydov
@ 2019-05-16 7:45 ` Konstantin Osipov
0 siblings, 0 replies; 17+ messages in thread
From: Konstantin Osipov @ 2019-05-16 7:45 UTC (permalink / raw)
To: tarantool-patches
* Vladimir Davydov <vdavydov.dev@gmail.com> [19/05/15 14:16]:
> A check was missing in index.alter. This resulted in an attempt to drop
> the sequence attached to the altered index even if the sequence was not
> modified.
>
> Closes #4214
OK to push.
--
Konstantin Osipov, Moscow, Russia, +7 903 626 22 32
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [tarantool-patches] Re: [PATCH 3/4] schema: allow to set sequence for any index part, not just the first
2019-05-16 7:45 ` [tarantool-patches] " Konstantin Osipov
@ 2019-05-16 8:02 ` Vladimir Davydov
0 siblings, 0 replies; 17+ messages in thread
From: Vladimir Davydov @ 2019-05-16 8:02 UTC (permalink / raw)
To: Konstantin Osipov; +Cc: tarantool-patches
On Thu, May 16, 2019 at 10:45:29AM +0300, Konstantin Osipov wrote:
> * Vladimir Davydov <vdavydov.dev@gmail.com> [19/05/15 14:16]:
> > 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}
>
>
> How about allowing column names? We already allow column names in
> the parts definition.
I don't understand. Do you suggest to match column name with a part
number? What for? The user knows index parts - they are right here in
the index definition - he can choose one for autoincrement. Actually,
this is what the solution team asked for.
>
> Do we really need a separate sequence_part option, why not make
> a scalar (bool = true/false, numeric, string - column number or
> id).
We do need 'sequence_part', because 'sequence' is already a scalar:
int - sequence id
string - sequence name
true/false - autogenerated sequence
An alternative approach would be attaching sequences to columns rather
than indexes (i.e. adding them to tuple_format), but that would require
massive rework of autoincrement with a lot of backward compatibility
hacks. It isn't quite clear to me that we need to do it now.
^ permalink raw reply [flat|nested] 17+ messages in thread
* [tarantool-patches] Re: [PATCH 0/4] A few fixes/improvements for autoincrement indexes
2019-05-15 10:33 [PATCH 0/4] A few fixes/improvements for autoincrement indexes Vladimir Davydov
` (3 preceding siblings ...)
2019-05-15 10:33 ` [PATCH 4/4] schema: explicitly forbid setting sequence for json path key part Vladimir Davydov
@ 2019-05-21 10:42 ` Kirill Yukhin
2019-05-21 14:58 ` Konstantin Osipov
4 siblings, 1 reply; 17+ messages in thread
From: Kirill Yukhin @ 2019-05-21 10:42 UTC (permalink / raw)
To: tarantool-patches
Hello,
On 15 May 13:33, Vladimir Davydov wrote:
> See comments to individual patches for more details.
>
> https://github.com/tarantool/tarantool/issues/4009
> https://github.com/tarantool/tarantool/issues/4210
> https://github.com/tarantool/tarantool/issues/4214
> https://github.com/tarantool/tarantool/commits/dv/sequence-fixes
>
> Vladimir Davydov (4):
> schema: use tuple field names in Lua
Checked into master.
> schema: fix error while altering index with sequence
Checked into 1.10, 2.1 and master.
> schema: allow to set sequence for any index part, not just the first
Checked into master.
> schema: explicitly forbid setting sequence for json path key part
Checked into 2.1 and master.
--
Regards, Kirill Yukhin
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [tarantool-patches] Re: [PATCH] box: fix autoincrement for json path indexes
2019-05-16 7:42 ` [tarantool-patches] " Konstantin Osipov
@ 2019-05-21 13:28 ` Vladimir Davydov
0 siblings, 0 replies; 17+ messages in thread
From: Vladimir Davydov @ 2019-05-21 13:28 UTC (permalink / raw)
To: Konstantin Osipov; +Cc: tarantool-patches
On Thu, May 16, 2019 at 10:42:56AM +0300, Konstantin Osipov wrote:
> * Vladimir Davydov <vdavydov.dev@gmail.com> [19/05/15 16:50]:
> > The autoincrement code was written when there were no nested field.
> > Now, it isn't enough to just skip to the autoincrement field - we also
> > need to descend deeper if key_part->path is set.
> >
> > Note, the code expects the nested field to be present and set to NULL.
> > That is, if field path is [1].a.b, the tuple must have all intermediate
> > fields set: {{a = {b = box.NULL}}} (usage of box.NULL is mandatory to
> > create a tuple like that in Lua).
>
> Please write a request to docs since this part deserves a spetial
> mention in the sequences docs.
Done: https://github.com/tarantool/doc/issues/782
^ permalink raw reply [flat|nested] 17+ messages in thread
* [tarantool-patches] Re: [PATCH 0/4] A few fixes/improvements for autoincrement indexes
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
0 siblings, 1 reply; 17+ messages in thread
From: Konstantin Osipov @ 2019-05-21 14:58 UTC (permalink / raw)
To: tarantool-patches
* Kirill Yukhin <kyukhin@tarantool.org> [19/05/21 13:43]:
> Hello,
> > schema: explicitly forbid setting sequence for json path key part
I asked to use an existing option and allow field names in the
patch, e.g. sequece = path.to.field.
I don't see that this is done in the patch.
Why did you check it in?
--
Konstantin Osipov, Moscow, Russia
^ permalink raw reply [flat|nested] 17+ messages in thread
* [tarantool-patches] Re: [PATCH 0/4] A few fixes/improvements for autoincrement indexes
2019-05-21 14:58 ` Konstantin Osipov
@ 2019-05-21 16:02 ` Kirill Yukhin
0 siblings, 0 replies; 17+ messages in thread
From: Kirill Yukhin @ 2019-05-21 16:02 UTC (permalink / raw)
To: tarantool-patches
Hello,
On 21 май 17:58, Konstantin Osipov wrote:
> * Kirill Yukhin <kyukhin@tarantool.org> [19/05/21 13:43]:
> > Hello,
>
> > > schema: explicitly forbid setting sequence for json path key part
>
> I asked to use an existing option and allow field names in the
> patch, e.g. sequece = path.to.field.
Do you suggest to allow assigning a sequence to JSON path?
> I don't see that this is done in the patch.
>
> Why did you check it in?
Vova replied you here [1], this might be useful follow-up, but
right now looks like this is out of scope of the request. They
just need to be able to set sequence to an arbitrary index part.
Since five days pass w/o answer I've checked it into master.
[1] - https://www.freelists.org/post/tarantool-patches/PATCH-34-schema-allow-to-set-sequence-for-any-index-part-not-just-the-first,2
--
Regards, Kirill Yukhin
^ permalink raw reply [flat|nested] 17+ messages in thread
end of thread, other threads:[~2019-05-21 16:02 UTC | newest]
Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
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 ` [PATCH 3/4] schema: allow to set sequence for any index part, not just the first Vladimir Davydov
2019-05-16 7:45 ` [tarantool-patches] " 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
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox