<HTML><BODY><div id="composeWebView_editable_content" data-mailruapp-compose-id="composeWebView_editable_content" style="text-align: left;"><div>Thanks, LGTM.</div><div><br></div><div id="mail-app-auto-signature">
Best regards,<div>Sergos </div>
</div><br><br>Saturday, 14 December 2019, 02:34 +0300 from Vladislav Shpilevoy <v.shpilevoy@tarantool.org>:<br><div id="composeWebView_previouse_content" data-mailruapp-compose-id="composeWebView_previouse_content"><blockquote id="mail-app-auto-quote" style="border-left-width: 1px; border-left-style: solid; border-left-color: rgb(11, 102, 249); margin: 10px 0px 10px 5px; padding: 0px 0px 0px 10px; display: inherit;" data-darkosha-id="1:3"><div class="js-helper js-readmsg-msg" data-darkosha-id="1:4" style="">
<style type="text/css" data-darkosha-id="1:5" style=""></style>
<div data-darkosha-id="1:6" style="">
<base target="_self" href="https://e.mail.ru/" data-darkosha-id="1:7" style="">
<div id="style_15762800670404139732_BODY" data-darkosha-id="1:8" style="">Hi! Thanks for the review!<br data-darkosha-id="1:9" style="">
<br data-darkosha-id="1:10" style="">
On 09/12/2019 21:18, Sergey Ostanevich wrote:<br data-darkosha-id="1:11" style="">
> Hi! <br data-darkosha-id="1:12" style="">
> <br data-darkosha-id="1:13" style="">
> Thanks for the patch!<br data-darkosha-id="1:14" style="">
> Please, see 4 comments below.<br data-darkosha-id="1:15" style="">
> <br data-darkosha-id="1:16" style="">
> Regards,<br data-darkosha-id="1:17" style="">
> Sergos<br data-darkosha-id="1:18" style="">
> <br data-darkosha-id="1:19" style="">
> <br data-darkosha-id="1:20" style="">
>> diff --git a/src/box/vinyl.c b/src/box/vinyl.c<br data-darkosha-id="1:21" style="">
>> index 767e40006..15a136f81 100644<br data-darkosha-id="1:22" style="">
>> --- a/src/box/vinyl.c<br data-darkosha-id="1:23" style="">
>> +++ b/src/box/vinyl.c<br data-darkosha-id="1:24" style="">
>> @@ -2004,13 +2004,25 @@ request_normalize_ops(struct request *request)<br data-darkosha-id="1:25" style="">
>> ops_end = mp_encode_str(ops_end, op_name, op_name_len);<br data-darkosha-id="1:26" style="">
>> <br data-darkosha-id="1:27" style="">
>> int field_no;<br data-darkosha-id="1:28" style="">
>> - if (mp_typeof(*pos) == MP_INT) {<br data-darkosha-id="1:29" style="">
>> + const char *field_name;<br data-darkosha-id="1:30" style="">
>> + switch (mp_typeof(*pos)) {<br data-darkosha-id="1:31" style="">
>> + case MP_INT:<br data-darkosha-id="1:32" style="">
>> field_no = mp_decode_int(&pos);<br data-darkosha-id="1:33" style="">
>> ops_end = mp_encode_int(ops_end, field_no);<br data-darkosha-id="1:34" style="">
>> - } else {<br data-darkosha-id="1:35" style="">
>> + break;<br data-darkosha-id="1:36" style="">
>> + case MP_UINT:<br data-darkosha-id="1:37" style="">
>> field_no = mp_decode_uint(&pos);<br data-darkosha-id="1:38" style="">
>> field_no -= request->index_base;<br data-darkosha-id="1:39" style="">
>> ops_end = mp_encode_uint(ops_end, field_no);<br data-darkosha-id="1:40" style="">
>> + break;<br data-darkosha-id="1:41" style="">
>> + case MP_STR:<br data-darkosha-id="1:42" style="">
>> + field_name = pos;<br data-darkosha-id="1:43" style="">
>> + mp_next(&pos);<br data-darkosha-id="1:44" style="">
>> + memcpy(ops_end, field_name, pos - field_name);<br data-darkosha-id="1:45" style="">
>> + ops_end += pos - field_name;<br data-darkosha-id="1:46" style="">
>> + break;<br data-darkosha-id="1:47" style="">
> <br data-darkosha-id="1:48" style="">
> Are you intentionally skip encode/decode here? Is it safe enough?<br data-darkosha-id="1:49" style="">
<br data-darkosha-id="1:50" style="">
mp_next() does decode. Memcpy is the same as encode here. Just without<br data-darkosha-id="1:51" style="">
'if's. It is safe.<br data-darkosha-id="1:52" style="">
<br data-darkosha-id="1:53" style="">
>> diff --git a/src/box/xrow_update.c b/src/box/xrow_update.c<br data-darkosha-id="1:54" style="">
>> index 123db081a..ecda17544 100644<br data-darkosha-id="1:55" style="">
>> --- a/src/box/xrow_update.c<br data-darkosha-id="1:56" style="">
>> +++ b/src/box/xrow_update.c<br data-darkosha-id="1:57" style="">
>> @@ -412,6 +434,15 @@ xrow_upsert_squash(const char *expr1, const char *expr1_end,<br data-darkosha-id="1:58" style="">
>> if (op->opcode != '+' && op->opcode != '-' &&<br data-darkosha-id="1:59" style="">
>> op->opcode != '=')<br data-darkosha-id="1:60" style="">
>> return NULL;<br data-darkosha-id="1:61" style="">
>> + /*<br data-darkosha-id="1:62" style="">
>> + * Not terminal operation means, that the<br data-darkosha-id="1:63" style="">
>> + * update is not flat, and squash would<br data-darkosha-id="1:64" style="">
>> + * need to build a tree of operations to<br data-darkosha-id="1:65" style="">
>> + * find matches. That is too complex,<br data-darkosha-id="1:66" style="">
>> + * squash is skipped.<br data-darkosha-id="1:67" style="">
>> + */<br data-darkosha-id="1:68" style="">
>> + if (! xrow_update_op_is_term(op))<br data-darkosha-id="1:69" style="">
>> + return NULL;<br data-darkosha-id="1:70" style="">
> <br data-darkosha-id="1:71" style="">
> Please, no space after unary op - and further on in the patch -<br data-darkosha-id="1:72" style="">
> according to $3.1 of<br data-darkosha-id="1:73" style="">
> <a href="https://www.tarantool.io/en/doc/2.2/dev_guide/c_style_guide/" target="_blank" data-darkosha-id="1:74" style="">https://www.tarantool.io/en/doc/2.2/dev_guide/c_style_guide/</a><br data-darkosha-id="1:75" style="">
> <br data-darkosha-id="1:76" style="">
<br data-darkosha-id="1:77" style="">
Ok, here it is:<br data-darkosha-id="1:78" style="">
<br data-darkosha-id="1:79" style="">
==============================================================================<br data-darkosha-id="1:80" style="">
<br data-darkosha-id="1:81" style="">
diff --git a/src/box/xrow_update.c b/src/box/xrow_update.c<br data-darkosha-id="1:82" style="">
index ecda17544..0cee50017 100644<br data-darkosha-id="1:83" style="">
--- a/src/box/xrow_update.c<br data-darkosha-id="1:84" style="">
+++ b/src/box/xrow_update.c<br data-darkosha-id="1:85" style="">
@@ -441,7 +441,7 @@ xrow_upsert_squash(const char *expr1, const char *expr1_end,<br data-darkosha-id="1:86" style="">
* find matches. That is too complex,<br data-darkosha-id="1:87" style="">
* squash is skipped.<br data-darkosha-id="1:88" style="">
*/<br data-darkosha-id="1:89" style="">
- if (! xrow_update_op_is_term(op))<br data-darkosha-id="1:90" style="">
+ if (!xrow_update_op_is_term(op))<br data-darkosha-id="1:91" style="">
return NULL;<br data-darkosha-id="1:92" style="">
if (op->field_no <= prev_field_no)<br data-darkosha-id="1:93" style="">
return NULL;<br data-darkosha-id="1:94" style="">
diff --git a/src/box/xrow_update_array.c b/src/box/xrow_update_array.c<br data-darkosha-id="1:95" style="">
index 1cc49f861..57427e39c 100644<br data-darkosha-id="1:96" style="">
--- a/src/box/xrow_update_array.c<br data-darkosha-id="1:97" style="">
+++ b/src/box/xrow_update_array.c<br data-darkosha-id="1:98" style="">
@@ -221,7 +221,7 @@ xrow_update_op_do_array_insert(struct xrow_update_op *op,<br data-darkosha-id="1:99" style="">
{<br data-darkosha-id="1:100" style="">
assert(field->type == XUPDATE_ARRAY);<br data-darkosha-id="1:101" style="">
struct xrow_update_array_item *item;<br data-darkosha-id="1:102" style="">
- if (! xrow_update_op_is_term(op)) {<br data-darkosha-id="1:103" style="">
+ if (!xrow_update_op_is_term(op)) {<br data-darkosha-id="1:104" style="">
item = xrow_update_array_extract_item(field, op);<br data-darkosha-id="1:105" style="">
if (item == NULL)<br data-darkosha-id="1:106" style="">
return -1;<br data-darkosha-id="1:107" style="">
@@ -256,7 +256,7 @@ xrow_update_op_do_array_set(struct xrow_update_op *op,<br data-darkosha-id="1:108" style="">
xrow_update_array_extract_item(field, op);<br data-darkosha-id="1:109" style="">
if (item == NULL)<br data-darkosha-id="1:110" style="">
return -1;<br data-darkosha-id="1:111" style="">
- if (! xrow_update_op_is_term(op))<br data-darkosha-id="1:112" style="">
+ if (!xrow_update_op_is_term(op))<br data-darkosha-id="1:113" style="">
return xrow_update_op_do_field_set(op, &item->field);<br data-darkosha-id="1:114" style="">
op->new_field_len = op->arg.set.length;<br data-darkosha-id="1:115" style="">
/*<br data-darkosha-id="1:116" style="">
@@ -275,7 +275,7 @@ xrow_update_op_do_array_delete(struct xrow_update_op *op,<br data-darkosha-id="1:117" style="">
struct xrow_update_field *field)<br data-darkosha-id="1:118" style="">
{<br data-darkosha-id="1:119" style="">
assert(field->type == XUPDATE_ARRAY);<br data-darkosha-id="1:120" style="">
- if (! xrow_update_op_is_term(op)) {<br data-darkosha-id="1:121" style="">
+ if (!xrow_update_op_is_term(op)) {<br data-darkosha-id="1:122" style="">
struct xrow_update_array_item *item =<br data-darkosha-id="1:123" style="">
xrow_update_array_extract_item(field, op);<br data-darkosha-id="1:124" style="">
if (item == NULL)<br data-darkosha-id="1:125" style="">
@@ -305,7 +305,7 @@ xrow_update_op_do_array_##op_type(struct xrow_update_op *op, \<br data-darkosha-id="1:126" style="">
xrow_update_array_extract_item(field, op); \<br data-darkosha-id="1:127" style="">
if (item == NULL) \<br data-darkosha-id="1:128" style="">
return -1; \<br data-darkosha-id="1:129" style="">
- if (! xrow_update_op_is_term(op)) \<br data-darkosha-id="1:130" style="">
+ if (!xrow_update_op_is_term(op)) \<br data-darkosha-id="1:131" style="">
return xrow_update_op_do_field_##op_type(op, &item->field); \<br data-darkosha-id="1:132" style="">
if (item->field.type != XUPDATE_NOP) \<br data-darkosha-id="1:133" style="">
return xrow_update_err_double(op); \<br data-darkosha-id="1:134" style="">
diff --git a/src/box/xrow_update_bar.c b/src/box/xrow_update_bar.c<br data-darkosha-id="1:135" style="">
index 737673e8a..7285c7e2b 100644<br data-darkosha-id="1:136" style="">
--- a/src/box/xrow_update_bar.c<br data-darkosha-id="1:137" style="">
+++ b/src/box/xrow_update_bar.c<br data-darkosha-id="1:138" style="">
@@ -58,7 +58,7 @@ xrow_update_bar_locate(struct xrow_update_op *op,<br data-darkosha-id="1:139" style="">
* non empty path. This is why op is expected to be not<br data-darkosha-id="1:140" style="">
* terminal.<br data-darkosha-id="1:141" style="">
*/<br data-darkosha-id="1:142" style="">
- assert(! xrow_update_op_is_term(op));<br data-darkosha-id="1:143" style="">
+ assert(!xrow_update_op_is_term(op));<br data-darkosha-id="1:144" style="">
int rc;<br data-darkosha-id="1:145" style="">
field->type = XUPDATE_BAR;<br data-darkosha-id="1:146" style="">
field->bar.op = op;<br data-darkosha-id="1:147" style="">
@@ -113,7 +113,7 @@ xrow_update_bar_locate_opt(struct xrow_update_op *op,<br data-darkosha-id="1:148" style="">
* non empty path. This is why op is expected to be not<br data-darkosha-id="1:149" style="">
* terminal.<br data-darkosha-id="1:150" style="">
*/<br data-darkosha-id="1:151" style="">
- assert(! xrow_update_op_is_term(op));<br data-darkosha-id="1:152" style="">
+ assert(!xrow_update_op_is_term(op));<br data-darkosha-id="1:153" style="">
int rc;<br data-darkosha-id="1:154" style="">
field->type = XUPDATE_BAR;<br data-darkosha-id="1:155" style="">
field->bar.op = op;<br data-darkosha-id="1:156" style="">
@@ -245,7 +245,7 @@ xrow_update_op_do_nop_set(struct xrow_update_op *op,<br data-darkosha-id="1:157" style="">
if (xrow_update_bar_locate_opt(op, field, &is_found, &key_len) != 0)<br data-darkosha-id="1:158" style="">
return -1;<br data-darkosha-id="1:159" style="">
op->new_field_len = op->arg.set.length;<br data-darkosha-id="1:160" style="">
- if (! is_found) {<br data-darkosha-id="1:161" style="">
+ if (!is_found) {<br data-darkosha-id="1:162" style="">
op->opcode = '!';<br data-darkosha-id="1:163" style="">
if (mp_typeof(*field->bar.parent) == MP_MAP)<br data-darkosha-id="1:164" style="">
op->new_field_len += mp_sizeof_str(key_len);<br data-darkosha-id="1:165" style="">
<br data-darkosha-id="1:166" style="">
==============================================================================<br data-darkosha-id="1:167" style="">
<br data-darkosha-id="1:168" style="">
>> diff --git a/src/box/xrow_update_bar.c b/src/box/xrow_update_bar.c<br data-darkosha-id="1:169" style="">
>> new file mode 100644<br data-darkosha-id="1:170" style="">
>> index 000000000..737673e8a<br data-darkosha-id="1:171" style="">
>> --- /dev/null<br data-darkosha-id="1:172" style="">
>> +++ b/src/box/xrow_update_bar.c<br data-darkosha-id="1:173" style="">
>> +static inline int<br data-darkosha-id="1:174" style="">
>> +xrow_update_bar_locate_opt(struct xrow_update_op *op,<br data-darkosha-id="1:175" style="">
>> + struct xrow_update_field *field, bool *is_found,<br data-darkosha-id="1:176" style="">
>> + int *key_len_or_index)<br data-darkosha-id="1:177" style="">
>> +{<br data-darkosha-id="1:178" style="">
>> + /*<br data-darkosha-id="1:179" style="">
>> + * Bar update is not flat by definition. It always has a<br data-darkosha-id="1:180" style="">
>> + * non empty path. This is why op is expected to be not<br data-darkosha-id="1:181" style="">
>> + * terminal.<br data-darkosha-id="1:182" style="">
>> + */<br data-darkosha-id="1:183" style="">
>> + assert(! xrow_update_op_is_term(op));<br data-darkosha-id="1:184" style="">
>> + int rc;<br data-darkosha-id="1:185" style="">
>> + field->type = XUPDATE_BAR;<br data-darkosha-id="1:186" style="">
>> + field->bar.op = op;<br data-darkosha-id="1:187" style="">
>> + field->bar.path = op->lexer.src + op->lexer.offset;<br data-darkosha-id="1:188" style="">
>> + field->bar.path_len = op->lexer.src_len - op->lexer.offset;<br data-darkosha-id="1:189" style="">
>> + const char *pos = field->data;<br data-darkosha-id="1:190" style="">
>> + struct json_token token;<br data-darkosha-id="1:191" style="">
>> + do {<br data-darkosha-id="1:192" style="">
>> + rc = json_lexer_next_token(&op->lexer, &token);<br data-darkosha-id="1:193" style="">
>> + if (rc != 0)<br data-darkosha-id="1:194" style="">
>> + return xrow_update_err_bad_json(op, rc);<br data-darkosha-id="1:195" style="">
>> +<br data-darkosha-id="1:196" style="">
>> + switch (token.type) {<br data-darkosha-id="1:197" style="">
>> + case JSON_TOKEN_END:<br data-darkosha-id="1:198" style="">
>> + *is_found = true;<br data-darkosha-id="1:199" style="">
>> + field->bar.point = pos;<br data-darkosha-id="1:200" style="">
>> + mp_next(&pos);<br data-darkosha-id="1:201" style="">
>> + field->bar.point_size = pos - field->bar.point;<br data-darkosha-id="1:202" style="">
>> + return 0;<br data-darkosha-id="1:203" style="">
>> + case JSON_TOKEN_NUM:<br data-darkosha-id="1:204" style="">
>> + field->bar.parent = pos;<br data-darkosha-id="1:205" style="">
>> + *key_len_or_index = token.num;<br data-darkosha-id="1:206" style="">
>> + rc = tuple_field_go_to_index(&pos, token.num);<br data-darkosha-id="1:207" style="">
>> + break;<br data-darkosha-id="1:208" style="">
>> + case JSON_TOKEN_STR:<br data-darkosha-id="1:209" style="">
>> + field->bar.parent = pos;<br data-darkosha-id="1:210" style="">
>> + *key_len_or_index = token.len;<br data-darkosha-id="1:211" style="">
>> + rc = tuple_field_go_to_key(&pos, token.str, token.len);<br data-darkosha-id="1:212" style="">
>> + break;<br data-darkosha-id="1:213" style="">
>> + default:<br data-darkosha-id="1:214" style="">
>> + assert(token.type == JSON_TOKEN_ANY);<br data-darkosha-id="1:215" style="">
>> + rc = op->lexer.symbol_count - 1;<br data-darkosha-id="1:216" style="">
>> + return xrow_update_err_bad_json(op, rc);<br data-darkosha-id="1:217" style="">
>> + }<br data-darkosha-id="1:218" style="">
>> + } while (rc == 0);<br data-darkosha-id="1:219" style="">
>> + assert(rc == -1);<br data-darkosha-id="1:220" style="">
>> + /* Ensure, that 'token' is next to last path part. */<br data-darkosha-id="1:221" style="">
>> + struct json_token tmp_token;<br data-darkosha-id="1:222" style="">
>> + rc = json_lexer_next_token(&op->lexer, &tmp_token);<br data-darkosha-id="1:223" style="">
>> + if (rc != 0)<br data-darkosha-id="1:224" style="">
>> + return xrow_update_err_bad_json(op, rc);<br data-darkosha-id="1:225" style="">
>> + if (tmp_token.type != JSON_TOKEN_END)<br data-darkosha-id="1:226" style="">
>> + return xrow_update_err_no_such_field(op);<br data-darkosha-id="1:227" style="">
>> +<br data-darkosha-id="1:228" style="">
>> + *is_found = false;<br data-darkosha-id="1:229" style="">
>> + if (token.type == JSON_TOKEN_NUM) {<br data-darkosha-id="1:230" style="">
>> + const char *tmp = field->bar.parent;<br data-darkosha-id="1:231" style="">
>> + if (mp_typeof(*tmp) != MP_ARRAY) {<br data-darkosha-id="1:232" style="">
>> + return xrow_update_err(op, "can not access by index a "\<br data-darkosha-id="1:233" style="">
>> + "non-array field");<br data-darkosha-id="1:234" style="">
>> + }<br data-darkosha-id="1:235" style="">
>> + uint32_t size = mp_decode_array(&tmp);<br data-darkosha-id="1:236" style="">
>> + if ((uint32_t) token.num > size)<br data-darkosha-id="1:237" style="">
>> + return xrow_update_err_no_such_field(op);<br data-darkosha-id="1:238" style="">
> <br data-darkosha-id="1:239" style="">
> IMHO there will be more informative to mention the array and an index<br data-darkosha-id="1:240" style="">
> that is out of bounds.<br data-darkosha-id="1:241" style="">
> <br data-darkosha-id="1:242" style="">
<br data-darkosha-id="1:243" style="">
Well, xrow_update_err_no_such_field() does it. It adds the whole<br data-darkosha-id="1:244" style="">
path to the error message. So a user will see what a path caused<br data-darkosha-id="1:245" style="">
the problem.<br data-darkosha-id="1:246" style="">
<br data-darkosha-id="1:247" style="">
>> + /*<br data-darkosha-id="1:248" style="">
>> + * The updated point is in an array, its position<br data-darkosha-id="1:249" style="">
>> + * was not found, and its index is <= size. The<br data-darkosha-id="1:250" style="">
>> + * only way how can that happen - the update tries<br data-darkosha-id="1:251" style="">
>> + * to append a new array element. The following<br data-darkosha-id="1:252" style="">
>> + * code tries to find the array's end.<br data-darkosha-id="1:253" style="">
>> + */<br data-darkosha-id="1:254" style="">
>> + assert((uint32_t) token.num == size);<br data-darkosha-id="1:255" style="">
>> + if (field->bar.parent == field->data) {<br data-darkosha-id="1:256" style="">
>> + /*<br data-darkosha-id="1:257" style="">
>> + * Optimization for the case when the path<br data-darkosha-id="1:258" style="">
>> + * is short. So parent of the updated<br data-darkosha-id="1:259" style="">
>> + * point is the field itself. It allows<br data-darkosha-id="1:260" style="">
>> + * not to decode anything at all. It is<br data-darkosha-id="1:261" style="">
>> + * worth doing, since the paths are<br data-darkosha-id="1:262" style="">
>> + * usually short.<br data-darkosha-id="1:263" style="">
>> + */<br data-darkosha-id="1:264" style="">
>> + field->bar.point = field->data + field->size;<br data-darkosha-id="1:265" style="">
>> + } else {<br data-darkosha-id="1:266" style="">
>> + field->bar.point = field->bar.parent;<br data-darkosha-id="1:267" style="">
>> + mp_next(&field->bar.point);<br data-darkosha-id="1:268" style="">
>> + }<br data-darkosha-id="1:269" style="">
>> + field->bar.point_size = 0;<br data-darkosha-id="1:270" style="">
>> + } else {<br data-darkosha-id="1:271" style="">
>> + assert(token.type == JSON_TOKEN_STR);<br data-darkosha-id="1:272" style="">
>> + field->bar.new_key = token.str;<br data-darkosha-id="1:273" style="">
>> + field->bar.new_key_len = token.len;<br data-darkosha-id="1:274" style="">
>> + if (mp_typeof(*field->bar.parent) != MP_MAP) {<br data-darkosha-id="1:275" style="">
>> + return xrow_update_err(op, "can not access by key a "\<br data-darkosha-id="1:276" style="">
>> + "non-map field");<br data-darkosha-id="1:277" style="">
>> + }<br data-darkosha-id="1:278" style="">
>> + }<br data-darkosha-id="1:279" style="">
>> + return 0;<br data-darkosha-id="1:280" style="">
>> +}<br data-darkosha-id="1:281" style="">
>> +<br data-darkosha-id="1:282" style="">
>> +/**<br data-darkosha-id="1:283" style="">
>> + * Nop fields are those which are not updated. And when they<br data-darkosha-id="1:284" style="">
>> + * receive an update via one of xrow_update_op_do_nop_* functions,<br data-darkosha-id="1:285" style="">
>> + * it means, that there is a non terminal path digging inside this<br data-darkosha-id="1:286" style="">
>> + * not updated field. It turns nop field into a bar field. How<br data-darkosha-id="1:287" style="">
>> + * exactly - depends on a concrete operation.<br data-darkosha-id="1:288" style="">
>> + */<br data-darkosha-id="1:289" style="">
>> +<br data-darkosha-id="1:290" style="">
>> +int<br data-darkosha-id="1:291" style="">
>> +xrow_update_op_do_nop_insert(struct xrow_update_op *op,<br data-darkosha-id="1:292" style="">
>> + struct xrow_update_field *field)<br data-darkosha-id="1:293" style="">
>> +{<br data-darkosha-id="1:294" style="">
>> + assert(op->opcode == '!');<br data-darkosha-id="1:295" style="">
>> + assert(field->type == XUPDATE_NOP);<br data-darkosha-id="1:296" style="">
> <br data-darkosha-id="1:297" style="">
> Hmm. Do you expect to handle all possible cases in debug mode? <br data-darkosha-id="1:298" style="">
> Otherwise here should be some sort of gaceful fail to make prod more<br data-darkosha-id="1:299" style="">
> stable.<br data-darkosha-id="1:300" style="">
> <br data-darkosha-id="1:301" style="">
<br data-darkosha-id="1:302" style="">
In Tarantool we usually rely on the tests and debug mode. Concretely<br data-darkosha-id="1:303" style="">
this case I covered with tests on 100% not including OOM (we can't<br data-darkosha-id="1:304" style="">
test malloc failures, basically). This is done to not slowdown release<br data-darkosha-id="1:305" style="">
build with never passing checks such as this. Removal of assertion<br data-darkosha-id="1:306" style="">
checks from release gives very significant perf impact. However in some<br data-darkosha-id="1:307" style="">
places which are not hot paths there is a thing related to what you<br data-darkosha-id="1:308" style="">
mean: <a href="https://github.com/tarantool/tarantool/issues/2571" target="_blank" data-darkosha-id="1:309" style="">https://github.com/tarantool/tarantool/issues/2571</a><br data-darkosha-id="1:310" style="">
</div>
<base target="_self" href="https://e.mail.ru/" data-darkosha-id="1:311" style="">
</div>
</div></blockquote></div></div></BODY></HTML>