From: Mergen Imeev via Tarantool-patches <tarantool-patches@dev.tarantool.org> To: v.shpilevoy@tarantool.org Cc: tarantool-patches@dev.tarantool.org Subject: [Tarantool-patches] [PATCH v1 12/13] sql: remove copying of result in finalizers Date: Fri, 10 Sep 2021 19:02:29 +0300 [thread overview] Message-ID: <3023d600fc46ecd6158c4a28914576a9c2ccad2d.1631289462.git.imeevma@gmail.com> (raw) In-Reply-To: <cover.1631289462.git.imeevma@gmail.com> This patch removes copying of the result in the finalizers of the SQL built-in aggregate functions. Part of #4145 --- src/box/sql/func.c | 149 ++++++++++++++++-------------------------- src/box/sql/sqlInt.h | 12 ---- src/box/sql/vdbe.c | 39 ++++------- src/box/sql/vdbeInt.h | 1 - src/box/sql/vdbeapi.c | 39 ----------- 5 files changed, 67 insertions(+), 173 deletions(-) diff --git a/src/box/sql/func.c b/src/box/sql/func.c index 72c1c7828..f1f08e7d6 100644 --- a/src/box/sql/func.c +++ b/src/box/sql/func.c @@ -59,35 +59,27 @@ step_sum(struct sql_context *ctx, int argc, struct Mem **argv) { assert(argc == 1); (void)argc; - assert(ctx->pMem->type == MEM_TYPE_NULL || mem_is_num(ctx->pMem)); + assert(ctx->pOut->type == MEM_TYPE_NULL || mem_is_num(ctx->pOut)); if (argv[0]->type == MEM_TYPE_NULL) return; - if (ctx->pMem->type == MEM_TYPE_NULL) - return mem_copy_as_ephemeral(ctx->pMem, argv[0]); - if (mem_add(ctx->pMem, argv[0], ctx->pMem) != 0) + if (ctx->pOut->type == MEM_TYPE_NULL) + return mem_copy_as_ephemeral(ctx->pOut, argv[0]); + if (mem_add(ctx->pOut, argv[0], ctx->pOut) != 0) ctx->is_aborted = true; } -/** Finalizer for the SUM() function. */ -static void -fin_sum(struct sql_context *ctx) -{ - assert(ctx->pMem->type == MEM_TYPE_NULL || mem_is_num(ctx->pMem)); - mem_copy_as_ephemeral(ctx->pOut, ctx->pMem); -} - /** Implementation of the TOTAL() function. */ static void step_total(struct sql_context *ctx, int argc, struct Mem **argv) { assert(argc == 1); (void)argc; - assert(ctx->pMem->type == MEM_TYPE_NULL || mem_is_num(ctx->pMem)); + assert(ctx->pOut->type == MEM_TYPE_NULL || mem_is_num(ctx->pOut)); if (argv[0]->type == MEM_TYPE_NULL) return; - if (ctx->pMem->type == MEM_TYPE_NULL) - mem_set_double(ctx->pMem, 0.0); - if (mem_add(ctx->pMem, argv[0], ctx->pMem) != 0) + if (ctx->pOut->type == MEM_TYPE_NULL) + mem_set_double(ctx->pOut, 0.0); + if (mem_add(ctx->pOut, argv[0], ctx->pOut) != 0) ctx->is_aborted = true; } @@ -95,11 +87,9 @@ step_total(struct sql_context *ctx, int argc, struct Mem **argv) static void fin_total(struct sql_context *ctx) { - assert(ctx->pMem->type == MEM_TYPE_NULL || mem_is_double(ctx->pMem)); - if (ctx->pMem->type == MEM_TYPE_NULL) + assert(ctx->pOut->type == MEM_TYPE_NULL || mem_is_double(ctx->pOut)); + if (ctx->pOut->type == MEM_TYPE_NULL) mem_set_double(ctx->pOut, 0.0); - else - mem_copy_as_ephemeral(ctx->pOut, ctx->pMem); } /** Implementation of the AVG() function. */ @@ -108,20 +98,20 @@ step_avg(struct sql_context *ctx, int argc, struct Mem **argv) { assert(argc == 1); (void)argc; - assert(ctx->pMem->type == MEM_TYPE_NULL || mem_is_bin(ctx->pMem)); + assert(ctx->pOut->type == MEM_TYPE_NULL || mem_is_bin(ctx->pOut)); if (argv[0]->type == MEM_TYPE_NULL) return; - if (ctx->pMem->type == MEM_TYPE_NULL) { + if (ctx->pOut->type == MEM_TYPE_NULL) { uint32_t size = 2 * sizeof(struct Mem); struct Mem *mems = sqlDbMallocRawNN(sql_get(), size); mem_create(&mems[0]); mem_create(&mems[1]); mem_copy_as_ephemeral(&mems[0], argv[0]); mem_set_uint(&mems[1], 1); - mem_set_bin_allocated(ctx->pMem, (char *)mems, size); + mem_set_bin_allocated(ctx->pOut, (char *)mems, size); return; } - struct Mem *mems = (struct Mem *)ctx->pMem->z; + struct Mem *mems = (struct Mem *)ctx->pOut->z; assert(mems[1].type = MEM_TYPE_UINT); ++mems[1].u.u; if (mem_add(&mems[0], argv[0], &mems[0]) != 0) @@ -132,10 +122,10 @@ step_avg(struct sql_context *ctx, int argc, struct Mem **argv) static void fin_avg(struct sql_context *ctx) { - assert(ctx->pMem->type == MEM_TYPE_NULL || mem_is_bin(ctx->pMem)); - if (ctx->pMem->type == MEM_TYPE_NULL) - return mem_set_null(ctx->pOut); - struct Mem *mems = (struct Mem *)ctx->pMem->z; + assert(ctx->pOut->type == MEM_TYPE_NULL || mem_is_bin(ctx->pOut)); + if (ctx->pOut->type == MEM_TYPE_NULL) + return; + struct Mem *mems = (struct Mem *)ctx->pOut->z; if (mem_div(&mems[0], &mems[1], ctx->pOut) != 0) ctx->is_aborted = true; } @@ -145,22 +135,21 @@ static void step_count(struct sql_context *ctx, int argc, struct Mem **argv) { assert(argc == 0 || argc == 1); - if (ctx->pMem->type == MEM_TYPE_NULL) - mem_set_uint(ctx->pMem, 0); + if (ctx->pOut->type == MEM_TYPE_NULL) + mem_set_uint(ctx->pOut, 0); if (argc == 1 && argv[0]->type == MEM_TYPE_NULL) return; - assert(ctx->pMem->type == MEM_TYPE_UINT); - ++ctx->pMem->u.u; + assert(ctx->pOut->type == MEM_TYPE_UINT); + ++ctx->pOut->u.u; } /** Finalizer for the COUNT() function. */ static void fin_count(struct sql_context *ctx) { - assert(ctx->pMem->type == MEM_TYPE_NULL || mem_is_uint(ctx->pMem)); - if (ctx->pMem->type == MEM_TYPE_NULL) + assert(ctx->pOut->type == MEM_TYPE_NULL || mem_is_uint(ctx->pOut)); + if (ctx->pOut->type == MEM_TYPE_NULL) return mem_set_uint(ctx->pOut, 0); - mem_copy_as_ephemeral(ctx->pOut, ctx->pMem); } /** Implementation of the MIN() and MAX() functions. */ @@ -170,12 +159,12 @@ step_minmax(struct sql_context *ctx, int argc, struct Mem **argv) assert(argc == 1); (void)argc; if (argv[0]->type == MEM_TYPE_NULL) { - if (ctx->pMem->type != MEM_TYPE_NULL) + if (ctx->pOut->type != MEM_TYPE_NULL) ctx->skipFlag = 1; return; } - if (ctx->pMem->type == MEM_TYPE_NULL) { - if (mem_copy(ctx->pMem, argv[0]) != 0) + if (ctx->pOut->type == MEM_TYPE_NULL) { + if (mem_copy(ctx->pOut, argv[0]) != 0) ctx->is_aborted = true; return; } @@ -187,22 +176,15 @@ step_minmax(struct sql_context *ctx, int argc, struct Mem **argv) * the only difference between the two being that the sense of the * comparison is inverted. */ - int cmp = mem_cmp_scalar(ctx->pMem, argv[0], ctx->coll); + int cmp = mem_cmp_scalar(ctx->pOut, argv[0], ctx->coll); if ((is_max && cmp < 0) || (!is_max && cmp > 0)) { - if (mem_copy(ctx->pMem, argv[0]) != 0) + if (mem_copy(ctx->pOut, argv[0]) != 0) ctx->is_aborted = true; return; } ctx->skipFlag = 1; } -/** Finalizer for the MIN() and MAX() functions. */ -static void -fin_minmax(struct sql_context *ctx) -{ - mem_copy(ctx->pOut, ctx->pMem); -} - /** Implementation of the GROUP_CONCAT() function. */ static void step_group_concat(struct sql_context *ctx, int argc, struct Mem **argv) @@ -212,8 +194,8 @@ step_group_concat(struct sql_context *ctx, int argc, struct Mem **argv) if (argv[0]->type == MEM_TYPE_NULL) return; assert(mem_is_str(argv[0]) || mem_is_bin(argv[0])); - if (ctx->pMem->type == MEM_TYPE_NULL) { - if (mem_copy_str(ctx->pMem, argv[0]->z, argv[0]->n) != 0) + if (ctx->pOut->type == MEM_TYPE_NULL) { + if (mem_copy_str(ctx->pOut, argv[0]->z, argv[0]->n) != 0) ctx->is_aborted = true; return; } @@ -231,24 +213,17 @@ step_group_concat(struct sql_context *ctx, int argc, struct Mem **argv) sep_len = argv[1]->n; } if (sep_len > 0) { - if (mem_append(ctx->pMem, sep, sep_len) != 0) { + if (mem_append(ctx->pOut, sep, sep_len) != 0) { ctx->is_aborted = true; return; } } - if (mem_append(ctx->pMem, argv[0]->z, argv[0]->n) != 0) { + if (mem_append(ctx->pOut, argv[0]->z, argv[0]->n) != 0) { ctx->is_aborted = true; return; } } -/** Finalizer for the GROUP_CONCAT() function. */ -static void -fin_group_concat(struct sql_context *ctx) -{ - mem_copy(ctx->pOut, ctx->pMem); -} - static const unsigned char * mem_as_ustr(struct Mem *mem) { @@ -1960,13 +1935,13 @@ static struct sql_func_definition definitions[] = { NULL}, {"GROUP_CONCAT", 1, {FIELD_TYPE_STRING}, FIELD_TYPE_STRING, - step_group_concat, fin_group_concat}, + step_group_concat, NULL}, {"GROUP_CONCAT", 2, {FIELD_TYPE_STRING, FIELD_TYPE_STRING}, - FIELD_TYPE_STRING, step_group_concat, fin_group_concat}, + FIELD_TYPE_STRING, step_group_concat, NULL}, {"GROUP_CONCAT", 1, {FIELD_TYPE_VARBINARY}, FIELD_TYPE_VARBINARY, - step_group_concat, fin_group_concat}, + step_group_concat, NULL}, {"GROUP_CONCAT", 2, {FIELD_TYPE_VARBINARY, FIELD_TYPE_VARBINARY}, - FIELD_TYPE_VARBINARY, step_group_concat, fin_group_concat}, + FIELD_TYPE_VARBINARY, step_group_concat, NULL}, {"HEX", 1, {FIELD_TYPE_VARBINARY}, FIELD_TYPE_STRING, hexFunc, NULL}, {"IFNULL", 2, {FIELD_TYPE_ANY, FIELD_TYPE_ANY}, FIELD_TYPE_SCALAR, @@ -1997,35 +1972,23 @@ static struct sql_func_definition definitions[] = { {"LOWER", 1, {FIELD_TYPE_STRING}, FIELD_TYPE_STRING, LowerICUFunc, NULL}, - {"MAX", 1, {FIELD_TYPE_INTEGER}, FIELD_TYPE_INTEGER, step_minmax, - fin_minmax}, - {"MAX", 1, {FIELD_TYPE_DOUBLE}, FIELD_TYPE_DOUBLE, step_minmax, - fin_minmax}, - {"MAX", 1, {FIELD_TYPE_NUMBER}, FIELD_TYPE_NUMBER, step_minmax, - fin_minmax}, + {"MAX", 1, {FIELD_TYPE_INTEGER}, FIELD_TYPE_INTEGER, step_minmax, NULL}, + {"MAX", 1, {FIELD_TYPE_DOUBLE}, FIELD_TYPE_DOUBLE, step_minmax, NULL}, + {"MAX", 1, {FIELD_TYPE_NUMBER}, FIELD_TYPE_NUMBER, step_minmax, NULL}, {"MAX", 1, {FIELD_TYPE_VARBINARY}, FIELD_TYPE_VARBINARY, step_minmax, - fin_minmax}, - {"MAX", 1, {FIELD_TYPE_UUID}, FIELD_TYPE_UUID, step_minmax, - fin_minmax}, - {"MAX", 1, {FIELD_TYPE_STRING}, FIELD_TYPE_STRING, step_minmax, - fin_minmax}, - {"MAX", 1, {FIELD_TYPE_SCALAR}, FIELD_TYPE_SCALAR, step_minmax, - fin_minmax}, - - {"MIN", 1, {FIELD_TYPE_INTEGER}, FIELD_TYPE_INTEGER, step_minmax, - fin_minmax}, - {"MIN", 1, {FIELD_TYPE_DOUBLE}, FIELD_TYPE_DOUBLE, step_minmax, - fin_minmax}, - {"MIN", 1, {FIELD_TYPE_NUMBER}, FIELD_TYPE_NUMBER, step_minmax, - fin_minmax}, + NULL}, + {"MAX", 1, {FIELD_TYPE_UUID}, FIELD_TYPE_UUID, step_minmax, NULL}, + {"MAX", 1, {FIELD_TYPE_STRING}, FIELD_TYPE_STRING, step_minmax, NULL}, + {"MAX", 1, {FIELD_TYPE_SCALAR}, FIELD_TYPE_SCALAR, step_minmax, NULL}, + + {"MIN", 1, {FIELD_TYPE_INTEGER}, FIELD_TYPE_INTEGER, step_minmax, NULL}, + {"MIN", 1, {FIELD_TYPE_DOUBLE}, FIELD_TYPE_DOUBLE, step_minmax, NULL}, + {"MIN", 1, {FIELD_TYPE_NUMBER}, FIELD_TYPE_NUMBER, step_minmax, NULL}, {"MIN", 1, {FIELD_TYPE_VARBINARY}, FIELD_TYPE_VARBINARY, step_minmax, - fin_minmax}, - {"MIN", 1, {FIELD_TYPE_UUID}, FIELD_TYPE_UUID, step_minmax, - fin_minmax}, - {"MIN", 1, {FIELD_TYPE_STRING}, FIELD_TYPE_STRING, step_minmax, - fin_minmax}, - {"MIN", 1, {FIELD_TYPE_SCALAR}, FIELD_TYPE_SCALAR, step_minmax, - fin_minmax}, + NULL}, + {"MIN", 1, {FIELD_TYPE_UUID}, FIELD_TYPE_UUID, step_minmax, NULL}, + {"MIN", 1, {FIELD_TYPE_STRING}, FIELD_TYPE_STRING, step_minmax, NULL}, + {"MIN", 1, {FIELD_TYPE_SCALAR}, FIELD_TYPE_SCALAR, step_minmax, NULL}, {"NULLIF", 2, {FIELD_TYPE_ANY, FIELD_TYPE_ANY}, FIELD_TYPE_SCALAR, nullifFunc, NULL}, @@ -2059,9 +2022,9 @@ static struct sql_func_definition definitions[] = { {"SUBSTR", 3, {FIELD_TYPE_VARBINARY, FIELD_TYPE_INTEGER, FIELD_TYPE_INTEGER}, FIELD_TYPE_VARBINARY, substrFunc, NULL}, - {"SUM", 1, {FIELD_TYPE_DOUBLE}, FIELD_TYPE_DOUBLE, step_sum, fin_sum}, - {"SUM", 1, {FIELD_TYPE_INTEGER}, FIELD_TYPE_INTEGER, step_sum, fin_sum}, - {"SUM", 1, {FIELD_TYPE_DECIMAL}, FIELD_TYPE_DECIMAL, step_sum, fin_sum}, + {"SUM", 1, {FIELD_TYPE_DOUBLE}, FIELD_TYPE_DOUBLE, step_sum, NULL}, + {"SUM", 1, {FIELD_TYPE_INTEGER}, FIELD_TYPE_INTEGER, step_sum, NULL}, + {"SUM", 1, {FIELD_TYPE_DECIMAL}, FIELD_TYPE_DECIMAL, step_sum, NULL}, {"TOTAL", 1, {FIELD_TYPE_DOUBLE}, FIELD_TYPE_DOUBLE, step_total, fin_total}, {"TOTAL", 1, {FIELD_TYPE_INTEGER}, FIELD_TYPE_DOUBLE, step_total, @@ -2320,7 +2283,7 @@ sql_built_in_functions_cache_init(void) assert(desc->argc != -1 || dict->argc_min != dict->argc_max); def->param_count = desc->argc; def->returns = desc->result; - def->aggregate = desc->finalize == NULL ? + def->aggregate = (dict->flags & SQL_FUNC_AGG) == 0 ? FUNC_AGGREGATE_NONE : FUNC_AGGREGATE_GROUP; def->language = FUNC_LANGUAGE_SQL_BUILTIN; def->name_len = len; diff --git a/src/box/sql/sqlInt.h b/src/box/sql/sqlInt.h index 710bd86cf..8782c072a 100644 --- a/src/box/sql/sqlInt.h +++ b/src/box/sql/sqlInt.h @@ -484,18 +484,6 @@ void sql_row_count(struct sql_context *context, MAYBE_UNUSED int unused1, MAYBE_UNUSED sql_value **unused2); -void * -sql_aggregate_context(sql_context *, - int nBytes); - -/** - * Allocate or return the aggregate context containing struct MEM for a user - * function. A new context is allocated on the first call. Subsequent calls - * return the same context that was returned on prior calls. - */ -struct Mem * -sql_context_agg_mem(struct sql_context *context); - int sql_column_count(sql_stmt * pStmt); diff --git a/src/box/sql/vdbe.c b/src/box/sql/vdbe.c index 8804e3d18..1d22c4a40 100644 --- a/src/box/sql/vdbe.c +++ b/src/box/sql/vdbe.c @@ -4145,7 +4145,6 @@ case OP_AggStep: { int argc = pOp->p1; sql_context *pCtx; Mem *pMem; - Mem t; assert(pOp->p4type==P4_FUNCCTX); pCtx = pOp->p4.pCtx; @@ -4156,8 +4155,8 @@ case OP_AggStep: { * checks to see if the register array has changed, and if so it * reinitializes the relavant parts of the sql_context object */ - if (pCtx->pMem != pMem) { - pCtx->pMem = pMem; + if (pCtx->pOut != pMem) { + pCtx->pOut = pMem; for(i = 0; i < argc; ++i) pCtx->argv[i] = &aMem[pOp->p2 + i]; } @@ -4169,18 +4168,12 @@ case OP_AggStep: { } #endif - mem_create(&t); - pCtx->pOut = &t; - pCtx->is_aborted = false; pCtx->skipFlag = 0; assert(pCtx->func->def->language == FUNC_LANGUAGE_SQL_BUILTIN); struct func_sql_builtin *func = (struct func_sql_builtin *)pCtx->func; func->call(pCtx, argc, pCtx->argv); - if (pCtx->is_aborted) { - mem_destroy(&t); + if (pCtx->is_aborted) goto abort_due_to_error; - } - assert(mem_is_null(&t)); if (pCtx->skipFlag) { assert(pOp[-1].opcode == OP_SkipLoad); i = pOp[-1].p1; @@ -4207,24 +4200,14 @@ case OP_AggFinal: { struct func_sql_builtin *func = (struct func_sql_builtin *)pOp->p4.func; struct Mem *pIn1 = &aMem[pOp->p1]; - struct sql_context ctx; - memset(&ctx, 0, sizeof(ctx)); - struct Mem t; - memset(&t, 0, sizeof(t)); - t.type = MEM_TYPE_NULL; - assert(t.flags == 0); - t.db = pIn1->db; - ctx.pOut = &t; - ctx.pMem = pIn1; - ctx.func = pOp->p4.func; - func->finalize(&ctx); - assert((pIn1->flags & MEM_Dyn) == 0); - if (pIn1->szMalloc > 0) - sqlDbFree(pIn1->db, pIn1->zMalloc); - memcpy(pIn1, &t, sizeof(t)); - - if (ctx.is_aborted) - goto abort_due_to_error; + if (func->finalize != NULL) { + struct sql_context ctx; + memset(&ctx, 0, sizeof(ctx)); + ctx.pOut = pIn1; + func->finalize(&ctx); + if (ctx.is_aborted) + goto abort_due_to_error; + } UPDATE_MAX_BLOBSIZE(pIn1); if (sqlVdbeMemTooBig(pIn1) != 0) goto too_big; diff --git a/src/box/sql/vdbeInt.h b/src/box/sql/vdbeInt.h index b9a18f1a1..5e2692d06 100644 --- a/src/box/sql/vdbeInt.h +++ b/src/box/sql/vdbeInt.h @@ -172,7 +172,6 @@ struct sql_context { Mem *pOut; /* The return value is stored here */ /* A pointer to function implementation. */ struct func *func; - Mem *pMem; /* Memory cell used to store aggregate context */ struct coll *coll; /* * True, if an error occurred during the execution of the diff --git a/src/box/sql/vdbeapi.c b/src/box/sql/vdbeapi.c index 6e598513c..39f560c32 100644 --- a/src/box/sql/vdbeapi.c +++ b/src/box/sql/vdbeapi.c @@ -349,45 +349,6 @@ sql_context_db_handle(sql_context * p) return p->pOut->db; } -/* - * Allocate or return the aggregate context for a user function. A new - * context is allocated on the first call. Subsequent calls return the - * same context that was returned on prior calls. - */ -void * -sql_aggregate_context(sql_context * p, int nByte) -{ - assert(p != NULL && p->func != NULL); - assert(p->func->def->language == FUNC_LANGUAGE_SQL_BUILTIN); - assert(p->func->def->aggregate == FUNC_AGGREGATE_GROUP); - if (!mem_is_agg(p->pMem) && mem_set_agg(p->pMem, p->func, nByte) != 0) - return NULL; - void *accum; - if (mem_get_agg(p->pMem, &accum) != 0) - return NULL; - return accum; -} - -struct Mem * -sql_context_agg_mem(struct sql_context *ctx) -{ - assert(ctx != NULL && ctx->func != NULL); - assert(ctx->func->def->language == FUNC_LANGUAGE_SQL_BUILTIN); - assert(ctx->func->def->aggregate == FUNC_AGGREGATE_GROUP); - struct Mem *mem; - if (!mem_is_agg(ctx->pMem)) { - if (mem_set_agg(ctx->pMem, ctx->func, sizeof(*mem)) != 0) - return NULL; - if (mem_get_agg(ctx->pMem, (void **)&mem) != 0) - return NULL; - mem_create(mem); - return mem; - } - if (mem_get_agg(ctx->pMem, (void **)&mem) != 0) - return NULL; - return mem; -} - /* * Return the number of columns in the result set for the statement pStmt. */ -- 2.25.1
next prev parent reply other threads:[~2021-09-10 16:07 UTC|newest] Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top 2021-09-10 16:01 [Tarantool-patches] [PATCH v1 00/13] sql: reworks aggregate functions Mergen Imeev via Tarantool-patches 2021-09-10 16:01 ` [Tarantool-patches] [PATCH v1 01/13] sql: use register P1 for number of arguments Mergen Imeev via Tarantool-patches 2021-09-10 16:01 ` [Tarantool-patches] [PATCH v1 02/13] sql: remove AggStep0 and OP_BuiltinFunction0 Mergen Imeev via Tarantool-patches 2021-09-10 16:27 ` Mergen Imeev via Tarantool-patches 2021-09-14 21:21 ` Vladislav Shpilevoy via Tarantool-patches 2021-09-10 16:01 ` [Tarantool-patches] [PATCH v1 03/13] sql: move collation to struct sql_context Mergen Imeev via Tarantool-patches 2021-09-14 21:22 ` Vladislav Shpilevoy via Tarantool-patches 2021-09-21 10:40 ` Mergen Imeev via Tarantool-patches 2021-09-10 16:02 ` [Tarantool-patches] [PATCH v1 04/13] sql: introduce mem_append() Mergen Imeev via Tarantool-patches 2021-09-10 16:02 ` [Tarantool-patches] [PATCH v1 05/13] sql: remove sql_vdbemem_finalize() Mergen Imeev via Tarantool-patches 2021-09-14 21:23 ` Vladislav Shpilevoy via Tarantool-patches 2021-09-21 10:47 ` Mergen Imeev via Tarantool-patches 2021-09-22 22:47 ` Vladislav Shpilevoy via Tarantool-patches 2021-09-10 16:02 ` [Tarantool-patches] [PATCH v1 06/13] sql: rework SUM() Mergen Imeev via Tarantool-patches 2021-09-10 16:02 ` [Tarantool-patches] [PATCH v1 07/13] sql: rework TOTAL() Mergen Imeev via Tarantool-patches 2021-09-10 16:02 ` [Tarantool-patches] [PATCH v1 08/13] sql: rework AVG() Mergen Imeev via Tarantool-patches 2021-09-14 21:24 ` Vladislav Shpilevoy via Tarantool-patches 2021-09-10 16:02 ` [Tarantool-patches] [PATCH v1 09/13] sql: rework COUNT() Mergen Imeev via Tarantool-patches 2021-09-10 16:02 ` [Tarantool-patches] [PATCH v1 10/13] sql: rework MIN() and MAX() Mergen Imeev via Tarantool-patches 2021-09-10 16:02 ` [Tarantool-patches] [PATCH v1 11/13] sql: rework GROUP_CONCAT() Mergen Imeev via Tarantool-patches 2021-09-10 16:02 ` Mergen Imeev via Tarantool-patches [this message] 2021-09-14 21:24 ` [Tarantool-patches] [PATCH v1 12/13] sql: remove copying of result in finalizers Vladislav Shpilevoy via Tarantool-patches 2021-09-21 10:49 ` Mergen Imeev via Tarantool-patches 2021-09-10 16:02 ` [Tarantool-patches] [PATCH v1 13/13] sql: remove MEM_TYPE_AGG Mergen Imeev 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=3023d600fc46ecd6158c4a28914576a9c2ccad2d.1631289462.git.imeevma@gmail.com \ --to=tarantool-patches@dev.tarantool.org \ --cc=imeevma@tarantool.org \ --cc=v.shpilevoy@tarantool.org \ --subject='Re: [Tarantool-patches] [PATCH v1 12/13] sql: remove copying of result in finalizers' \ /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