From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Content-Type: text/plain; charset=utf-8 Mime-Version: 1.0 (Mac OS X Mail 11.5 \(3445.9.1\)) Subject: Re: [tarantool-patches] Re: [PATCH v2] Introduce separate entity object types for entity privileges. From: Serge Petrenko In-Reply-To: <20180817091931.r45zifiikkwzuycu@esperanza> Date: Fri, 17 Aug 2018 15:19:29 +0300 Content-Transfer-Encoding: quoted-printable Message-Id: <93712A9E-2004-4609-8506-4ACB043A627B@tarantool.org> References: <20180802105558.20488-1-sergepetrenko@tarantool.org> <20180807163842.agnqqk7gyua2vwzv@esperanza> <305E5CD8-68DD-4897-9E77-347F290091A6@tarantool.org> <20180817091931.r45zifiikkwzuycu@esperanza> To: Vladimir Davydov Cc: Konstantin Osipov , tarantool-patches@freelists.org List-ID: Hi! Thank you for review. I fixed your comments, the new diff is below. > 17 =D0=B0=D0=B2=D0=B3. 2018 =D0=B3., =D0=B2 12:19, Vladimir Davydov = =D0=BD=D0=B0=D0=BF=D0=B8=D1=81=D0=B0=D0=BB(=D0=B0= ): >=20 > On Tue, Aug 14, 2018 at 04:41:25PM +0300, Serge Petrenko wrote: >> diff --git a/src/box/alter.cc b/src/box/alter.cc >> index 3007a131d..7d65cab3a 100644 >> --- a/src/box/alter.cc >> +++ b/src/box/alter.cc >> @@ -2537,10 +2537,41 @@ priv_def_create_from_tuple(struct priv_def = *priv, struct tuple *tuple) >> { >> priv->grantor_id =3D tuple_field_u32_xc(tuple, = BOX_PRIV_FIELD_ID); >> priv->grantee_id =3D tuple_field_u32_xc(tuple, = BOX_PRIV_FIELD_UID); >> + >> const char *object_type =3D >> tuple_field_cstr_xc(tuple, BOX_PRIV_FIELD_OBJECT_TYPE); >> - priv->object_id =3D tuple_field_u32_xc(tuple, = BOX_PRIV_FIELD_OBJECT_ID); >> priv->object_type =3D schema_object_type(object_type); >> + >> + const char *object_id =3D tuple_field(tuple, = BOX_PRIV_FIELD_OBJECT_ID); >=20 > This isn't object_id. It's msgpack. Please rename this variable to > emphasize that. For instance, 'object_id_field', 'object_id_raw', or > simply 'data=E2=80=99. Ok, let it be =E2=80=98data=E2=80=99. >=20 >> + if (object_id =3D=3D NULL) { >> + tnt_raise(ClientError, ER_NO_SUCH_FIELD, >> + BOX_PRIV_FIELD_OBJECT_ID + TUPLE_INDEX_BASE); >> + } >> + /* >> + * When granting or revoking privileges on a whole entity >> + * we pass an asterisk ('*') to object_id to indicate >> + * grant on every object of that entity. >> + * So check for that first. >> + */ >> + if (mp_typeof(*object_id) =3D=3D MP_STR) { >> + object_id =3D tuple_field_cstr_xc(tuple, = BOX_PRIV_FIELD_OBJECT_ID); >> + if(*object_id =3D=3D '*' && strlen(object_id) =3D=3D 1) = { >=20 > Nit: in a case like this, better use strcmp. We decided to switch to =C2=AB=C2=BB (empty string), so use = mp_decode_strl(&data) =3D=3D 0 here >=20 >> + priv->object_id =3D 0; >> + priv->object_type =3D = schema_entity_type(priv->object_type); >> + } else { >> + tnt_raise(ClientError, ER_FIELD_TYPE, >> + BOX_PRIV_FIELD_OBJECT_ID + = TUPLE_INDEX_BASE, >> + field_type_strs[FIELD_TYPE_UNSIGNED]); >> + } >> + } else if (mp_typeof(*object_id) =3D=3D MP_UINT) { >> + priv->object_id =3D tuple_field_u32_xc(tuple, >> + = BOX_PRIV_FIELD_OBJECT_ID); >> + } else { >> + tnt_raise(ClientError, ER_FIELD_TYPE, >> + BOX_PRIV_FIELD_OBJECT_ID + TUPLE_INDEX_BASE, >> + field_type_strs[FIELD_TYPE_UNSIGNED]); >> + } >> + >=20 > Somehow, I don't like this piece of code. For instance, you raise > the same error (FIELD_TYPE_UNSIGNED) in two places. Also, you use > tuple_field_*_xc after you explicitly check the type, which is > pointless, because they can't fail. >=20 > May be, something like this? >=20 > switch (mp_typeof(*data)) { > case MP_STR: > if (mp_decode_strl(&data) =3D=3D 0) { > /* Entity-wide privilege. */ > priv->object_id =3D 0; > break; > } > FALLTHROUGH; > default: > priv->object_id =3D tuple_field_u32_xc(...); > } Ok, I use your variant. >=20 >> if (priv->object_type =3D=3D SC_UNKNOWN) { >> tnt_raise(ClientError, ER_UNKNOWN_SCHEMA_OBJECT, >> object_type); >> diff --git a/src/box/lua/schema.lua b/src/box/lua/schema.lua >> index b9b8c9004..361810c79 100644 >> --- a/src/box/lua/schema.lua >> +++ b/src/box/lua/schema.lua >> @@ -1801,17 +1801,19 @@ local function privilege_name(privilege) >> end >>=20 >> local function object_resolve(object_type, object_name) >> + if object_name ~=3D nil and type(object_name) ~=3D 'string' >> + and type(object_name) ~=3D 'number' then >> + box.error(box.error.ILLEGAL_PARAMS, "wrong object name = type") >> + end >> if object_type =3D=3D 'universe' then >> - if object_name ~=3D nil and type(object_name) ~=3D 'string' >> - and type(object_name) ~=3D 'number' then >> - box.error(box.error.ILLEGAL_PARAMS, "wrong object name = type") >> - end >> return 0 >> end >> + if (object_type =3D=3D 'space' or object_type =3D=3D 'function' = or >> + object_type =3D=3D 'sequence' or object_type =3D=3D 'role') = and >> + object_name =3D=3D nil then >> + return '*' >> + end >=20 > No, I don't like this: now, if you want to add a new object type, > you have to patch two places: here and below, where the object name > is resolved. Let's leave it as before. Ok. >=20 >> if object_type =3D=3D 'space' then >> - if object_name =3D=3D nil or object_name =3D=3D 0 then >> - return 0 >> - end >> local space =3D box.space[object_name] >> if space =3D=3D nil then >> box.error(box.error.NO_SUCH_SPACE, object_name) >> @@ -1819,9 +1821,6 @@ local function object_resolve(object_type, = object_name) >> return space.id >> end >> if object_type =3D=3D 'function' then >> - if object_name =3D=3D nil or object_name =3D=3D 0 then >> - return 0 >> - end >> local _vfunc =3D box.space[box.schema.VFUNC_ID] >> local func >> if type(object_name) =3D=3D 'string' then >> @@ -1836,9 +1835,6 @@ local function object_resolve(object_type, = object_name) >> end >> end >> if object_type =3D=3D 'sequence' then >> - if object_name =3D=3D nil or object_name =3D=3D 0 then >> - return 0 >> - end >> local seq =3D sequence_resolve(object_name) >> if seq =3D=3D nil then >> box.error(box.error.NO_SUCH_SEQUENCE, object_name) >> @@ -1867,6 +1863,9 @@ local function object_name(object_type, = object_id) >> if object_type =3D=3D 'universe' then >> return "" >> end >> + if object_id =3D=3D '*' then >> + return '*' >> + end >> local space >> if object_type =3D=3D 'space' then >> space =3D box.space._vspace >> @@ -2106,10 +2105,10 @@ local function grant(uid, name, privilege, = object_type, >> _priv:replace{options.grantor, uid, object_type, oid, = privilege_hex} >> elseif not options.if_not_exists then >> if object_type =3D=3D 'role' then >> - box.error(box.error.ROLE_GRANTED, name, object_name) >> + box.error(box.error.ROLE_GRANTED, name, object_name = or '*') >> else >> box.error(box.error.PRIV_GRANTED, name, privilege, >> - object_type, object_name) >> + object_type, object_name or '*') >> end >> end >> end >> @@ -2134,10 +2133,10 @@ local function revoke(uid, name, privilege, = object_type, object_name, options) >> return >> end >> if object_type =3D=3D 'role' then >> - box.error(box.error.ROLE_NOT_GRANTED, name, object_name) >> + box.error(box.error.ROLE_NOT_GRANTED, name, object_name = or '*') >> else >> box.error(box.error.PRIV_NOT_GRANTED, name, privilege, >> - object_type, object_name) >> + object_type, object_name or '*') >> end >> end >> local old_privilege =3D tuple[5] >> @@ -2153,13 +2152,14 @@ local function revoke(uid, name, privilege, = object_type, object_name, options) >> return >> end >> box.error(box.error.PRIV_NOT_GRANTED, name, privilege, >> - object_type, object_name) >> + object_type, object_name or '*') >> end >> if privilege_hex ~=3D 0 then >> _priv:replace{grantor, uid, object_type, oid, privilege_hex} >> else >> _priv:delete{uid, object_type, oid} >> end >> + >=20 > Extra new line, please remove. Done >=20 >> end >>=20 >> local function drop(uid, opts) >> @@ -2192,9 +2192,10 @@ local function drop(uid, opts) >> local privs =3D _vpriv.index.primary:select{uid} >>=20 >> 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]) >> + -- we need an additional box.session.su() here, because of >> + -- unnecessary check for privilege PRIV_REVOKE in = priv_def_check() >> + local oid =3D tuple[4] ~=3D '*' and tuple[4] or nil >> + box.session.su("admin", revoke, uid, uid, tuple[5], = tuple[3], oid) >> end >> box.space[box.schema.USER_ID]:delete{uid} >> end >> diff --git a/src/box/lua/upgrade.lua b/src/box/lua/upgrade.lua >> index 0293f6ef8..5dbc09bbb 100644 >> --- a/src/box/lua/upgrade.lua >> +++ b/src/box/lua/upgrade.lua >> @@ -964,6 +964,28 @@ local function upgrade_to_1_10_0() >> create_vsequence_space() >> end >>=20 >> = +-------------------------------------------------------------------------= ------- >> +--- Tarantool 1.10.1 >> = +-------------------------------------------------------------------------= ------- >> +local function upgrade_space_priv_to_1_10_1() >> + local _priv =3D box.space._priv >> + local _vpriv =3D box.space._vpriv >> + local f =3D _priv:format() >> + >> + f[4].type =3D 'scalar' >> + _priv:format(f) >> + f =3D _vpriv:format() >> + f[4].type =3D 'scalar' >> + _vpriv:format(f) >> + _priv.index.primary:alter{parts=3D{2, 'unsigned', 3, 'string', = 4, 'scalar'}} >> + _vpriv.index.primary:alter{parts=3D{2, 'unsigned', 3, 'string', = 4, 'scalar'}} >> + _priv.index.object:alter{parts=3D{3, 'string', 4, 'scalar'}} >> + _vpriv.index.object:alter{parts=3D{3, 'string', 4, 'scalar'}} >> +end >> + >> +local function upgrade_to_1_10_1() >> + upgrade_space_priv_to_1_10_1() >> +end >>=20 >> local function get_version() >> local version =3D box.space._schema:get{'version'} >> @@ -991,6 +1013,7 @@ local function upgrade(options) >> {version =3D mkversion(1, 7, 6), func =3D upgrade_to_1_7_6, = auto =3D false}, >> {version =3D mkversion(1, 7, 7), func =3D upgrade_to_1_7_7, = auto =3D true}, >> {version =3D mkversion(1, 10, 0), func =3D upgrade_to_1_10_0, = auto =3D true}, >> + {version =3D mkversion(1, 10, 1), func =3D = upgrade_to_1_10_1, auto =3D true}, >=20 > Should be 1.10.2 >=20 > 1.10.1 has already been released. Changed to 1.10.2 and updated bootstrap.snap >=20 >> } >>=20 >> for _, handler in ipairs(handlers) do >> diff --git a/src/box/schema.cc b/src/box/schema.cc >> index 433f52c08..9958e9016 100644 >> --- a/src/box/schema.cc >> +++ b/src/box/schema.cc >> @@ -536,10 +536,18 @@ schema_find_name(enum schema_object_type type, = uint32_t object_id) >> switch (type) { >> case SC_UNIVERSE: >> return ""; >> + case SC_ENTITY_SPACE: >> + return ""; >> + case SC_ENTITY_FUNCTION: >> + return ""; >> + case SC_ENTITY_SEQUENCE: >> + return ""; >> + case SC_ENTITY_ROLE: >> + return ""; >> + case SC_ENTITY_USER: >> + return ""; >=20 > Please rewrite it as >=20 > case SC_ENTITY_SPACE: > case SC_ENTITY_FUNCTION: > case SC_ENTITY_SEQUENCE: > ... > return ""; >=20 > Also, I don't like that sometimes we use '*' and sometimes '' when > reporting errors. What about using '' for entity-wide privileges > everywhere, including the _priv space? This would save us from > possible conflicts with objects named '*' (yeah, no sane user would > call a space like that, but still). This would also allow us to > simplify object_resolve() as I suggested in the previous review > round. Done. I like the idea with using =C2=AB=C2=BB instead of =C2=AB*=C2=BB, = switched to that. >=20 >> case SC_SPACE: >> { >> - if (object_id =3D=3D 0) >> - return "SPACE"; >> struct space *space =3D space_by_id(object_id); >> if (space =3D=3D NULL) >> break; >> @@ -547,8 +555,6 @@ schema_find_name(enum schema_object_type type, = uint32_t object_id) >> } >> case SC_FUNCTION: >> { >> - if (object_id =3D=3D 0) >> - return "FUNCTION"; >> struct func *func =3D func_by_id(object_id); >> if (func =3D=3D NULL) >> break; >> @@ -556,8 +562,6 @@ schema_find_name(enum schema_object_type type, = uint32_t object_id) >> } >> case SC_SEQUENCE: >> { >> - if (object_id =3D=3D 0) >> - return "SEQUENCE"; >> struct sequence *seq =3D = sequence_by_id(object_id); >> if (seq =3D=3D NULL) >> break; >> diff --git a/src/box/schema.h b/src/box/schema.h >> index 0822262d0..f1735ff34 100644 >> --- a/src/box/schema.h >> +++ b/src/box/schema.h >> @@ -250,16 +250,19 @@ static inline >> struct access * >> entity_access_get(enum schema_object_type type) >> { >> - switch (type) { >> - case SC_SPACE: >> - return entity_access.space; >> - case SC_FUNCTION: >> - return entity_access.function; >> - case SC_SEQUENCE: >> - return entity_access.sequence; >> - default: >> - return NULL; >> - } >> + switch (type) { >> + case SC_SPACE: >> + case SC_ENTITY_SPACE: >> + return entity_access.space; >> + case SC_FUNCTION: >> + case SC_ENTITY_FUNCTION: >> + return entity_access.function; >> + case SC_SEQUENCE: >> + case SC_ENTITY_SEQUENCE: >> + return entity_access.sequence; >> + default: >> + return NULL; >> + } >> } >>=20 >> #endif /* INCLUDES_TARANTOOL_BOX_SCHEMA_H */ >> diff --git a/src/box/schema_def.c b/src/box/schema_def.c >> index 97c074ab2..18ec6c8d2 100644 >> --- a/src/box/schema_def.c >> +++ b/src/box/schema_def.c >> @@ -31,16 +31,39 @@ >> #include "schema_def.h" >>=20 >> static const char *object_type_strs[] =3D { >> - /* [SC_UKNNOWN] =3D */ "unknown", >> - /* [SC_UNIVERSE] =3D */ "universe", >> - /* [SC_SPACE] =3D */ "space", >> - /* [SC_FUNCTION] =3D */ "function", >> - /* [SC_USER] =3D */ "user", >> - /* [SC_ROLE] =3D */ "role", >> - /* [SC_SEQUENCE] =3D */ "sequence", >> - /* [SC_COLLATION] =3D */ "collation", >> + /* [SC_UKNNOWN] =3D */ "unknown", >> + /* [SC_UNIVERSE] =3D */ "universe", >> + /* [SC_SPACE] =3D */ "space", >> + /* [SC_ENTITY_SPACE] =3D */ "space", >> + /* [SC_FUNCTION] =3D */ "function", >> + /* [SC_ENTITY_FUNCTION] =3D */ "function", >> + /* [SC_USER] =3D */ "user", >> + /* [SC_ENTITY_USER] =3D */ "user", >> + /* [SC_ROLE] =3D */ "role", >> + /* [SC_ENTITY_ROLE] =3D */ "role", >> + /* [SC_SEQUENCE] =3D */ "sequence", >> + /* [SC_ENTITY_SEQUENCE] =3D */ "sequence", >> + /* [SC_COLLATION] =3D */ "collation", >> + /* [SC_ENTITY_COLLATION] =3D */ "collation", >=20 > I don't like this code duplication. Actually, I don't think that you > need to have separate names for entity-wide privileges at all: AFAICS, > schema_object_name() is never called for SC_ENTITY_*. Let's remove > SC_ENTITY_* from this array. >=20 > If you do that, you won't be able to increment object type to get = entity > type. Well, OK, it's not that scary, taking into account the fact that > you always use a helper function for that (see right below). I see it > that way >=20 > enum schema_object_type { > SC_UNKNOWN =3D 0, > SC_UNIVERSE =3D 1, > SC_SPACE =3D 2, > SC_FUNCTION =3D 3, > SC_USER =3D 4, > SC_ROLE =3D 5, > SC_SEQUENCE =3D 6, > SC_COLLATION =3D 7, > schema_object_type_MAX =3D 8 >=20 > /* Entity types. */ > SC_ENTITY_SPACE, > SC_ENTITY_FUNCTION, > =E2=80=A6 > } >=20 > enum schema_object_type > schema_entity_type(enum schema_object_type type) > { > switch (type) { > case SC_SPACE: > return SC_ENTITY_SPACE; > case SC_FUNCTION: > return SC_ENTITY_FUNCTION; > ... > } > } >=20 Ok, switched to your variant with slight differences. >> }; >>=20 >> +enum schema_object_type >> +schema_entity_type(enum schema_object_type type) >> +{ >> + switch(type) { >=20 > ^^ > space missing Fixed. >=20 >> + case SC_SPACE: >> + case SC_FUNCTION: >> + case SC_USER: >> + case SC_ROLE: >> + case SC_SEQUENCE: >> + case SC_COLLATION: >> + return type + 1; >> + break; >> + default: >> + unreachable(); >> + } >> +} >> + >> enum schema_object_type >> schema_object_type(const char *name) >> { >> diff --git a/src/box/schema_def.h b/src/box/schema_def.h >> index 2edb8d37f..9b5bd6864 100644 >> --- a/src/box/schema_def.h >> +++ b/src/box/schema_def.h >> @@ -218,19 +218,35 @@ enum { >> * >> * Use 0 for unknown to use the same index consistently >> * even when there are more object types in the future. >> + * >> + * When adding new types please follow this rule: >> + * SC_ENTITY_NEW_OBJECT =3D SC_NEW_OBJECT + 1 >> + * schema_entity_type() relies on this convention. >> */ >> enum schema_object_type { >> SC_UNKNOWN =3D 0, >> SC_UNIVERSE =3D 1, >> SC_SPACE =3D 2, >> - SC_FUNCTION =3D 3, >> - SC_USER =3D 4, >> - SC_ROLE =3D 5, >> - SC_SEQUENCE =3D 6, >> - SC_COLLATION =3D 7, >> - schema_object_type_MAX =3D 8 >> + SC_ENTITY_SPACE =3D 3, >> + SC_FUNCTION =3D 4, >> + SC_ENTITY_FUNCTION =3D 5, >> + SC_USER =3D 6, >> + SC_ENTITY_USER =3D 7, >> + SC_ROLE =3D 8, >> + SC_ENTITY_ROLE =3D 9, >> + SC_SEQUENCE =3D 10, >> + SC_ENTITY_SEQUENCE =3D 11, >> + SC_COLLATION =3D 12, >> + SC_ENTITY_COLLATION =3D 13, >> + schema_object_type_MAX =3D 13 >> }; >=20 --- src/box/alter.cc | 27 +++++++++++++++++++- src/box/bootstrap.snap | Bin 1540 -> 1556 bytes src/box/lua/schema.lua | 58 = ++++++++++++++++++++++++++----------------- src/box/lua/upgrade.lua | 23 +++++++++++++++++ src/box/schema.cc | 11 ++++---- src/box/schema.h | 23 +++++++++-------- src/box/schema_def.c | 7 ++++++ src/box/schema_def.h | 18 +++++++++++++- src/box/user.cc | 27 +++++++++++--------- test/box-py/bootstrap.result | 14 +++++------ test/box/access.result | 6 ++--- test/box/access_misc.result | 8 +++--- test/box/alter.result | 8 +++--- test/xlog/upgrade.result | 14 +++++------ 14 files changed, 166 insertions(+), 78 deletions(-) diff --git a/src/box/alter.cc b/src/box/alter.cc index 3007a131d..f586a2695 100644 --- a/src/box/alter.cc +++ b/src/box/alter.cc @@ -2537,10 +2537,35 @@ priv_def_create_from_tuple(struct priv_def = *priv, struct tuple *tuple) { priv->grantor_id =3D tuple_field_u32_xc(tuple, = BOX_PRIV_FIELD_ID); priv->grantee_id =3D tuple_field_u32_xc(tuple, = BOX_PRIV_FIELD_UID); + const char *object_type =3D tuple_field_cstr_xc(tuple, BOX_PRIV_FIELD_OBJECT_TYPE); - priv->object_id =3D tuple_field_u32_xc(tuple, = BOX_PRIV_FIELD_OBJECT_ID); priv->object_type =3D schema_object_type(object_type); + + const char *data =3D tuple_field(tuple, = BOX_PRIV_FIELD_OBJECT_ID); + if (data =3D=3D NULL) { + tnt_raise(ClientError, ER_NO_SUCH_FIELD, + BOX_PRIV_FIELD_OBJECT_ID + TUPLE_INDEX_BASE); + } + /* + * When granting or revoking privileges on a whole entity + * we pass empty string ('') to object_id to indicate + * grant on every object of that entity. + * So check for that first. + */ + switch (mp_typeof(*data)) { + case MP_STR: + if (mp_decode_strl(&data) =3D=3D 0) { + /* Entity-wide privilege. */ + priv->object_id =3D 0; + priv->object_type =3D = schema_entity_type(priv->object_type); + break; + } + FALLTHROUGH; + default: + priv->object_id =3D tuple_field_u32_xc(tuple, + = BOX_PRIV_FIELD_OBJECT_ID); + } if (priv->object_type =3D=3D SC_UNKNOWN) { tnt_raise(ClientError, ER_UNKNOWN_SCHEMA_OBJECT, object_type); diff --git a/src/box/bootstrap.snap b/src/box/bootstrap.snap index = b610828c9c9ae9a22acdd8c150c16c6838b7a273..44992b050e9d73d69608fb92782d1e96= 5f6cdc51 100644 GIT binary patch delta 1551 zcmV+q2JrcW43rFz7=3DJM>GB!9ZXE|m$WMeloGhzx!ZgX^DZewLSAT%>EG&o@}VJ$c{ zGcheRV>UP~VPZ03EipATVq!NoIX7cCWeQe9Y;R+0Iv{&}3JTS_3%bn(nE=3Dk-$Bkd5 z0000004TLD{QyvfEC41w*hV;#?6&k&og$AulUnEmX0mA^f0L=3Dio5sT!g zD{Fnf#vxPKYgy*n?1AMVIy{=3Dp9gia^hC=3DL0fWLuz8rC_P&bxEnm$jbL+0jvRI_+sG zru|Ih;m)d9Ab%fU2!MAhTHBbGce$H&nf~2*&yFmHLT-w8E2;yCj1eht_F<%$wYjrA z--_qmirxZNlbP>7cRjpY(I5*1%V7?t>8y7vDuOB;TVebwm5d3mRG{g&pI!j5ZV zdG3dP6Mx6^(8sb6!1;Xg8sDAa&WZ-$y>W_Zn~dpXc#Nf8o1_@R#?P@Ion`uUK3>En z4|O&qz`GSKF%8FiNe275855I3zK&RX`$!^s>UR9^o~tSri06BO z0Q-*j>z9Q*4+(#G7_m1GyjxLQ$D%fO4}ENn1MgPUw1qv^wQ}ZNwi0uPF;){6CdrBo=3D>OXh`5;7UxHP%|pfgijbup=3DMGrPps{8(Quhz zWw^YXTN9%N1NEZh;%hNtVMQxeEKqt?SWV_GYBSbz?d=3D0?f`WpY*c$IvG*qAOKeIM_ zQh2wbDYx3&2cpRx0;YE$dsj=3Dv%(gx?x*@*;&XWUfcndq})KR0uozbQ*?y?v(<-mNH&3>7#_ z#&nJefg`BVSY%8M%m4s@04M+v21hAoRSyz?&^U^NFbZH021E!rh)xs$fZ#w_L4OfM zEf@qq49vQeA))6t$8JsxhygJm2AP2;6jR1Ytzq>yuq)+j_YBuXSm^>oOc44oRR2+r zfKn$8@9xdDJsnXgj8fvJX-OOEnOz2N82f7Vr6^tAcX*WFIPM{0Ntj!pLMS~2mv!oE zRrM)J%oMN{r_N{V(s7_ah4$kjihs$63_%%=3D)mhn z2W|IQc+vMG<^-d?>WOsJ?wF5DwFGHVZ;5{eV6!P9un202vw!Z8R4d19B91M{)$#!E>qp7jG6HO>MyhU^@4T z^f(MLmIX$FanP|HqB(=3D3bAPgI29$n(?koqvkkh_+Jdt&9kemV%zz>2&MdX*2g^(0B zb3fr-G#O-Ux`l`P)LF58aj(U8%fMRlqE2MOof#G*F;Vmq(Um!gfT;c#$##_N2vs0b zGn`~?u8)RY;W>4D58f)EMzh}yokR<1H8AM^(7KO=3DYgngs1QB1+=3Dm<%o!R6Hut?jEW B)aL*I delta 1534 zcmVdT4F*z~{Np5p=3DVQyn(Iv_b=3DV_`LAF*YqTV`gS8= zG-hTvEnzrjFfCy?W;Qf4VP!dGGGq!?Lu_wjYdRo%F*+bOeF_TIx(m9^1&9F7A|rpb zr2qf`001bpFZ}>e{VMI&<{eU?~Ai$VOI~v629dx2JaIm@kx4N&&zCxB$xlBK}6v zM#}nreKVfmYggvF>;bcooE<&pjzw|&ydgCd;B)Xi4C|Up=3DiRyONm;Mu=3Dn31mId~$~K1OP2OJJrGIzc!y|v*5Q}mxHFpG|K|%#jeQ^A;E^l>* z3*Bp}NefgxX1+gm^KmUTgDMc1Jsb?P)oZC4!mL!?OgGcvU!7uNP_0u4V%4c@$$Tde zOCDy|bcHe0;hLW1g*=3D6kJQqvOo9n=3D`!@rT1v3PA=3DsEaGtUmrgF1V*+HwF$= z%o|ck2Ck)MDdN~U>lpNk)Rh9)Qd8p>$FU`TvVVQ}JNw3+pEy`&7|(v!cb#wKcU}Xc zztr*E^M9!-1a3aZxQyRo-mQ)X;JxvQVS5a1E-Z#;*X8(mp!hlb(b=3DWn_TxWHa?e&p z0ms_NyVg8C=3DMtXRLX=3DhZO}2jlujiL*MCw|r<8%iFyl-urCG}bk_A!)lFN(Z z*9rxd2`ZdQ%ZOz}8m(9>QmHeYBvm9q6rtA9wbTrW=3DuAh+mpZa8Z9M*WuhEnWw8OPP z0Ken?`duE+M1Fc0sWuO;rRJ>TPnWxUKDEZdwbU$UUQcC(VtJFR2G>&aT`%TX-lUJ$ zzkkQk8h`!+Ak42Gb5O~I9X_GL4xhR(RGq@`<8YEmeGLBa%Ed{YaV#4wH7X6(wXrob zRx(mCOfa|?Bo}qm;#z9jPz5?Ii>k-mKV61Bw$iw6MNm)>lUj2vHAVFK{#e#!kBV!l ziDGG`ab1f2WXaFUg5t{}`TM8d6EBXt_J3uuRg$)9X&lOg&M*+4wU)S+njl=3D^il77Rj$ynhqj zxeG%W18Ui|uoin^FOJH&6BE>1-;h#Us!zr2@yPWOP}$xk=3D>TS*Ej6Q8ZgBx&}sXh}Wym z;Yvs=3DXm6s&oTIkS5VXc28)t^2+kc4qR4r1#;*gdpU~^0s$pG8pm?G)gVGer7p5*j@ zrQSOro_cGm&fR}<@b8h^=3DiXW!%4reE=3DRqJFWsqt`1BcS0HC@As3ba#z^Ko9Pi8avYk$Oa!!S#& zSx3_!A8xyrpfT#3Y0zk_Hi}Y>p%$pI61F+5M3N&%2xKJAC;$CDD}<6?=3D$#5uoTZ5Z zCNj}EgB|fKv=3D$L@ag>MEJ_76DnN*W1Z`O`MZ9ptwx|K1yxMV1V1(Ltx%(4y7obk4E zW?=3D^8GIQ=3Dkv4A0`wS7N1*>`Z!opukPx!_g@c{8|RJi<`!QS!z#<&+X#nnV8V6uo^% zFL^|hfwSZ-+|LAZ&d5i?Zt>-$tMH_1UnT!Yb{@SussOv@WfJ50JyfLCQd9Bw_N-dh k2=3DV>Mm|$S01}gnuSl5OyKJnJxL~`9Mur5?adb1g8%>k diff --git a/src/box/lua/schema.lua b/src/box/lua/schema.lua index b9b8c9004..d347fd1e6 100644 --- a/src/box/lua/schema.lua +++ b/src/box/lua/schema.lua @@ -1801,16 +1801,16 @@ local function privilege_name(privilege) end =20 local function object_resolve(object_type, object_name) + if object_name ~=3D nil and type(object_name) ~=3D 'string' + and type(object_name) ~=3D 'number' then + box.error(box.error.ILLEGAL_PARAMS, "wrong object name type") + end if object_type =3D=3D 'universe' then - if object_name ~=3D nil and type(object_name) ~=3D 'string' - and type(object_name) ~=3D 'number' then - box.error(box.error.ILLEGAL_PARAMS, "wrong object name = type") - end return 0 end if object_type =3D=3D 'space' then - if object_name =3D=3D nil or object_name =3D=3D 0 then - return 0 + if object_name =3D=3D '' then + return '' end local space =3D box.space[object_name] if space =3D=3D nil then @@ -1819,8 +1819,8 @@ local function object_resolve(object_type, = object_name) return space.id end if object_type =3D=3D 'function' then - if object_name =3D=3D nil or object_name =3D=3D 0 then - return 0 + if object_name =3D=3D '' then + return '' end local _vfunc =3D box.space[box.schema.VFUNC_ID] local func @@ -1836,8 +1836,8 @@ local function object_resolve(object_type, = object_name) end end if object_type =3D=3D 'sequence' then - if object_name =3D=3D nil or object_name =3D=3D 0 then - return 0 + if object_name =3D=3D '' then + return '' end local seq =3D sequence_resolve(object_name) if seq =3D=3D nil then @@ -1864,7 +1864,7 @@ local function object_resolve(object_type, = object_name) end =20 local function object_name(object_type, object_id) - if object_type =3D=3D 'universe' then + if object_type =3D=3D 'universe' or object_id =3D=3D '' then return "" end local space @@ -2072,12 +2072,18 @@ local function grant(uid, name, privilege, = object_type, object_name, options) -- =46rom user point of view, role is the same thing -- as a privilege. Allow syntax grant(user, role). - if object_name =3D=3D nil and object_type =3D=3D nil then - -- sic: avoid recursion, to not bother with roles - -- named 'execute' - object_type =3D 'role' - object_name =3D privilege - privilege =3D 'execute' + if object_name =3D=3D nil then + if object_type =3D=3D nil then + -- sic: avoid recursion, to not bother with roles + -- named 'execute' + object_type =3D 'role' + object_name =3D privilege + privilege =3D 'execute' + else + -- Allow syntax grant(user, priv, entity) + -- for entity grants. + object_name =3D '' + end end local privilege_hex =3D privilege_check(privilege, object_type) =20 @@ -2117,10 +2123,16 @@ end local function revoke(uid, name, privilege, object_type, object_name, = options) -- =46rom user point of view, role is the same thing -- as a privilege. Allow syntax revoke(user, role). - if object_name =3D=3D nil and object_type =3D=3D nil then - object_type =3D 'role' - object_name =3D privilege - privilege =3D 'execute' + if object_name =3D=3D nil then + if object_type =3D=3D nil then + object_type =3D 'role' + object_name =3D privilege + privilege =3D 'execute' + else + -- Allow syntax revoke(user, privilege, entity) + -- to revoke entity privileges. + object_name =3D '' + end end local privilege_hex =3D privilege_check(privilege, object_type) options =3D options or {} @@ -2192,8 +2204,8 @@ local function drop(uid, opts) local privs =3D _vpriv.index.primary:select{uid} =20 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() + -- 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]) end box.space[box.schema.USER_ID]:delete{uid} diff --git a/src/box/lua/upgrade.lua b/src/box/lua/upgrade.lua index 0293f6ef8..091da2dc4 100644 --- a/src/box/lua/upgrade.lua +++ b/src/box/lua/upgrade.lua @@ -964,6 +964,28 @@ local function upgrade_to_1_10_0() create_vsequence_space() end =20 = +-------------------------------------------------------------------------= ------- +--- Tarantool 1.10.2 = +-------------------------------------------------------------------------= ------- +local function upgrade_space_priv_to_1_10_2() + local _priv =3D box.space._priv + local _vpriv =3D box.space._vpriv + local f =3D _priv:format() + + f[4].type =3D 'scalar' + _priv:format(f) + f =3D _vpriv:format() + f[4].type =3D 'scalar' + _vpriv:format(f) + _priv.index.primary:alter{parts=3D{2, 'unsigned', 3, 'string', 4, = 'scalar'}} + _vpriv.index.primary:alter{parts=3D{2, 'unsigned', 3, 'string', 4, = 'scalar'}} + _priv.index.object:alter{parts=3D{3, 'string', 4, 'scalar'}} + _vpriv.index.object:alter{parts=3D{3, 'string', 4, 'scalar'}} +end + +local function upgrade_to_1_10_2() + upgrade_space_priv_to_1_10_2() +end =20 local function get_version() local version =3D box.space._schema:get{'version'} @@ -991,6 +1013,7 @@ local function upgrade(options) {version =3D mkversion(1, 7, 6), func =3D upgrade_to_1_7_6, = auto =3D false}, {version =3D mkversion(1, 7, 7), func =3D upgrade_to_1_7_7, = auto =3D true}, {version =3D mkversion(1, 10, 0), func =3D upgrade_to_1_10_0, = auto =3D true}, + {version =3D mkversion(1, 10, 2), func =3D upgrade_to_1_10_2, = auto =3D true}, } =20 for _, handler in ipairs(handlers) do diff --git a/src/box/schema.cc b/src/box/schema.cc index 433f52c08..4502ca6dc 100644 --- a/src/box/schema.cc +++ b/src/box/schema.cc @@ -535,11 +535,14 @@ schema_find_name(enum schema_object_type type, = uint32_t object_id) { switch (type) { case SC_UNIVERSE: + case SC_ENTITY_SPACE: + case SC_ENTITY_FUNCTION: + case SC_ENTITY_SEQUENCE: + case SC_ENTITY_ROLE: + case SC_ENTITY_USER: return ""; case SC_SPACE: { - if (object_id =3D=3D 0) - return "SPACE"; struct space *space =3D space_by_id(object_id); if (space =3D=3D NULL) break; @@ -547,8 +550,6 @@ schema_find_name(enum schema_object_type type, = uint32_t object_id) } case SC_FUNCTION: { - if (object_id =3D=3D 0) - return "FUNCTION"; struct func *func =3D func_by_id(object_id); if (func =3D=3D NULL) break; @@ -556,8 +557,6 @@ schema_find_name(enum schema_object_type type, = uint32_t object_id) } case SC_SEQUENCE: { - if (object_id =3D=3D 0) - return "SEQUENCE"; struct sequence *seq =3D = sequence_by_id(object_id); if (seq =3D=3D NULL) break; diff --git a/src/box/schema.h b/src/box/schema.h index 0822262d0..f1735ff34 100644 --- a/src/box/schema.h +++ b/src/box/schema.h @@ -250,16 +250,19 @@ static inline struct access * entity_access_get(enum schema_object_type type) { - switch (type) { - case SC_SPACE: - return entity_access.space; - case SC_FUNCTION: - return entity_access.function; - case SC_SEQUENCE: - return entity_access.sequence; - default: - return NULL; - } + switch (type) { + case SC_SPACE: + case SC_ENTITY_SPACE: + return entity_access.space; + case SC_FUNCTION: + case SC_ENTITY_FUNCTION: + return entity_access.function; + case SC_SEQUENCE: + case SC_ENTITY_SEQUENCE: + return entity_access.sequence; + default: + return NULL; + } } =20 #endif /* INCLUDES_TARANTOOL_BOX_SCHEMA_H */ diff --git a/src/box/schema_def.c b/src/box/schema_def.c index 97c074ab2..bbae046c3 100644 --- a/src/box/schema_def.c +++ b/src/box/schema_def.c @@ -41,6 +41,13 @@ static const char *object_type_strs[] =3D { /* [SC_COLLATION] =3D */ "collation", }; =20 +enum schema_object_type +schema_entity_type(enum schema_object_type type) +{ + assert((int) type < (int) schema_object_type_MAX); + return type + schema_object_type_MAX - 1; +} + enum schema_object_type schema_object_type(const char *name) { diff --git a/src/box/schema_def.h b/src/box/schema_def.h index 2edb8d37f..5ece809f1 100644 --- a/src/box/schema_def.h +++ b/src/box/schema_def.h @@ -218,6 +218,10 @@ enum { * * Use 0 for unknown to use the same index consistently * even when there are more object types in the future. + * + * When adding new types please keep the + * same order between objects and corresponding entity types. + * schema_entity_type() relies on this convention. */ enum schema_object_type { SC_UNKNOWN =3D 0, @@ -228,9 +232,21 @@ enum schema_object_type { SC_ROLE =3D 5, SC_SEQUENCE =3D 6, SC_COLLATION =3D 7, - schema_object_type_MAX =3D 8 + schema_object_type_MAX =3D 8, + SC_ENTITY_SPACE, + SC_ENTITY_FUNCTION, + SC_ENTITY_USER, + SC_ENTITY_ROLE, + SC_ENTITY_SEQUENCE, + SC_ENTITY_COLLATION }; =20 +/** + * Given a object type, return an entity type it belongs to. + */ +enum schema_object_type +schema_entity_type(enum schema_object_type type); + enum schema_object_type schema_object_type(const char *name); =20 diff --git a/src/box/user.cc b/src/box/user.cc index fbf06566a..eec785652 100644 --- a/src/box/user.cc +++ b/src/box/user.cc @@ -207,12 +207,23 @@ access_find(struct priv_def *priv) access =3D universe.access; break; } + case SC_ENTITY_SPACE: + { + access =3D entity_access.space; + break; + } + case SC_ENTITY_FUNCTION: + { + access =3D entity_access.function; + break; + } + case SC_ENTITY_SEQUENCE: + { + access =3D entity_access.sequence; + break; + } case SC_SPACE: { - if (priv->object_id =3D=3D 0) { - access =3D entity_access.space; - break; - } struct space *space =3D space_by_id(priv->object_id); if (space) access =3D space->access; @@ -220,10 +231,6 @@ access_find(struct priv_def *priv) } case SC_FUNCTION: { - if (priv->object_id =3D=3D 0) { - access =3D entity_access.function; - break; - } struct func *func =3D func_by_id(priv->object_id); if (func) access =3D func->access; @@ -231,10 +238,6 @@ access_find(struct priv_def *priv) } case SC_SEQUENCE: { - if (priv->object_id =3D=3D 0) { - access =3D entity_access.sequence; - break; - } struct sequence *seq =3D = sequence_by_id(priv->object_id); if (seq) access =3D seq->access; diff --git a/test/box-py/bootstrap.result b/test/box-py/bootstrap.result index 16c2027cf..cf8242de5 100644 --- a/test/box-py/bootstrap.result +++ b/test/box-py/bootstrap.result @@ -5,7 +5,7 @@ box.space._schema:select{} --- - - ['cluster', ''] - ['max_id', 511] - - ['version', 1, 10, 0] + - ['version', 1, 10, 2] ... box.space._cluster:select{} --- @@ -58,10 +58,10 @@ box.space._space:select{} 'type': 'string'}, {'name': 'auth', 'type': 'map'}]] - [312, 1, '_priv', 'memtx', 0, {}, [{'name': 'grantor', 'type': = 'unsigned'}, { 'name': 'grantee', 'type': 'unsigned'}, {'name': 'object_type', = 'type': 'string'}, - {'name': 'object_id', 'type': 'unsigned'}, {'name': 'privilege', = 'type': 'unsigned'}]] + {'name': 'object_id', 'type': 'scalar'}, {'name': 'privilege', = 'type': 'unsigned'}]] - [313, 1, '_vpriv', 'sysview', 0, {}, [{'name': 'grantor', 'type': = 'unsigned'}, {'name': 'grantee', 'type': 'unsigned'}, {'name': 'object_type', = 'type': 'string'}, - {'name': 'object_id', 'type': 'unsigned'}, {'name': 'privilege', = 'type': 'unsigned'}]] + {'name': 'object_id', 'type': 'scalar'}, {'name': 'privilege', = 'type': 'unsigned'}]] - [320, 1, '_cluster', 'memtx', 0, {}, [{'name': 'id', 'type': = 'unsigned'}, {'name': 'uuid', 'type': 'string'}]] - [330, 1, '_truncate', 'memtx', 0, {}, [{'name': 'id', 'type': = 'unsigned'}, {'name': 'count', @@ -104,13 +104,13 @@ box.space._index:select{} - [305, 1, 'owner', 'tree', {'unique': false}, [[1, 'unsigned']]] - [305, 2, 'name', 'tree', {'unique': true}, [[2, 'string']]] - [312, 0, 'primary', 'tree', {'unique': true}, [[1, 'unsigned'], [2, = 'string'], - [3, 'unsigned']]] + [3, 'scalar']]] - [312, 1, 'owner', 'tree', {'unique': false}, [[0, 'unsigned']]] - - [312, 2, 'object', 'tree', {'unique': false}, [[2, 'string'], [3, = 'unsigned']]] + - [312, 2, 'object', 'tree', {'unique': false}, [[2, 'string'], [3, = 'scalar']]] - [313, 0, 'primary', 'tree', {'unique': true}, [[1, 'unsigned'], [2, = 'string'], - [3, 'unsigned']]] + [3, 'scalar']]] - [313, 1, 'owner', 'tree', {'unique': false}, [[0, 'unsigned']]] - - [313, 2, 'object', 'tree', {'unique': false}, [[2, 'string'], [3, = 'unsigned']]] + - [313, 2, 'object', 'tree', {'unique': false}, [[2, 'string'], [3, = 'scalar']]] - [320, 0, 'primary', 'tree', {'unique': true}, [[0, 'unsigned']]] - [320, 1, 'uuid', 'tree', {'unique': true}, [[1, 'string']]] - [330, 0, 'primary', 'tree', {'unique': true}, [[0, 'unsigned']]] diff --git a/test/box/access.result b/test/box/access.result index f4669a4a3..599500633 100644 --- a/test/box/access.result +++ b/test/box/access.result @@ -504,7 +504,7 @@ box.space._priv:select{id} ... box.schema.user.grant('user', 'read', 'universe') --- -- error: User 'user' already has read access on universe 'nil' +- error: User 'user' already has read access on universe '' ... box.space._priv:select{id} --- @@ -690,7 +690,7 @@ box.schema.user.grant('guest', 'read,write,execute', = 'universe') ... box.schema.user.grant('guest', 'read,write,execute', 'universe') --- -- error: User 'guest' already has read,write,execute access on universe = 'nil' +- error: User 'guest' already has read,write,execute access on universe = '' ... box.schema.user.grant('guest', 'read,write,execute', 'universe', '', { = if_not_exists =3D true }) --- @@ -703,7 +703,7 @@ box.schema.user.revoke('guest', 'usage,session', = 'universe') ... box.schema.user.revoke('guest', 'read,write,execute', 'universe') --- -- error: User 'guest' does not have read,write,execute access on = universe 'nil' +- error: User 'guest' does not have read,write,execute access on = universe '' ... box.schema.user.revoke('guest', 'read,write,execute', 'universe', '', { = if_exists =3D true }) --- diff --git a/test/box/access_misc.result b/test/box/access_misc.result index 2d87fa2d5..3061f1181 100644 --- a/test/box/access_misc.result +++ b/test/box/access_misc.result @@ -436,7 +436,7 @@ box.schema.user.revoke('testuser', 'usage,session', = 'universe') ... box.schema.user.revoke('testuser', 'read, write, execute', 'universe') --- -- error: User 'testuser' does not have read, write, execute access on = universe 'nil' +- error: User 'testuser' does not have read, write, execute access on = universe '' ... box.schema.user.revoke('testuser', 'create', 'universe') --- @@ -797,10 +797,10 @@ box.space._space:select() 'type': 'string'}, {'name': 'auth', 'type': 'map'}]] - [312, 1, '_priv', 'memtx', 0, {}, [{'name': 'grantor', 'type': = 'unsigned'}, { 'name': 'grantee', 'type': 'unsigned'}, {'name': 'object_type', = 'type': 'string'}, - {'name': 'object_id', 'type': 'unsigned'}, {'name': 'privilege', = 'type': 'unsigned'}]] + {'name': 'object_id', 'type': 'scalar'}, {'name': 'privilege', = 'type': 'unsigned'}]] - [313, 1, '_vpriv', 'sysview', 0, {}, [{'name': 'grantor', 'type': = 'unsigned'}, {'name': 'grantee', 'type': 'unsigned'}, {'name': 'object_type', = 'type': 'string'}, - {'name': 'object_id', 'type': 'unsigned'}, {'name': 'privilege', = 'type': 'unsigned'}]] + {'name': 'object_id', 'type': 'scalar'}, {'name': 'privilege', = 'type': 'unsigned'}]] - [320, 1, '_cluster', 'memtx', 0, {}, [{'name': 'id', 'type': = 'unsigned'}, {'name': 'uuid', 'type': 'string'}]] - [330, 1, '_truncate', 'memtx', 0, {}, [{'name': 'id', 'type': = 'unsigned'}, {'name': 'count', @@ -853,7 +853,7 @@ box.schema.user.grant('tester', 'read', 'universe') -- error: the privilege is not granted box.schema.user.revoke('tester', 'create', 'universe') --- -- error: User 'tester' does not have create access on universe 'nil' +- error: User 'tester' does not have create access on universe '' ... -- no error: if_exists clause box.schema.user.revoke('tester', 'create', 'universe', nil, { if_exists = =3D true }) diff --git a/test/box/alter.result b/test/box/alter.result index eb7014d8b..36bdb5fd3 100644 --- a/test/box/alter.result +++ b/test/box/alter.result @@ -214,13 +214,13 @@ _index:select{} - [305, 1, 'owner', 'tree', {'unique': false}, [[1, 'unsigned']]] - [305, 2, 'name', 'tree', {'unique': true}, [[2, 'string']]] - [312, 0, 'primary', 'tree', {'unique': true}, [[1, 'unsigned'], [2, = 'string'], - [3, 'unsigned']]] + [3, 'scalar']]] - [312, 1, 'owner', 'tree', {'unique': false}, [[0, 'unsigned']]] - - [312, 2, 'object', 'tree', {'unique': false}, [[2, 'string'], [3, = 'unsigned']]] + - [312, 2, 'object', 'tree', {'unique': false}, [[2, 'string'], [3, = 'scalar']]] - [313, 0, 'primary', 'tree', {'unique': true}, [[1, 'unsigned'], [2, = 'string'], - [3, 'unsigned']]] + [3, 'scalar']]] - [313, 1, 'owner', 'tree', {'unique': false}, [[0, 'unsigned']]] - - [313, 2, 'object', 'tree', {'unique': false}, [[2, 'string'], [3, = 'unsigned']]] + - [313, 2, 'object', 'tree', {'unique': false}, [[2, 'string'], [3, = 'scalar']]] - [320, 0, 'primary', 'tree', {'unique': true}, [[0, 'unsigned']]] - [320, 1, 'uuid', 'tree', {'unique': true}, [[1, 'string']]] - [330, 0, 'primary', 'tree', {'unique': true}, [[0, 'unsigned']]] diff --git a/test/xlog/upgrade.result b/test/xlog/upgrade.result index f02996bba..76467baf1 100644 --- a/test/xlog/upgrade.result +++ b/test/xlog/upgrade.result @@ -36,7 +36,7 @@ box.space._schema:select() --- - - ['cluster', ''] - ['max_id', 513] - - ['version', 1, 10, 0] + - ['version', 1, 10, 2] ... box.space._space:select() --- @@ -85,10 +85,10 @@ box.space._space:select() 'type': 'string'}, {'name': 'auth', 'type': 'map'}]] - [312, 1, '_priv', 'memtx', 0, {}, [{'name': 'grantor', 'type': = 'unsigned'}, { 'name': 'grantee', 'type': 'unsigned'}, {'name': 'object_type', = 'type': 'string'}, - {'name': 'object_id', 'type': 'unsigned'}, {'name': 'privilege', = 'type': 'unsigned'}]] + {'name': 'object_id', 'type': 'scalar'}, {'name': 'privilege', = 'type': 'unsigned'}]] - [313, 1, '_vpriv', 'sysview', 0, {}, [{'name': 'grantor', 'type': = 'unsigned'}, {'name': 'grantee', 'type': 'unsigned'}, {'name': 'object_type', = 'type': 'string'}, - {'name': 'object_id', 'type': 'unsigned'}, {'name': 'privilege', = 'type': 'unsigned'}]] + {'name': 'object_id', 'type': 'scalar'}, {'name': 'privilege', = 'type': 'unsigned'}]] - [320, 1, '_cluster', 'memtx', 0, {}, [{'name': 'id', 'type': = 'unsigned'}, {'name': 'uuid', 'type': 'string'}]] - [330, 1, '_truncate', 'memtx', 0, {}, [{'name': 'id', 'type': = 'unsigned'}, {'name': 'count', @@ -134,13 +134,13 @@ box.space._index:select() - [305, 1, 'owner', 'tree', {'unique': false}, [[1, 'unsigned']]] - [305, 2, 'name', 'tree', {'unique': true}, [[2, 'string']]] - [312, 0, 'primary', 'tree', {'unique': true}, [[1, 'unsigned'], [2, = 'string'], - [3, 'unsigned']]] + [3, 'scalar']]] - [312, 1, 'owner', 'tree', {'unique': false}, [[0, 'unsigned']]] - - [312, 2, 'object', 'tree', {'unique': false}, [[2, 'string'], [3, = 'unsigned']]] + - [312, 2, 'object', 'tree', {'unique': false}, [[2, 'string'], [3, = 'scalar']]] - [313, 0, 'primary', 'tree', {'unique': true}, [[1, 'unsigned'], [2, = 'string'], - [3, 'unsigned']]] + [3, 'scalar']]] - [313, 1, 'owner', 'tree', {'unique': false}, [[0, 'unsigned']]] - - [313, 2, 'object', 'tree', {'unique': false}, [[2, 'string'], [3, = 'unsigned']]] + - [313, 2, 'object', 'tree', {'unique': false}, [[2, 'string'], [3, = 'scalar']]] - [320, 0, 'primary', 'tree', {'unique': true}, [[0, 'unsigned']]] - [320, 1, 'uuid', 'tree', {'unique': true}, [[1, 'string']]] - [330, 0, 'primary', 'tree', {'unique': true}, [[0, 'unsigned']]] --=20 2.15.2 (Apple Git-101.1)