Skip to content

Commit 206f8bd

Browse files
box: support space and index names in IPROTO requests
Add support for accepting IPROTO requests with space or index name instead of identifier (identifier is preferred over name): remove `space_id` key from mandatory keys and delay resolution of space identifier until request gets to transaction thread. Add support for sending CRUD requests from net.box connection objects with disabled schema fetching by manually specifying space or index name or identifier: when schema fetching is disabled, the space and index tables of connections return wrapper tables that store necessary context (space or index name or identifier, determined by type, connection object and space for indexes) for performing requests. Closes #8146 @TarantoolBot document Title: Space and index name in IPROTO requests Refer to design document for details: https://www.notion.so/tarantool/Schemafull-IPROTO-cc315ad6bdd641dea66ad854992d8cbf?pvs=4#f4d4b3fa2b3646f1949319866428b6c0
1 parent 442ee72 commit 206f8bd

16 files changed

+266
-47
lines changed
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
## feature/box
2+
3+
* Added support for accepting IPROTO requests with space or index name instead
4+
of identifier (gh-8146).
5+
6+
## feature/net.box
7+
8+
* Added support for sending CRUD requests from connection objects with disabled
9+
schema fetching by manually specifying space or index name or identifier
10+
(gh-8146).

src/box/iproto.cc

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2138,6 +2138,39 @@ tx_process_rollback(struct cmsg *m)
21382138
tx_end_msg(msg, &header);
21392139
}
21402140

