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 v2 11/15] sql: rework MIN() and MAX() Date: Tue, 21 Sep 2021 13:59:26 +0300 [thread overview] Message-ID: <a944a509f67c55a2ce9c5abc61ae5c2489c16633.1632220375.git.imeevma@gmail.com> (raw) In-Reply-To: <cover.1632220375.git.imeevma@gmail.com> 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
next prev parent reply other threads:[~2021-09-21 11:04 UTC|newest] Thread overview: 31+ messages / expand[flat|nested] mbox.gz Atom feed top [not found] <cover.1632220375.git.imeevma@gmail.com> 2021-09-21 10:59 ` [Tarantool-patches] [PATCH v2 01/15] sql: fix possible undefined behavior during cast Mergen Imeev via Tarantool-patches 2021-09-21 10:59 ` [Tarantool-patches] [PATCH v2 02/15] sql: use register P1 for number of arguments Mergen Imeev via Tarantool-patches 2021-09-21 10:59 ` [Tarantool-patches] [PATCH v2 04/15] sql: move collation to struct sql_context Mergen Imeev via Tarantool-patches 2021-09-21 10:59 ` [Tarantool-patches] [PATCH v2 05/15] sql: introduce mem_append() Mergen Imeev via Tarantool-patches 2021-09-25 11:06 ` Mergen Imeev via Tarantool-patches 2021-09-21 10:59 ` [Tarantool-patches] [PATCH v2 06/15] sql: remove sql_vdbemem_finalize() Mergen Imeev via Tarantool-patches 2021-09-22 22:47 ` Vladislav Shpilevoy via Tarantool-patches 2021-09-25 11:13 ` Mergen Imeev via Tarantool-patches 2021-09-21 10:59 ` [Tarantool-patches] [PATCH v2 07/15] sql: rework SUM() Mergen Imeev via Tarantool-patches 2021-09-22 22:48 ` Vladislav Shpilevoy via Tarantool-patches 2021-09-25 11:17 ` Mergen Imeev via Tarantool-patches 2021-09-21 10:59 ` [Tarantool-patches] [PATCH v2 08/15] sql: rework TOTAL() Mergen Imeev via Tarantool-patches 2021-09-25 11:20 ` Mergen Imeev via Tarantool-patches 2021-09-21 10:59 ` [Tarantool-patches] [PATCH v2 09/15] sql: rework AVG() Mergen Imeev via Tarantool-patches 2021-09-22 22:48 ` Vladislav Shpilevoy via Tarantool-patches 2021-09-25 11:32 ` Mergen Imeev via Tarantool-patches 2021-09-21 10:59 ` [Tarantool-patches] [PATCH v2 10/15] sql: rework COUNT() Mergen Imeev via Tarantool-patches 2021-09-25 11:34 ` Mergen Imeev via Tarantool-patches 2021-09-21 10:59 ` Mergen Imeev via Tarantool-patches [this message] 2021-09-25 11:36 ` [Tarantool-patches] [PATCH v2 11/15] sql: rework MIN() and MAX() Mergen Imeev via Tarantool-patches 2021-09-21 10:59 ` [Tarantool-patches] [PATCH v2 12/15] sql: rework GROUP_CONCAT() Mergen Imeev via Tarantool-patches 2021-09-22 22:49 ` Vladislav Shpilevoy via Tarantool-patches 2021-09-25 11:42 ` Mergen Imeev via Tarantool-patches 2021-09-29 7:03 ` Mergen Imeev via Tarantool-patches 2021-09-21 10:59 ` [Tarantool-patches] [PATCH v2 13/15] sql: remove copying of result in finalizers Mergen Imeev via Tarantool-patches 2021-09-22 22:50 ` Vladislav Shpilevoy via Tarantool-patches 2021-09-25 11:47 ` Mergen Imeev via Tarantool-patches 2021-09-21 10:59 ` [Tarantool-patches] [PATCH v2 14/15] sql: remove MEM_TYPE_AGG Mergen Imeev via Tarantool-patches 2021-09-21 10:59 ` [Tarantool-patches] [PATCH v2 15/15] sql: remove field argv from struct sql_context Mergen Imeev via Tarantool-patches 2021-09-22 22:51 ` Vladislav Shpilevoy via Tarantool-patches 2021-09-25 12:03 ` 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=a944a509f67c55a2ce9c5abc61ae5c2489c16633.1632220375.git.imeevma@gmail.com \ --to=tarantool-patches@dev.tarantool.org \ --cc=imeevma@tarantool.org \ --cc=v.shpilevoy@tarantool.org \ --subject='Re: [Tarantool-patches] [PATCH v2 11/15] sql: rework MIN() and MAX()' \ /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