From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from [87.239.111.99] (localhost [127.0.0.1]) by dev.tarantool.org (Postfix) with ESMTP id F12C96EC40; Sat, 25 Sep 2021 14:36:52 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org F12C96EC40 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=tarantool.org; s=dev; t=1632569813; bh=kShvfG6HcPnS8uCDplvO3DLBKd8wO4iZEmzk3XZgPjE=; h=Date:To:References:In-Reply-To:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=mb2HFfjTFRqJOXkgrQHgJdDjclzPRDF/U2VRROsB4L1prNaneI0bOm4K0agDs3A63 6I3eGJ6djjhAdwBR3PsS1japIq3d+MoEIsn4xizDU26VLJnfoQMnMkLQLBnCxgsM5e mwUaXeLotdShJnFv5k2mrHz+Q1WRjBu0EaX/3t9E= Received: from smtpng1.i.mail.ru (smtpng1.i.mail.ru [94.100.181.251]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dev.tarantool.org (Postfix) with ESMTPS id 3CBC66EC40 for ; Sat, 25 Sep 2021 14:36:50 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org 3CBC66EC40 Received: by smtpng1.m.smailru.net with esmtpa (envelope-from ) id 1mU5z7-0006ej-GL; Sat, 25 Sep 2021 14:36:49 +0300 Date: Sat, 25 Sep 2021 14:36:48 +0300 To: v.shpilevoy@tarantool.org, tarantool-patches@dev.tarantool.org Message-ID: <20210925113648.GH290467@tarantool.org> References: MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline In-Reply-To: X-4EC0790: 10 X-7564579A: 646B95376F6C166E X-77F55803: 4F1203BC0FB41BD96A58C36AA2E99649BF631F26B0465AFD3B2A95FE693EAA5B182A05F5380850409487F936DF91E16BBDF83321C66A53762F7761A60A7B14140B2F7BF7786B88EA X-7FA49CB5: FF5795518A3D127A4AD6D5ED66289B5278DA827A17800CE7AE28AD3C7270E452C2099A533E45F2D0395957E7521B51C2CFCAF695D4D8E9FCEA1F7E6F0F101C6778DA827A17800CE7E9C44F3538ABC873EA1F7E6F0F101C6723150C8DA25C47586E58E00D9D99D84E1BDDB23E98D2D38BBCA57AF85F7723F2CF26DC135AC9C78F3885F758DE777133CC7F00164DA146DAFE8445B8C89999728AA50765F7900637F6B57BC7E64490618DEB871D839B7333395957E7521B51C2DFABB839C843B9C08941B15DA834481F8AA50765F7900637F6B57BC7E6449061A352F6E88A58FB86F5D81C698A659EA7E827F84554CEF5019E625A9149C048EE9ECD01F8117BC8BEE2021AF6380DFAD18AA50765F790063735872C767BF85DA227C277FBC8AE2E8B953A8A48A05D51F175ECD9A6C639B01B4E70A05D1297E1BBCB5012B2E24CD356 X-C1DE0DAB: 0D63561A33F958A5EE4606A90A96B723ECFD076415362356E241BE8572CD6504D59269BC5F550898D99A6476B3ADF6B47008B74DF8BB9EF7333BD3B22AA88B938A852937E12ACA75BFC02AB3DF06BA5A410CA545F18667F91A7EA1CDA0B5A7A0 X-C8649E89: 4E36BF7865823D7055A7F0CF078B5EC49A30900B95165D341E08D7EE1804B7634CCF92CE665406252F537E14C2E6D177F95B63085BB8DFC101C3E1761820D7F41D7E09C32AA3244C7E71C292A637B5028C9DB064389A969424AF4FAF06DA24FD729B2BEF169E0186 X-D57D3AED: 3ZO7eAau8CL7WIMRKs4sN3D3tLDjz0dLbV79QFUyzQ2Ujvy7cMT6pYYqY16iZVKkSc3dCLJ7zSJH7+u4VD18S7Vl4ZUrpaVfd2+vE6kuoey4m4VkSEu530nj6fImhcD4MUrOEAnl0W826KZ9Q+tr5ycPtXkTV4k65bRjmOUUP8cvGozZ33TWg5HZplvhhXbhDGzqmQDTd6OAevLeAnq3Ra9uf7zvY2zzsIhlcp/Y7m53TZgf2aB4JOg4gkr2biojqHUEAOTxd4gz9mvA30h0wA== X-Mailru-Sender: 689FA8AB762F7393C37E3C1AEC41BA5D601739F31A0E4EA8A756619522731FE983D72C36FC87018B9F80AB2734326CD2FB559BB5D741EB96352A0ABBE4FDA4210A04DAD6CC59E33667EA787935ED9F1B X-Mras: Ok Subject: Re: [Tarantool-patches] [PATCH v2 11/15] sql: rework MIN() and MAX() X-BeenThere: tarantool-patches@dev.tarantool.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Tarantool development patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , From: Mergen Imeev via Tarantool-patches Reply-To: Mergen Imeev Errors-To: tarantool-patches-bounces@dev.tarantool.org Sender: "Tarantool-patches" Thank you for the review! I replaced manual checks of MEM type by mem_is_*() functions. Diff and new patch below. On Tue, Sep 21, 2021 at 01:59:26PM +0300, Mergen Imeev via Tarantool-patches wrote: > This patch does some refactoring for the SQL built-in aggregate > functions MIN() and MAX(). > > Part of #4145 > --- > src/box/sql/func.c | 162 +++++++++++++++++++-------------------------- > src/box/sql/vdbe.c | 1 - > 2 files changed, 69 insertions(+), 94 deletions(-) > > diff --git a/src/box/sql/func.c b/src/box/sql/func.c > index 113df423a..f699aa927 100644 > --- a/src/box/sql/func.c > +++ b/src/box/sql/func.c > @@ -173,6 +173,46 @@ fin_count(struct sql_context *ctx) > mem_copy_as_ephemeral(ctx->pOut, ctx->pMem); > } > > +/** Implementation of the MIN() and MAX() functions. */ > +static void > +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) > + ctx->skipFlag = 1; > + return; > + } > + if (ctx->pMem->type == MEM_TYPE_NULL) { > + if (mem_copy(ctx->pMem, argv[0]) != 0) > + ctx->is_aborted = true; > + return; > + } > + > + uint32_t flags = ((struct func_sql_builtin *)ctx->func)->flags; > + bool is_max = (flags & SQL_FUNC_MAX) != 0; > + /* > + * This step function is used for both the min() and max() aggregates, > + * 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); > + if ((is_max && cmp < 0) || (!is_max && cmp > 0)) { > + if (mem_copy(ctx->pMem, 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); > +} > + > static const unsigned char * > mem_as_ustr(struct Mem *mem) > { > @@ -220,16 +260,6 @@ sql_func_uuid(struct sql_context *ctx, int argc, struct Mem **argv) > mem_set_uuid(ctx->pOut, &uuid); > } > > -/* > - * Indicate that the accumulator load should be skipped on this > - * iteration of the aggregate loop. > - */ > -static void > -sqlSkipAccumulatorLoad(sql_context * context) > -{ > - context->skipFlag = 1; > -} > - > /* > * Implementation of the non-aggregate min() and max() functions > */ > @@ -1727,60 +1757,6 @@ soundexFunc(sql_context * context, int argc, sql_value ** argv) > } > } > > -/* > - * Routines to implement min() and max() aggregate functions. > - */ > -static void > -minmaxStep(sql_context * context, int NotUsed, sql_value ** argv) > -{ > - Mem *pArg = (Mem *) argv[0]; > - Mem *pBest; > - UNUSED_PARAMETER(NotUsed); > - > - struct func_sql_builtin *func = > - (struct func_sql_builtin *)context->func; > - pBest = sql_context_agg_mem(context); > - if (!pBest) > - return; > - > - if (mem_is_null(argv[0])) { > - if (!mem_is_null(pBest)) > - sqlSkipAccumulatorLoad(context); > - } else if (!mem_is_null(pBest)) { > - struct coll *pColl = context->coll; > - /* > - * This step function is used for both the min() > - * and max() aggregates, the only difference > - * between the two being that the sense of the > - * comparison is inverted. > - */ > - bool is_max = (func->flags & SQL_FUNC_MAX) != 0; > - int cmp = mem_cmp_scalar(pBest, pArg, pColl); > - if ((is_max && cmp < 0) || (!is_max && cmp > 0)) { > - if (mem_copy(pBest, pArg) != 0) > - context->is_aborted = true; > - } else { > - sqlSkipAccumulatorLoad(context); > - } > - } else { > - pBest->db = sql_context_db_handle(context); > - if (mem_copy(pBest, pArg) != 0) > - context->is_aborted = true; > - } > -} > - > -static void > -minMaxFinalize(sql_context * context) > -{ > - struct Mem *mem = context->pMem; > - struct Mem *res; > - if (mem_get_agg(mem, (void **)&res) != 0) > - return; > - if (!mem_is_null(res)) > - sql_result_value(context, res); > - mem_destroy(res); > -} > - > /* > * group_concat(EXPR, ?SEPARATOR?) > */ > @@ -2052,35 +2028,35 @@ static struct sql_func_definition definitions[] = { > {"LOWER", 1, {FIELD_TYPE_STRING}, FIELD_TYPE_STRING, LowerICUFunc, > NULL}, > > - {"MAX", 1, {FIELD_TYPE_INTEGER}, FIELD_TYPE_INTEGER, minmaxStep, > - minMaxFinalize}, > - {"MAX", 1, {FIELD_TYPE_DOUBLE}, FIELD_TYPE_DOUBLE, minmaxStep, > - minMaxFinalize}, > - {"MAX", 1, {FIELD_TYPE_NUMBER}, FIELD_TYPE_NUMBER, minmaxStep, > - minMaxFinalize}, > - {"MAX", 1, {FIELD_TYPE_VARBINARY}, FIELD_TYPE_VARBINARY, minmaxStep, > - minMaxFinalize}, > - {"MAX", 1, {FIELD_TYPE_UUID}, FIELD_TYPE_UUID, minmaxStep, > - minMaxFinalize}, > - {"MAX", 1, {FIELD_TYPE_STRING}, FIELD_TYPE_STRING, minmaxStep, > - minMaxFinalize}, > - {"MAX", 1, {FIELD_TYPE_SCALAR}, FIELD_TYPE_SCALAR, minmaxStep, > - minMaxFinalize}, > - > - {"MIN", 1, {FIELD_TYPE_INTEGER}, FIELD_TYPE_INTEGER, minmaxStep, > - minMaxFinalize}, > - {"MIN", 1, {FIELD_TYPE_DOUBLE}, FIELD_TYPE_DOUBLE, minmaxStep, > - minMaxFinalize}, > - {"MIN", 1, {FIELD_TYPE_NUMBER}, FIELD_TYPE_NUMBER, minmaxStep, > - minMaxFinalize}, > - {"MIN", 1, {FIELD_TYPE_VARBINARY}, FIELD_TYPE_VARBINARY, minmaxStep, > - minMaxFinalize}, > - {"MIN", 1, {FIELD_TYPE_UUID}, FIELD_TYPE_UUID, minmaxStep, > - minMaxFinalize}, > - {"MIN", 1, {FIELD_TYPE_STRING}, FIELD_TYPE_STRING, minmaxStep, > - minMaxFinalize}, > - {"MIN", 1, {FIELD_TYPE_SCALAR}, FIELD_TYPE_SCALAR, minmaxStep, > - minMaxFinalize}, > + {"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_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}, > + {"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}, > > {"NULLIF", 2, {FIELD_TYPE_ANY, FIELD_TYPE_ANY}, FIELD_TYPE_SCALAR, > nullifFunc, NULL}, > diff --git a/src/box/sql/vdbe.c b/src/box/sql/vdbe.c > index a74ee29ea..8804e3d18 100644 > --- a/src/box/sql/vdbe.c > +++ b/src/box/sql/vdbe.c > @@ -4169,7 +4169,6 @@ case OP_AggStep: { > } > #endif > > - pMem->n++; > mem_create(&t); > pCtx->pOut = &t; > pCtx->is_aborted = false; > -- > 2.25.1 > Diff: diff --git a/src/box/sql/func.c b/src/box/sql/func.c index 59cb9aca8..3708440e3 100644 --- a/src/box/sql/func.c +++ b/src/box/sql/func.c @@ -183,12 +183,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 (mem_is_null(argv[0])) { + if (!mem_is_null(ctx->pMem)) ctx->skipFlag = 1; return; } - if (ctx->pMem->type == MEM_TYPE_NULL) { + if (mem_is_null(ctx->pMem)) { if (mem_copy(ctx->pMem, argv[0]) != 0) ctx->is_aborted = true; return; New patch: commit 898e3104cedbe5f91c04d70a4d8436dbb9dd094d Author: Mergen Imeev Date: Thu Sep 9 18:32:19 2021 +0300 sql: rework MIN() and MAX() This patch does some refactoring for the SQL built-in aggregate functions MIN() and MAX(). Part of #4145 diff --git a/src/box/sql/func.c b/src/box/sql/func.c index 00db6512a..3708440e3 100644 --- a/src/box/sql/func.c +++ b/src/box/sql/func.c @@ -177,6 +177,46 @@ fin_count(struct sql_context *ctx) mem_copy_as_ephemeral(ctx->pOut, ctx->pMem); } +/** Implementation of the MIN() and MAX() functions. */ +static void +step_minmax(struct sql_context *ctx, int argc, struct Mem **argv) +{ + assert(argc == 1); + (void)argc; + if (mem_is_null(argv[0])) { + if (!mem_is_null(ctx->pMem)) + ctx->skipFlag = 1; + return; + } + if (mem_is_null(ctx->pMem)) { + if (mem_copy(ctx->pMem, argv[0]) != 0) + ctx->is_aborted = true; + return; + } + + uint32_t flags = ((struct func_sql_builtin *)ctx->func)->flags; + bool is_max = (flags & SQL_FUNC_MAX) != 0; + /* + * This step function is used for both the min() and max() aggregates, + * 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); + if ((is_max && cmp < 0) || (!is_max && cmp > 0)) { + if (mem_copy(ctx->pMem, 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); +} + static const unsigned char * mem_as_ustr(struct Mem *mem) { @@ -224,16 +264,6 @@ sql_func_uuid(struct sql_context *ctx, int argc, struct Mem **argv) mem_set_uuid(ctx->pOut, &uuid); } -/* - * Indicate that the accumulator load should be skipped on this - * iteration of the aggregate loop. - */ -static void -sqlSkipAccumulatorLoad(sql_context * context) -{ - context->skipFlag = 1; -} - /* * Implementation of the non-aggregate min() and max() functions */ @@ -1731,60 +1761,6 @@ soundexFunc(sql_context * context, int argc, sql_value ** argv) } } -/* - * Routines to implement min() and max() aggregate functions. - */ -static void -minmaxStep(sql_context * context, int NotUsed, sql_value ** argv) -{ - Mem *pArg = (Mem *) argv[0]; - Mem *pBest; - UNUSED_PARAMETER(NotUsed); - - struct func_sql_builtin *func = - (struct func_sql_builtin *)context->func; - pBest = sql_context_agg_mem(context); - if (!pBest) - return; - - if (mem_is_null(argv[0])) { - if (!mem_is_null(pBest)) - sqlSkipAccumulatorLoad(context); - } else if (!mem_is_null(pBest)) { - struct coll *pColl = context->coll; - /* - * This step function is used for both the min() - * and max() aggregates, the only difference - * between the two being that the sense of the - * comparison is inverted. - */ - bool is_max = (func->flags & SQL_FUNC_MAX) != 0; - int cmp = mem_cmp_scalar(pBest, pArg, pColl); - if ((is_max && cmp < 0) || (!is_max && cmp > 0)) { - if (mem_copy(pBest, pArg) != 0) - context->is_aborted = true; - } else { - sqlSkipAccumulatorLoad(context); - } - } else { - pBest->db = sql_context_db_handle(context); - if (mem_copy(pBest, pArg) != 0) - context->is_aborted = true; - } -} - -static void -minMaxFinalize(sql_context * context) -{ - struct Mem *mem = context->pMem; - struct Mem *res; - if (mem_get_agg(mem, (void **)&res) != 0) - return; - if (!mem_is_null(res)) - sql_result_value(context, res); - mem_destroy(res); -} - /* * group_concat(EXPR, ?SEPARATOR?) */ @@ -2056,35 +2032,35 @@ static struct sql_func_definition definitions[] = { {"LOWER", 1, {FIELD_TYPE_STRING}, FIELD_TYPE_STRING, LowerICUFunc, NULL}, - {"MAX", 1, {FIELD_TYPE_INTEGER}, FIELD_TYPE_INTEGER, minmaxStep, - minMaxFinalize}, - {"MAX", 1, {FIELD_TYPE_DOUBLE}, FIELD_TYPE_DOUBLE, minmaxStep, - minMaxFinalize}, - {"MAX", 1, {FIELD_TYPE_NUMBER}, FIELD_TYPE_NUMBER, minmaxStep, - minMaxFinalize}, - {"MAX", 1, {FIELD_TYPE_VARBINARY}, FIELD_TYPE_VARBINARY, minmaxStep, - minMaxFinalize}, - {"MAX", 1, {FIELD_TYPE_UUID}, FIELD_TYPE_UUID, minmaxStep, - minMaxFinalize}, - {"MAX", 1, {FIELD_TYPE_STRING}, FIELD_TYPE_STRING, minmaxStep, - minMaxFinalize}, - {"MAX", 1, {FIELD_TYPE_SCALAR}, FIELD_TYPE_SCALAR, minmaxStep, - minMaxFinalize}, - - {"MIN", 1, {FIELD_TYPE_INTEGER}, FIELD_TYPE_INTEGER, minmaxStep, - minMaxFinalize}, - {"MIN", 1, {FIELD_TYPE_DOUBLE}, FIELD_TYPE_DOUBLE, minmaxStep, - minMaxFinalize}, - {"MIN", 1, {FIELD_TYPE_NUMBER}, FIELD_TYPE_NUMBER, minmaxStep, - minMaxFinalize}, - {"MIN", 1, {FIELD_TYPE_VARBINARY}, FIELD_TYPE_VARBINARY, minmaxStep, - minMaxFinalize}, - {"MIN", 1, {FIELD_TYPE_UUID}, FIELD_TYPE_UUID, minmaxStep, - minMaxFinalize}, - {"MIN", 1, {FIELD_TYPE_STRING}, FIELD_TYPE_STRING, minmaxStep, - minMaxFinalize}, - {"MIN", 1, {FIELD_TYPE_SCALAR}, FIELD_TYPE_SCALAR, minmaxStep, - minMaxFinalize}, + {"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_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}, + {"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}, {"NULLIF", 2, {FIELD_TYPE_ANY, FIELD_TYPE_ANY}, FIELD_TYPE_SCALAR, nullifFunc, NULL}, diff --git a/src/box/sql/vdbe.c b/src/box/sql/vdbe.c index 66ac2c4f3..ee07af9c2 100644 --- a/src/box/sql/vdbe.c +++ b/src/box/sql/vdbe.c @@ -4169,7 +4169,6 @@ case OP_AggStep: { } #endif - pMem->n++; mem_create(&t); pCtx->pOut = &t; pCtx->is_aborted = false;