2141+
/*
2142+
* In case the request does not contain a space or identifier but contains a
2143+
* corresponding name, tries to resolve the name.
2144+
* A space identifier is mandatory for a CRUD request, so in case the space
2145+
* identifier is not present in the request and we fail to get an identifier
2146+
* from the space name (or the space name is missing), we must return with an
2147+
* error, setting a missing request field diagnostic, just as it was done in
2148+
* `xrow_decode_dml` before space names in IPROTO requests were introduced.
2149+
*/
2150+
static int
2151+
tx_resolve_space_and_index_name(struct request *dml)
2152+
{
2153+
if (dml->space_id == 0 && dml->space_name != NULL) {
2154+
uint32_t space_id = box_space_id_by_name(dml->space_name,
2155+
dml->space_name_len);
2156+
if (space_id != BOX_ID_NIL)
2157+
dml->space_id = space_id;
2158+
}
2159+
if (dml->space_id == 0) {
2160+
diag_set(ClientError, ER_MISSING_REQUEST_FIELD,
2161+
iproto_key_name(IPROTO_SPACE_ID));
2162+
return -1;
2163+
}
2164+
if (dml->index_id == 0 && dml->index_name != NULL) {
2165+
uint32_t index_id = box_index_id_by_name(dml->space_id,
2166+
dml->index_name,
2167+
dml->index_name_len);
2168+
if (index_id != BOX_ID_NIL)
2169+
dml->index_id = index_id;
2170+
}
2171+
return 0;
2172+
}
2173+
21412174
static void
21422175
tx_process1(struct cmsg *m)
21432176
{
@@ -2149,6 +2182,8 @@ tx_process1(struct cmsg *m)
21492182
struct obuf_svp svp;
21502183
struct obuf *out;
21512184
tx_inject_delay();
2185+
if (tx_resolve_space_and_index_name(&msg->dml) != 0)
2186+
goto error;
21522187
if (box_process1(&msg->dml, &tuple) != 0)
21532188
goto error;
21542189
out = msg->connection->tx.p_obuf;
@@ -2185,6 +2220,8 @@ tx_process_select(struct cmsg *m)
21852220
goto error;
21862221

21872222
tx_inject_delay();
2223+
if (tx_resolve_space_and_index_name(&msg->dml) != 0)
2224+
goto error;
21882225
packed_pos = req->after_position;
21892226
packed_pos_end = req->after_position_end;
21902227
if (packed_pos != NULL) {

src/box/iproto_constants.c

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,8 @@ const unsigned char iproto_key_type[IPROTO_KEY_MAX] =
152152
/* 0x59 */ MP_UINT, /* IPROTO_TXN_ISOLATION */
153153
/* 0x5a */ MP_UINT, /* IPROTO_VCLOCK_SYNC */
154154
/* 0x5b */ MP_STR, /* IPROTO_AUTH_TYPE */
155+
/* 0x5c */ MP_STR, /* IPROTO_SPACE_NAME */
156+
/* 0x5d */ MP_STR, /* IPROTO_INDEX_NAME */
155157
/* }}} */
156158
};
157159

@@ -179,15 +181,15 @@ const char *iproto_type_strs[] =
179181
#define bit(c) (1ULL<<IPROTO_##c)
180182
const uint64_t iproto_body_key_map[IPROTO_TYPE_STAT_MAX] = {
181183
0, /* unused */
182-
bit(SPACE_ID) | bit(LIMIT) | bit(KEY), /* SELECT */
183-
bit(SPACE_ID) | bit(TUPLE), /* INSERT */
184-
bit(SPACE_ID) | bit(TUPLE), /* REPLACE */
185-
bit(SPACE_ID) | bit(KEY) | bit(TUPLE), /* UPDATE */
186-
bit(SPACE_ID) | bit(KEY), /* DELETE */
184+
bit(LIMIT) | bit(KEY), /* SELECT */
185+
bit(TUPLE), /* INSERT */
186+
bit(TUPLE), /* REPLACE */
187+
bit(KEY) | bit(TUPLE), /* UPDATE */
188+
bit(KEY), /* DELETE */
187189
0, /* CALL_16 */
188190
0, /* AUTH */
189191
0, /* EVAL */
190-
bit(SPACE_ID) | bit(OPS) | bit(TUPLE), /* UPSERT */
192+
bit(OPS) | bit(TUPLE), /* UPSERT */
191193
0, /* CALL */
192194
0, /* EXECUTE */
193195
0, /* NOP */

src/box/iproto_constants.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,17 @@ enum iproto_key {
179179
* authentication method.
180180
*/
181181
IPROTO_AUTH_TYPE = 0x5b,
182+
/**
183+
* Space name used instead of identifier (IPROTO_SPACE_ID) in CRUD
184+
* requests. Ignored when identifier is present.
185+
*/
186+
IPROTO_SPACE_NAME = 0x5c,
187+
/**
188+
* Index name used instead of identifier (IPROTO_INDEX_ID) in
189+
* IPROTO_SELECT and IPROTO_DELETE requests. Ignored when identifier is
190+
* present.
191+
*/
192+
IPROTO_INDEX_NAME = 0x5d,
182193
/*
183194
* Be careful to not extend iproto_key values over 0x7f.
184195
* iproto_keys are encoded in msgpack as positive fixnum, which ends at

src/box/iproto_features.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,4 +68,6 @@ iproto_features_init(void)
6868
IPROTO_FEATURE_WATCHERS);
6969
iproto_features_set(&IPROTO_CURRENT_FEATURES,
7070
IPROTO_FEATURE_PAGINATION);
71+
iproto_features_set(&IPROTO_CURRENT_FEATURES,
72+
IPROTO_FEATURE_SPACE_AND_INDEX_NAMES);
7173
}

src/box/iproto_features.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,14 @@ enum iproto_feature_id {
5353
* request fields and IPROTO_POSITION response field.
5454
*/
5555
IPROTO_FEATURE_PAGINATION = 4,
56+
/**
57+
* Using space [index] names instead of identifiers support:
58+
* IPROTO_SPACE_NAME and IPROTO_INDEX_NAME fields in IPROTO_SELECT and
59+
* IPROTO_DELETE request body;
60+
* IPROTO_SPACE_NAME field in IPROTO_INSERT, IPROTO_REPLACE,
61+
* IPROTO_UPDATE and IPROTO_UPSERT request body.
62+
*/
63+
IPROTO_FEATURE_SPACE_AND_INDEX_NAMES = 5,
5664
iproto_feature_id_MAX,
5765
};
5866

@@ -69,7 +77,7 @@ struct iproto_features {
6977
* `box.iproto.protocol_version` needs to be updated correspondingly.
7078
*/
7179
enum {
72-
IPROTO_CURRENT_VERSION = 4,
80+
IPROTO_CURRENT_VERSION = 5,
7381
};
7482

7583
/**

src/box/lua/iproto.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,8 @@ push_iproto_key_enum(struct lua_State *L)
134134
{"EVENT_DATA", IPROTO_EVENT_DATA},
135135
{"TXN_ISOLATION", IPROTO_TXN_ISOLATION},
136136
{"VCLOCK_SYNC", IPROTO_VCLOCK_SYNC},
137+
{"SPACE_NAME", IPROTO_SPACE_NAME},
138+
{"INDEX_NAME", IPROTO_INDEX_NAME},
137139
};
138140
push_iproto_constant_subnamespace(L, "key", keys, lengthof(keys));
139141
for (size_t i = 0; i < lengthof(keys); ++i) {
@@ -293,6 +295,7 @@ push_iproto_protocol_features(struct lua_State *L)
293295
{"error_extension", IPROTO_FEATURE_ERROR_EXTENSION},
294296
{"watchers", IPROTO_FEATURE_WATCHERS},
295297
{"pagination", IPROTO_FEATURE_PAGINATION},
298+
{"space_and_index_names", IPROTO_FEATURE_SPACE_AND_INDEX_NAMES},
296299
};
297300

298301
lua_createtable(L, 0, lengthof(features));

src/box/lua/net_box.c

Lines changed: 48 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -797,6 +797,44 @@ netbox_encode_eval(lua_State *L, int idx, struct mpstream *stream,
797797
netbox_end_encode(stream, svp);
798798
}
799799

800+
/*
801+
* Depending on the type of the 'id' argument (see also net.box space metatable)
802+
* encode either a space identifier or a space name.
803+
*/
804+
static void
805+
netbox_encode_space_id_or_name(lua_State *L, int idx, struct mpstream *stream)
806+
{
807+
if (lua_type(L, idx) == LUA_TNUMBER) {
808+
uint32_t space_id = lua_tonumber(L, idx);
809+
mpstream_encode_uint(stream, IPROTO_SPACE_ID);
810+
mpstream_encode_uint(stream, space_id);
811+
} else {
812+
size_t len;
813+
const char *space_name = lua_tolstring(L, idx, &len);
814+
mpstream_encode_uint(stream, IPROTO_SPACE_NAME);
815+
mpstream_encode_strn(stream, space_name, len);
816+
}
817+
}
818+
819+
/*
820+
* Depending on the type of the 'id' argument (see also net.box index metatable)
821+
* encode either a index identifier or an index name.
822+
*/
823+
static void
824+
netbox_encode_index_id_or_name(lua_State *L, int idx, struct mpstream *stream)
825+
{
826+
if (lua_type(L, idx) == LUA_TNUMBER) {
827+
uint32_t space_id = lua_tonumber(L, idx);
828+
mpstream_encode_uint(stream, IPROTO_INDEX_ID);
829+
mpstream_encode_uint(stream, space_id);
830+
} else {
831+
size_t len;
832+
const char *space_name = lua_tolstring(L, idx, &len);
833+
mpstream_encode_uint(stream, IPROTO_INDEX_NAME);
834+
mpstream_encode_strn(stream, space_name, len);
835+
}
836+
}
837+
800838
/* Encode select request. */
801839
static void
802840
netbox_encode_select(lua_State *L, int idx, struct mpstream *stream,
@@ -817,19 +855,13 @@ netbox_encode_select(lua_State *L, int idx, struct mpstream *stream,
817855
if (fetch_pos)
818856
map_size++;
819857
mpstream_encode_map(stream, map_size);
820-
uint32_t space_id = lua_tonumber(L, idx);
821-
uint32_t index_id = lua_tonumber(L, idx + 1);
822858
int iterator = lua_tointeger(L, idx + 2);
823859
uint32_t offset = lua_tonumber(L, idx + 3);
824860
uint32_t limit = lua_tonumber(L, idx + 4);
825861

826-
/* encode space_id */
827-
mpstream_encode_uint(stream, IPROTO_SPACE_ID);
828-
mpstream_encode_uint(stream, space_id);
862+
netbox_encode_space_id_or_name(L, idx, stream);
829863

830-
/* encode index_id */
831-
mpstream_encode_uint(stream, IPROTO_INDEX_ID);
832-
mpstream_encode_uint(stream, index_id);
864+
netbox_encode_index_id_or_name(L, idx + 1, stream);
833865

834866
/* encode iterator */
835867
mpstream_encode_uint(stream, IPROTO_ITERATOR);
@@ -881,10 +913,7 @@ netbox_encode_insert_or_replace(lua_State *L, int idx, struct mpstream *stream,
881913

882914
mpstream_encode_map(stream, 2);
883915

884-
/* encode space_id */
885-
uint32_t space_id = lua_tonumber(L, idx);
886-
mpstream_encode_uint(stream, IPROTO_SPACE_ID);
887-
mpstream_encode_uint(stream, space_id);
916+
netbox_encode_space_id_or_name(L, idx, stream);
888917

889918
/* encode args */
890919
mpstream_encode_uint(stream, IPROTO_TUPLE);
@@ -919,15 +948,9 @@ netbox_encode_delete(lua_State *L, int idx, struct mpstream *stream,
919948

920949
mpstream_encode_map(stream, 3);
921950

922-
/* encode space_id */
923-
uint32_t space_id = lua_tonumber(L, idx);
924-
mpstream_encode_uint(stream, IPROTO_SPACE_ID);
925-
mpstream_encode_uint(stream, space_id);
951+
netbox_encode_space_id_or_name(L, idx, stream);
926952

927-
/* encode space_id */
928-
uint32_t index_id = lua_tonumber(L, idx + 1);
929-
mpstream_encode_uint(stream, IPROTO_INDEX_ID);
930-
mpstream_encode_uint(stream, index_id);
953+
netbox_encode_index_id_or_name(L, idx + 1, stream);
931954

932955
/* encode key */
933956
mpstream_encode_uint(stream, IPROTO_KEY);
@@ -946,15 +969,9 @@ netbox_encode_update(lua_State *L, int idx, struct mpstream *stream,
946969

947970
mpstream_encode_map(stream, 5);
948971

949-
/* encode space_id */
950-
uint32_t space_id = lua_tonumber(L, idx);
951-
mpstream_encode_uint(stream, IPROTO_SPACE_ID);
952-
mpstream_encode_uint(stream, space_id);
972+
netbox_encode_space_id_or_name(L, idx, stream);
953973

954-
/* encode index_id */
955-
uint32_t index_id = lua_tonumber(L, idx + 1);
956-
mpstream_encode_uint(stream, IPROTO_INDEX_ID);
957-
mpstream_encode_uint(stream, index_id);
974+
netbox_encode_index_id_or_name(L, idx + 1, stream);
958975

959976
/* encode index_id */
960977
mpstream_encode_uint(stream, IPROTO_INDEX_BASE);
@@ -981,10 +998,7 @@ netbox_encode_upsert(lua_State *L, int idx, struct mpstream *stream,
981998

982999
mpstream_encode_map(stream, 4);
9831000

984-
/* encode space_id */
985-
uint32_t space_id = lua_tonumber(L, idx);
986-
mpstream_encode_uint(stream, IPROTO_SPACE_ID);
987-
mpstream_encode_uint(stream, space_id);
1001+
netbox_encode_space_id_or_name(L, idx, stream);
9881002

9891003
/* encode index_base */
9901004
mpstream_encode_uint(stream, IPROTO_INDEX_BASE);
@@ -3000,6 +3014,8 @@ luaopen_net_box(struct lua_State *L)
30003014
IPROTO_FEATURE_WATCHERS);
30013015
iproto_features_set(&NETBOX_IPROTO_FEATURES,
30023016
IPROTO_FEATURE_PAGINATION);
3017+
iproto_features_set(&NETBOX_IPROTO_FEATURES,
3018+
IPROTO_FEATURE_SPACE_AND_INDEX_NAMES);
30033019

30043020
lua_pushcfunction(L, luaT_netbox_request_iterator_next);
30053021
luaT_netbox_request_iterator_next_ref = luaL_ref(L, LUA_REGISTRYINDEX);

src/box/lua/net_box.lua

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ local IPROTO_FEATURE_NAMES = {
5959
[2] = 'error_extension',
6060
[3] = 'watchers',
6161
[4] = 'pagination',
62+
[5] = 'space_and_index_names',
6263
}
6364

6465
local REQUEST_OPTION_TYPES = {
@@ -390,6 +391,24 @@ local function new_sm(uri, opts)
390391
})
391392
end
392393
end
394+
if not opts.fetch_schema and features.space_and_index_names then
395+
remote.space = setmetatable({_remote = remote}, {
396+
__index = function(self, key)
397+
local space = {id = key, name = key,
398+
_remote = self._remote,
399+
_format_cdata =
400+
box.internal.new_tuple_format()}
401+
space.index = setmetatable({space = space,
402+
_remote = remote}, {
403+
__index = function(self, key)
404+
return setmetatable({id = key, name = key,
405+
space = self.space,
406+
_remote = self._remote},
407+
self._remote._index_mt)
408+
end})
409+
return setmetatable(space, self._remote._space_mt)
410+
end})
411+
end
393412
elseif what == 'did_fetch_schema' then
394413
remote:_install_schema(...)
395414
elseif what == 'event' then

src/box/xrow.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -959,6 +959,14 @@ xrow_decode_dml(struct xrow_header *row, struct request *request,
959959
request->after_tuple = value;
960960
request->after_tuple_end = data;
961961
break;
962+
case IPROTO_SPACE_NAME:
963+
request->space_name =
964+
mp_decode_str(&value, &request->space_name_len);
965+
break;
966+
case IPROTO_INDEX_NAME:
967+
request->index_name =
968+
mp_decode_str(&value, &request->index_name_len);
969+
break;
962970
default:
963971
break;
964972
}

src/box/xrow.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,14 @@ struct request {
215215
int index_base;
216216
/** Send position of last selected tuple in response if true. */
217217
bool fetch_position;
218+
/** Name of requested space, points to the request's input buffer. */
219+
const char *space_name;
220+
/** Length of @space_name. */
221+
uint32_t space_name_len;
222+
/** Name of requested index, points to the request's input buffer. */
223+
const char *index_name;
224+
/** Length of @index_name. */
225+
uint32_t index_name_len;
218226
};
219227

220228
/**

test/box-luatest/gh_7894_export_iproto_constants_and_features_test.lua

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,8 @@ local reference_table = {
7979
EVENT_DATA = 0x58,
8080
TXN_ISOLATION = 0x59,
8181
VCLOCK_SYNC = 0x5a,
82+
SPACE_NAME = 0x5c,
83+
INDEX_NAME = 0x5d,
8284
},
8385

8486
-- `iproto_metadata_key` enumeration.
@@ -157,7 +159,7 @@ local reference_table = {
157159
},
158160

159161
-- `IPROTO_CURRENT_VERSION` constant
160-
protocol_version = 4,
162+
protocol_version = 5,
161163

162164
-- `feature_id` enumeration
163165
protocol_features = {
@@ -166,13 +168,15 @@ local reference_table = {
166168
error_extension = true,
167169
watchers = true,
168170
pagination = true,
171+
space_and_index_names = true,
169172
},
170173
feature = {
171174
streams = 0,
172175
transactions = 1,
173176
error_extension = 2,
174177
watchers = 3,
175178
pagination = 4,
179+
space_and_index_names = 5,
176180
},
177181
}
178182

0 commit comments

Comments
 (0)