From: Mergen Imeev via Tarantool-patches <tarantool-patches@dev.tarantool.org> To: Vladislav Shpilevoy <v.shpilevoy@tarantool.org> Cc: tarantool-patches@dev.tarantool.org Subject: Re: [Tarantool-patches] [PATCH v5 18/52] sql: introduce mem_concat() Date: Tue, 13 Apr 2021 19:57:53 +0300 [thread overview] Message-ID: <20210413165753.GA185709@tarantool.org> (raw) In-Reply-To: <eac20a15-cd24-2d46-3e27-23f9c9234923@tarantool.org> Thank you for the review! My answers, diff and new patch below. On Sun, Apr 11, 2021 at 08:11:53PM +0200, Vladislav Shpilevoy wrote: > Good job on the patch! > > See 2 comments below. > > On 09.04.2021 19:57, Mergen Imeev via Tarantool-patches wrote: > > This patch introduces mem_concat(). Function mem_concat() concatenates > > values from two MEMs in case these values are strings or binaries and > > writes the result to the third MEM. > > > > Part of #5818 > > --- > > src/box/sql/mem.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++ > > src/box/sql/mem.h | 8 ++++++ > > src/box/sql/vdbe.c | 50 ++---------------------------------- > > 3 files changed, 74 insertions(+), 48 deletions(-) > > > > diff --git a/src/box/sql/mem.c b/src/box/sql/mem.c > > index b417c1007..2d76ef88d 100644 > > --- a/src/box/sql/mem.c > > +++ b/src/box/sql/mem.c > > @@ -326,6 +326,70 @@ mem_move(struct Mem *to, struct Mem *from) > > return 0; > > } > > > > +static bool > > +is_result_null(const struct Mem *a, const struct Mem *b, struct Mem *result, > > + enum field_type type) > > 1. Functions called 'is_*' never should change anything. > Fixed. Renamed to check_result_null(). > Another question is why do you even need it? It is used in a single place, > where it could be just inlined. And is not used in a place, where it could > be applied. > I added it here since it was the first commit, which used it. This functions will be used in all arithmetic and bitwise operations with two operands. > > +{ > > + mem_clear(result); > > + result->field_type = type; > > + return (((a->flags | b->flags) & MEM_Null) != 0); > > +} > > + > > +int > > +mem_concat(struct Mem *a, struct Mem *b, struct Mem *result) > > +{ > > + assert(result != b); > > + if (a != result) { > > + if (is_result_null(a, b, result, FIELD_TYPE_STRING)) > > + return 0; > > + } else { > > + if (((a->flags | b->flags) & MEM_Null) != 0) { > > + mem_clear(a); > > + result->field_type = FIELD_TYPE_STRING; > > + return 0; > > + } > > + } > > + > > + /* Concatenation operation can be applied only to strings and blobs. */ > > + if ((b->flags & (MEM_Str | MEM_Blob)) == 0) { > > + diag_set(ClientError, ER_INCONSISTENT_TYPES, > > + "text or varbinary", mem_type_to_str(b)); > > + return -1; > > + } > > + if ((a->flags & (MEM_Str | MEM_Blob)) == 0) { > > + diag_set(ClientError, ER_INCONSISTENT_TYPES, > > + "text or varbinary", mem_type_to_str(a)); > > + return -1; > > + } > > + > > + /* Moreover, both operands must be of the same type. */ > > + if ((b->flags & MEM_Str) != (a->flags & MEM_Str)) { > > + diag_set(ClientError, ER_INCONSISTENT_TYPES, > > + mem_type_to_str(a), mem_type_to_str(b)); > > + return -1; > > + } > > + > > + if (ExpandBlob(a) != 0 || ExpandBlob(b) != 0) > > + return -1; > > + > > + uint32_t size = a->n + b->n; > > + if ((int)size > sql_get()->aLimit[SQL_LIMIT_LENGTH]) { > > + diag_set(ClientError, ER_SQL_EXECUTE, "string or blob too big"); > > + return -1; > > + } > > + if (sqlVdbeMemGrow(result, size, result == a) != 0) > > + return -1; > > + > > + result->flags = a->flags & (MEM_Str | MEM_Blob); > > 2. Why isn't result cleared? What if it was an Agg, or Frame? > I see before your patch they called vdbe_prepare_null_out(), which > cleared the mem. > In case result != left result is cleared in check_result_null(). In the other case it is cleared if one of operands is NULL. If it is not cleared than result == left, which means that if it is not varbinary of string, the error will be returned. There shouldn't be any problem during destruction, I think. Also, if we clear result when result == left we will get NULL as result of concatenation no matter what left and right were. I do not know why result was cleared previously, since it may lead to result described above. > > + if ((result->flags & MEM_Blob) != 0) > > + result->field_type = FIELD_TYPE_VARBINARY; > > + if (result != a) > > + memcpy(result->z, a->z, a->n); > > + memcpy(&result->z[a->n], b->z, b->n); > > + result->n = size; > > + return 0; > > +} Diff: diff --git a/src/box/sql/mem.c b/src/box/sql/mem.c index 67c8d90ee..f3bb62369 100644 --- a/src/box/sql/mem.c +++ b/src/box/sql/mem.c @@ -181,8 +181,8 @@ mem_move(struct Mem *to, struct Mem *from) } static bool -is_result_null(const struct Mem *a, const struct Mem *b, struct Mem *result, - enum field_type type) +check_result_null(const struct Mem *a, const struct Mem *b, struct Mem *result, + enum field_type type) { mem_clear(result); result->field_type = type; @@ -194,7 +194,7 @@ mem_concat(struct Mem *a, struct Mem *b, struct Mem *result) { assert(result != b); if (a != result) { - if (is_result_null(a, b, result, FIELD_TYPE_STRING)) + if (check_result_null(a, b, result, FIELD_TYPE_STRING)) return 0; } else { if (((a->flags | b->flags) & MEM_Null) != 0) { New patch: commit e95f6aea6698865e5c864fa8ae1b5393c4faf553 Author: Mergen Imeev <imeevma@gmail.com> Date: Sat Mar 13 21:30:54 2021 +0300 sql: introduce mem_concat() This patch introduces mem_concat(). Function mem_concat() concatenates values from two MEMs in case these values are strings or binaries and writes the result to the third MEM. Part of #5818 diff --git a/src/box/sql/mem.c b/src/box/sql/mem.c index a7caac014..f3bb62369 100644 --- a/src/box/sql/mem.c +++ b/src/box/sql/mem.c @@ -180,6 +180,70 @@ mem_move(struct Mem *to, struct Mem *from) from->zMalloc = NULL; } +static bool +check_result_null(const struct Mem *a, const struct Mem *b, struct Mem *result, + enum field_type type) +{ + mem_clear(result); + result->field_type = type; + return (((a->flags | b->flags) & MEM_Null) != 0); +} + +int +mem_concat(struct Mem *a, struct Mem *b, struct Mem *result) +{ + assert(result != b); + if (a != result) { + if (check_result_null(a, b, result, FIELD_TYPE_STRING)) + return 0; + } else { + if (((a->flags | b->flags) & MEM_Null) != 0) { + mem_clear(a); + result->field_type = FIELD_TYPE_STRING; + return 0; + } + } + + /* Concatenation operation can be applied only to strings and blobs. */ + if ((b->flags & (MEM_Str | MEM_Blob)) == 0) { + diag_set(ClientError, ER_INCONSISTENT_TYPES, + "text or varbinary", mem_type_to_str(b)); + return -1; + } + if ((a->flags & (MEM_Str | MEM_Blob)) == 0) { + diag_set(ClientError, ER_INCONSISTENT_TYPES, + "text or varbinary", mem_type_to_str(a)); + return -1; + } + + /* Moreover, both operands must be of the same type. */ + if ((b->flags & MEM_Str) != (a->flags & MEM_Str)) { + diag_set(ClientError, ER_INCONSISTENT_TYPES, + mem_type_to_str(a), mem_type_to_str(b)); + return -1; + } + + if (ExpandBlob(a) != 0 || ExpandBlob(b) != 0) + return -1; + + uint32_t size = a->n + b->n; + if ((int)size > sql_get()->aLimit[SQL_LIMIT_LENGTH]) { + diag_set(ClientError, ER_SQL_EXECUTE, "string or blob too big"); + return -1; + } + if (sqlVdbeMemGrow(result, size, result == a) != 0) + return -1; + + result->flags = a->flags & (MEM_Str | MEM_Blob); + if ((result->flags & MEM_Blob) != 0) + result->field_type = FIELD_TYPE_VARBINARY; + if (result != a) + memcpy(result->z, a->z, a->n); + memcpy(&result->z[a->n], b->z, b->n); + result->n = size; + return 0; +} + static inline bool mem_has_msgpack_subtype(struct Mem *mem) { diff --git a/src/box/sql/mem.h b/src/box/sql/mem.h index 37f6ac5df..d17ed0593 100644 --- a/src/box/sql/mem.h +++ b/src/box/sql/mem.h @@ -322,6 +322,14 @@ mem_copy_as_ephemeral(struct Mem *to, const struct Mem *from); void mem_move(struct Mem *to, struct Mem *from); +/** + * Concatenate strings or binaries from the first and the second MEMs and write + * to the result MEM. In case the first MEM or the second MEM is NULL, the + * result MEM is set to NULL even if the result MEM is actually the first MEM. + */ +int +mem_concat(struct Mem *left, struct Mem *right, struct Mem *result); + /** * Simple type to str convertor. It is used to simplify * error reporting. diff --git a/src/box/sql/vdbe.c b/src/box/sql/vdbe.c index e73ed173d..c017c5091 100644 --- a/src/box/sql/vdbe.c +++ b/src/box/sql/vdbe.c @@ -1060,57 +1060,11 @@ case OP_ResultRow: { * types (i.e. TEXT and BLOB). */ case OP_Concat: { /* same as TK_CONCAT, in1, in2, out3 */ - i64 nByte; - pIn1 = &aMem[pOp->p1]; pIn2 = &aMem[pOp->p2]; - pOut = vdbe_prepare_null_out(p, pOp->p3); - assert(pIn1!=pOut); - if (mem_is_any_null(pIn1, pIn2)) { - /* Force NULL be of type STRING. */ - pOut->field_type = FIELD_TYPE_STRING; - break; - } - /* - * Concatenation operation can be applied only to - * strings and blobs. - */ - if (!mem_is_bytes(pIn1) || !mem_is_bytes(pIn2)) { - char *inconsistent_type = !mem_is_bytes(pIn1) ? - mem_type_to_str(pIn1) : - mem_type_to_str(pIn2); - diag_set(ClientError, ER_INCONSISTENT_TYPES, - "text or varbinary", inconsistent_type); - goto abort_due_to_error; - } - - /* Moreover, both operands must be of the same type. */ - if (!mem_is_same_type(pIn1, pIn2)) { - diag_set(ClientError, ER_INCONSISTENT_TYPES, - mem_type_to_str(pIn2), mem_type_to_str(pIn1)); - goto abort_due_to_error; - } - if (ExpandBlob(pIn1) != 0 || ExpandBlob(pIn2) != 0) + pOut = &aMem[pOp->p3]; + if (mem_concat(pIn2, pIn1, pOut) != 0) goto abort_due_to_error; - nByte = pIn1->n + pIn2->n; - if (nByte>db->aLimit[SQL_LIMIT_LENGTH]) { - goto too_big; - } - if (sqlVdbeMemGrow(pOut, (int)nByte+2, pOut==pIn2)) { - goto no_mem; - } - if (mem_is_str(pIn1)) - MemSetTypeFlag(pOut, MEM_Str); - else - MemSetTypeFlag(pOut, MEM_Blob); - if (pOut!=pIn2) { - memcpy(pOut->z, pIn2->z, pIn2->n); - } - memcpy(&pOut->z[pIn2->n], pIn1->z, pIn1->n); - pOut->z[nByte]=0; - pOut->z[nByte+1] = 0; - pOut->flags |= MEM_Term; - pOut->n = (int)nByte; UPDATE_MAX_BLOBSIZE(pOut); break; }
next prev parent reply other threads:[~2021-04-13 16:57 UTC|newest] Thread overview: 107+ messages / expand[flat|nested] mbox.gz Atom feed top 2021-04-09 16:51 [Tarantool-patches] [PATCH v5 00/52] Move mem-related functions to mem.c/mem.h Mergen Imeev via Tarantool-patches 2021-04-09 16:51 ` [Tarantool-patches] [PATCH v5 01/52] sql: enhance vdbe_decode_msgpack_into_mem() Mergen Imeev via Tarantool-patches 2021-04-11 17:42 ` Vladislav Shpilevoy via Tarantool-patches 2021-04-13 12:01 ` Mergen Imeev via Tarantool-patches 2021-04-13 12:12 ` Mergen Imeev via Tarantool-patches 2021-04-13 23:22 ` Vladislav Shpilevoy via Tarantool-patches 2021-04-13 23:34 ` Mergen Imeev via Tarantool-patches 2021-04-09 16:51 ` [Tarantool-patches] [PATCH v5 02/52] sql: disable unused code in sql/analyze.c Mergen Imeev via Tarantool-patches 2021-04-09 16:51 ` [Tarantool-patches] [PATCH v5 03/52] sql: disable unused code in sql/legacy.c Mergen Imeev via Tarantool-patches 2021-04-09 16:51 ` [Tarantool-patches] [PATCH v5 04/52] sql: remove NULL-termination in OP_ResultRow Mergen Imeev via Tarantool-patches 2021-04-14 22:23 ` Vladislav Shpilevoy via Tarantool-patches 2021-04-14 22:37 ` Mergen Imeev via Tarantool-patches 2021-04-09 16:51 ` [Tarantool-patches] [PATCH v5 05/52] sql: move MEM-related functions to mem.c/mem.h Mergen Imeev via Tarantool-patches 2021-04-09 16:59 ` [Tarantool-patches] [PATCH v5 06/52] sql: refactor port_vdbemem_*() functions Mergen Imeev via Tarantool-patches 2021-04-09 16:59 ` [Tarantool-patches] [PATCH v5 07/52] sql: remove unused MEM-related functions Mergen Imeev via Tarantool-patches 2021-04-09 16:59 ` [Tarantool-patches] [PATCH v5 08/52] sql: disable unused code in sql/vdbemem.c Mergen Imeev via Tarantool-patches 2021-04-09 16:59 ` [Tarantool-patches] [PATCH v5 09/52] sql: introduce mem_str() Mergen Imeev via Tarantool-patches 2021-04-11 17:44 ` Vladislav Shpilevoy via Tarantool-patches 2021-04-13 12:36 ` Mergen Imeev via Tarantool-patches 2021-04-14 22:23 ` Vladislav Shpilevoy via Tarantool-patches 2021-04-14 22:42 ` Mergen Imeev via Tarantool-patches 2021-04-09 16:59 ` [Tarantool-patches] [PATCH v5 10/52] sql: introduce mem_create() Mergen Imeev via Tarantool-patches 2021-04-09 17:36 ` [Tarantool-patches] [PATCH v5 11/52] sql: introduce mem_destroy() Mergen Imeev via Tarantool-patches 2021-04-11 17:46 ` Vladislav Shpilevoy via Tarantool-patches 2021-04-13 12:42 ` Mergen Imeev via Tarantool-patches 2021-04-09 17:36 ` [Tarantool-patches] [PATCH v5 12/52] sql: introduce mem_is_*() functions() Mergen Imeev via Tarantool-patches 2021-04-11 17:59 ` Vladislav Shpilevoy via Tarantool-patches 2021-04-13 16:09 ` Mergen Imeev via Tarantool-patches 2021-04-14 22:48 ` Vladislav Shpilevoy via Tarantool-patches 2021-04-14 23:07 ` Mergen Imeev via Tarantool-patches 2021-04-09 17:36 ` [Tarantool-patches] [PATCH v5 13/52] sql: introduce mem_copy() Mergen Imeev via Tarantool-patches 2021-04-11 18:06 ` Vladislav Shpilevoy via Tarantool-patches 2021-04-13 16:18 ` Mergen Imeev via Tarantool-patches 2021-04-09 17:36 ` [Tarantool-patches] [PATCH v5 14/52] sql: introduce mem_copy_as_ephemeral() Mergen Imeev via Tarantool-patches 2021-04-11 18:10 ` Vladislav Shpilevoy via Tarantool-patches 2021-04-13 16:31 ` Mergen Imeev via Tarantool-patches 2021-04-09 17:37 ` [Tarantool-patches] [PATCH v5 15/52] sql: rework mem_move() Mergen Imeev via Tarantool-patches 2021-04-11 18:10 ` Vladislav Shpilevoy via Tarantool-patches 2021-04-13 16:38 ` Mergen Imeev via Tarantool-patches 2021-04-09 17:57 ` [Tarantool-patches] [PATCH v5 16/52] sql: rework vdbe_decode_msgpack_into_mem() Mergen Imeev via Tarantool-patches 2021-04-09 17:57 ` [Tarantool-patches] [PATCH v5 17/52] sql: remove sql_column_to_messagepack() Mergen Imeev via Tarantool-patches 2021-04-14 22:58 ` Vladislav Shpilevoy via Tarantool-patches 2021-04-14 23:14 ` Mergen Imeev via Tarantool-patches 2021-04-09 17:57 ` [Tarantool-patches] [PATCH v5 18/52] sql: introduce mem_concat() Mergen Imeev via Tarantool-patches 2021-04-11 18:11 ` Vladislav Shpilevoy via Tarantool-patches 2021-04-13 16:57 ` Mergen Imeev via Tarantool-patches [this message] 2021-04-14 23:04 ` Vladislav Shpilevoy via Tarantool-patches 2021-04-14 23:22 ` Mergen Imeev via Tarantool-patches 2021-04-09 17:57 ` [Tarantool-patches] [PATCH v5 19/52] sql: introduce arithmetic operations for MEM Mergen Imeev via Tarantool-patches 2021-04-11 18:13 ` Vladislav Shpilevoy via Tarantool-patches 2021-04-13 17:06 ` Mergen Imeev via Tarantool-patches 2021-04-14 23:10 ` Vladislav Shpilevoy via Tarantool-patches 2021-04-14 23:33 ` Mergen Imeev via Tarantool-patches 2021-04-09 17:57 ` [Tarantool-patches] [PATCH v5 20/52] sql: introduce mem_compare() Mergen Imeev via Tarantool-patches 2021-04-11 18:16 ` Vladislav Shpilevoy via Tarantool-patches 2021-04-13 18:33 ` Mergen Imeev via Tarantool-patches 2021-04-14 23:20 ` Vladislav Shpilevoy via Tarantool-patches 2021-04-14 23:40 ` Mergen Imeev via Tarantool-patches 2021-04-09 18:11 ` [Tarantool-patches] [PATCH v5 21/52] sql: introduce bitwise operations for MEM Mergen Imeev via Tarantool-patches 2021-04-12 23:31 ` Vladislav Shpilevoy via Tarantool-patches 2021-04-13 20:49 ` Mergen Imeev via Tarantool-patches 2021-04-09 18:11 ` [Tarantool-patches] [PATCH v5 22/52] sql: Initialize MEM in sqlVdbeAllocUnpackedRecord() Mergen Imeev via Tarantool-patches 2021-04-09 18:11 ` [Tarantool-patches] [PATCH v5 23/52] sql: introduce mem_set_null() Mergen Imeev via Tarantool-patches 2021-04-09 18:11 ` [Tarantool-patches] [PATCH v5 24/52] sql: introduce mem_set_int() Mergen Imeev via Tarantool-patches 2021-04-12 23:32 ` Vladislav Shpilevoy via Tarantool-patches 2021-04-13 20:56 ` Mergen Imeev via Tarantool-patches 2021-04-09 18:11 ` [Tarantool-patches] [PATCH v5 25/52] sql: introduce mem_set_uint() Mergen Imeev via Tarantool-patches 2021-04-09 19:45 ` [Tarantool-patches] [PATCH v5 26/52] sql: move mem_set_bool() and mem_set_double() Mergen Imeev via Tarantool-patches 2021-04-09 19:45 ` [Tarantool-patches] [PATCH v5 27/52] sql: introduce mem_set_str_*() functions Mergen Imeev via Tarantool-patches 2021-04-12 23:34 ` Vladislav Shpilevoy via Tarantool-patches 2021-04-13 21:36 ` Mergen Imeev via Tarantool-patches 2021-04-14 23:49 ` Vladislav Shpilevoy via Tarantool-patches 2021-04-15 1:25 ` Mergen Imeev via Tarantool-patches 2021-04-09 19:45 ` [Tarantool-patches] [PATCH v5 28/52] sql: introduce mem_copy_str() and mem_copy_str0() Mergen Imeev via Tarantool-patches 2021-04-12 23:35 ` Vladislav Shpilevoy via Tarantool-patches 2021-04-13 22:00 ` Mergen Imeev via Tarantool-patches 2021-04-14 23:54 ` Vladislav Shpilevoy via Tarantool-patches 2021-04-15 0:30 ` Mergen Imeev via Tarantool-patches 2021-04-09 19:45 ` [Tarantool-patches] [PATCH v5 29/52] sql: introduce mem_set_bin_*() functions Mergen Imeev via Tarantool-patches 2021-04-09 19:45 ` [Tarantool-patches] [PATCH v5 30/52] sql: introduce mem_copy_bin() Mergen Imeev via Tarantool-patches 2021-04-12 23:36 ` Vladislav Shpilevoy via Tarantool-patches 2021-04-13 22:06 ` Mergen Imeev via Tarantool-patches 2021-04-09 20:05 ` [Tarantool-patches] [PATCH v5 31/52] sql: introduce mem_set_zerobin() Mergen Imeev via Tarantool-patches 2021-04-09 20:05 ` [Tarantool-patches] [PATCH v5 32/52] sql: introduce mem_set_*() for map and array Mergen Imeev via Tarantool-patches 2021-04-12 23:36 ` Vladislav Shpilevoy via Tarantool-patches 2021-04-13 22:08 ` Mergen Imeev via Tarantool-patches 2021-04-09 20:05 ` [Tarantool-patches] [PATCH v5 33/52] sql: introduce mem_set_invalid() Mergen Imeev via Tarantool-patches 2021-04-09 20:05 ` [Tarantool-patches] [PATCH v5 34/52] sql: refactor mem_set_ptr() Mergen Imeev via Tarantool-patches 2021-04-09 20:05 ` [Tarantool-patches] [PATCH v5 35/52] sql: introduce mem_set_frame() Mergen Imeev via Tarantool-patches 2021-04-12 23:37 ` Vladislav Shpilevoy via Tarantool-patches 2021-04-13 22:19 ` Mergen Imeev via Tarantool-patches 2021-04-09 20:25 ` [Tarantool-patches] [PATCH v5 36/52] sql: introduce mem_set_agg() Mergen Imeev via Tarantool-patches 2021-04-12 23:37 ` Vladislav Shpilevoy via Tarantool-patches 2021-04-13 22:46 ` Mergen Imeev via Tarantool-patches 2021-04-09 20:25 ` [Tarantool-patches] [PATCH v5 37/52] sql: introduce mem_set_null_clear() Mergen Imeev via Tarantool-patches 2021-04-12 23:38 ` Vladislav Shpilevoy via Tarantool-patches 2021-04-13 22:50 ` Mergen Imeev via Tarantool-patches 2021-04-09 20:25 ` [Tarantool-patches] [PATCH v5 38/52] sql: move MEM flags to mem.c Mergen Imeev via Tarantool-patches 2021-04-13 20:42 ` Mergen Imeev via Tarantool-patches 2021-04-09 20:25 ` [Tarantool-patches] [PATCH v5 39/52] sql: introduce mem_to_int*() functions Mergen Imeev via Tarantool-patches 2021-04-12 23:39 ` Vladislav Shpilevoy via Tarantool-patches 2021-04-13 22:58 ` Mergen Imeev via Tarantool-patches 2021-04-13 23:10 ` Mergen Imeev via Tarantool-patches 2021-04-09 20:26 ` [Tarantool-patches] [PATCH v5 40/52] sql: introduce mem_to_double() Mergen Imeev via Tarantool-patches 2021-04-13 23:21 ` Mergen Imeev via Tarantool-patches 2021-04-15 0:39 ` [Tarantool-patches] [PATCH v5 00/52] Move mem-related functions to mem.c/mem.h Vladislav Shpilevoy via Tarantool-patches 2021-04-15 6:49 ` Kirill Yukhin via Tarantool-patches
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20210413165753.GA185709@tarantool.org \ --to=tarantool-patches@dev.tarantool.org \ --cc=imeevma@tarantool.org \ --cc=v.shpilevoy@tarantool.org \ --subject='Re: [Tarantool-patches] [PATCH v5 18/52] sql: introduce mem_concat()' \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox