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 04/15] sql: move collation to struct sql_context Date: Tue, 21 Sep 2021 13:59:08 +0300 [thread overview] Message-ID: <b3d3a6af31a4bf33c2fe74c30750f6456fcc295b.1632220375.git.imeevma@gmail.com> (raw) In-Reply-To: <cover.1632220375.git.imeevma@gmail.com> This patch makes it easier to get a collation by a function. Needed for #4145 --- src/box/sql/date.c | 43 ------------------------------------------- src/box/sql/expr.c | 6 +----- src/box/sql/func.c | 26 ++++++-------------------- src/box/sql/select.c | 12 +++++------- src/box/sql/sqlInt.h | 3 +-- src/box/sql/vdbe.c | 18 +++--------------- src/box/sql/vdbeInt.h | 4 +--- src/box/sql/vdbeapi.c | 27 --------------------------- 8 files changed, 17 insertions(+), 122 deletions(-) diff --git a/src/box/sql/date.c b/src/box/sql/date.c index dbf460498..914a00dd2 100644 --- a/src/box/sql/date.c +++ b/src/box/sql/date.c @@ -1247,46 +1247,3 @@ ctimestampFunc(sql_context * context, datetimeFunc(context, 0, 0); } #endif /* !defined(SQL_OMIT_DATETIME_FUNCS) */ - -#ifdef SQL_OMIT_DATETIME_FUNCS -/* - * If the library is compiled to omit the full-scale date and time - * handling (to get a smaller binary), the following minimal version - * of the functions current_time(), current_date() and current_timestamp() - * are included instead. This is to support column declarations that - * include "DEFAULT CURRENT_TIME" etc. - * - * This function uses the C-library functions time(), gmtime() - * and strftime(). The format string to pass to strftime() is supplied - * as the user-data for the function. - */ -static void -currentTimeFunc(sql_context * context, int argc, sql_value ** argv) -{ - time_t t; - char *zFormat = (char *)sql_user_data(context); - sql_int64 iT; - struct tm *pTm; - struct tm sNow; - char zBuf[20]; - - UNUSED_PARAMETER(argc); - UNUSED_PARAMETER(argv); - - iT = sqlStmtCurrentTime(context); - if (iT <= 0) - return; - t = iT / 1000 - 10000 * (sql_int64) 21086676; -#if HAVE_GMTIME_R - pTm = gmtime_r(&t, &sNow); -#else - pTm = gmtime(&t); - if (pTm) - memcpy(&sNow, pTm, sizeof(sNow)); -#endif - if (pTm) { - strftime(zBuf, 20, zFormat, &sNow); - sql_result_text(context, zBuf, -1, SQL_TRANSIENT); - } -} -#endif diff --git a/src/box/sql/expr.c b/src/box/sql/expr.c index 6446ef091..ab7d95f7e 100644 --- a/src/box/sql/expr.c +++ b/src/box/sql/expr.c @@ -4102,13 +4102,9 @@ sqlExprCodeTarget(Parse * pParse, Expr * pExpr, int target) pParse->is_aborted = true; return 0; } - if (sql_func_flag_is_set(func, SQL_FUNC_NEEDCOLL)) { - sqlVdbeAddOp4(v, OP_CollSeq, 0, 0, 0, - (char *)coll, P4_COLLSEQ); - } if (func->def->language == FUNC_LANGUAGE_SQL_BUILTIN) { struct sql_context *ctx = - sql_context_new(v, func, nFarg); + sql_context_new(func, nFarg, coll); if (ctx == NULL) { pParse->is_aborted = true; return -1; diff --git a/src/box/sql/func.c b/src/box/sql/func.c index 9009f9e4f..b4461c6ee 100644 --- a/src/box/sql/func.c +++ b/src/box/sql/func.c @@ -100,20 +100,6 @@ sql_func_uuid(struct sql_context *ctx, int argc, struct Mem **argv) mem_set_uuid(ctx->pOut, &uuid); } -/* - * Return the collating function associated with a function. - */ -static struct coll * -sqlGetFuncCollSeq(sql_context * context) -{ - VdbeOp *pOp; - assert(context->pVdbe != 0); - pOp = &context->pVdbe->aOp[context->iOp - 1]; - assert(pOp->opcode == OP_CollSeq); - assert(pOp->p4type == P4_COLLSEQ || pOp->p4.pColl == NULL); - return pOp->p4.pColl; -} - /* * Indicate that the accumulator load should be skipped on this * iteration of the aggregate loop. @@ -141,7 +127,7 @@ minmaxFunc(sql_context * context, int argc, sql_value ** argv) context->is_aborted = true; return; } - pColl = sqlGetFuncCollSeq(context); + pColl = context->coll; assert(mask == -1 || mask == 0); iBest = 0; if (mem_is_null(argv[0])) @@ -402,7 +388,7 @@ position_func(struct sql_context *context, int argc, struct Mem **argv) n_haystack_bytes); } int beg_offset = 0; - struct coll *coll = sqlGetFuncCollSeq(context); + struct coll *coll = context->coll; int c; for (c = 0; c + n_needle_chars <= n_haystack_chars; c++) { if (coll->cmp((const char *) haystack_str + beg_offset, @@ -667,7 +653,7 @@ case_type##ICUFunc(sql_context *context, int argc, sql_value **argv) \ return; \ } \ UErrorCode status = U_ZERO_ERROR; \ - struct coll *coll = sqlGetFuncCollSeq(context); \ + struct coll *coll = context->coll; \ const char *locale = NULL; \ if (coll != NULL && coll->type == COLL_TYPE_ICU) { \ locale = ucol_getLocaleByType(coll->collator, \ @@ -1029,7 +1015,7 @@ likeFunc(sql_context *context, int argc, sql_value **argv) if (!zA || !zB) return; int res; - struct coll *coll = sqlGetFuncCollSeq(context); + struct coll *coll = context->coll; assert(coll != NULL); res = sql_utf8_pattern_compare(zB, zA, zB_end, zA_end, coll, escape); @@ -1050,7 +1036,7 @@ likeFunc(sql_context *context, int argc, sql_value **argv) static void nullifFunc(sql_context * context, int NotUsed, sql_value ** argv) { - struct coll *pColl = sqlGetFuncCollSeq(context); + struct coll *pColl = context->coll; UNUSED_PARAMETER(NotUsed); if (mem_cmp_scalar(argv[0], argv[1], pColl) != 0) sql_result_value(context, argv[0]); @@ -1761,7 +1747,7 @@ minmaxStep(sql_context * context, int NotUsed, sql_value ** argv) if (!mem_is_null(pBest)) sqlSkipAccumulatorLoad(context); } else if (!mem_is_null(pBest)) { - struct coll *pColl = sqlGetFuncCollSeq(context); + struct coll *pColl = context->coll; /* * This step function is used for both the min() * and max() aggregates, the only difference diff --git a/src/box/sql/select.c b/src/box/sql/select.c index 459325a88..2880f8ea0 100644 --- a/src/box/sql/select.c +++ b/src/box/sql/select.c @@ -5621,8 +5621,8 @@ updateAccumulator(Parse * pParse, AggInfo * pAggInfo) pParse->is_aborted = true; return; } + struct coll *coll = NULL; if (sql_func_flag_is_set(pF->func, SQL_FUNC_NEEDCOLL)) { - struct coll *coll = NULL; struct ExprList_item *pItem; int j; assert(pList != 0); /* pList!=0 if pF->pFunc has NEEDCOLL */ @@ -5636,10 +5636,9 @@ updateAccumulator(Parse * pParse, AggInfo * pAggInfo) } if (regHit == 0 && pAggInfo->nAccumulator) regHit = ++pParse->nMem; - sqlVdbeAddOp4(v, OP_CollSeq, regHit, 0, 0, - (char *)coll, P4_COLLSEQ); + sqlVdbeAddOp1(v, OP_SkipLoad, regHit); } - struct sql_context *ctx = sql_context_new(v, pF->func, nArg); + struct sql_context *ctx = sql_context_new(pF->func, nArg, coll); if (ctx == NULL) { pParse->is_aborted = true; return; @@ -6751,7 +6750,7 @@ sql_expr_extract_select(struct Parse *parser, struct Select *select) } struct sql_context * -sql_context_new(struct Vdbe *vdbe, struct func *func, uint32_t argc) +sql_context_new(struct func *func, uint32_t argc, struct coll *coll) { uint32_t size = sizeof(struct sql_context); if (argc > 1) @@ -6763,7 +6762,6 @@ sql_context_new(struct Vdbe *vdbe, struct func *func, uint32_t argc) ctx->func = func; ctx->is_aborted = false; ctx->skipFlag = 0; - ctx->pVdbe = vdbe; - ctx->iOp = 0; + ctx->coll = coll; return ctx; } diff --git a/src/box/sql/sqlInt.h b/src/box/sql/sqlInt.h index c2701dbde..710bd86cf 100644 --- a/src/box/sql/sqlInt.h +++ b/src/box/sql/sqlInt.h @@ -4142,7 +4142,7 @@ void sqlStrAccumReset(StrAccum *); void sqlSelectDestInit(SelectDest *, int, int, int); struct sql_context * -sql_context_new(struct Vdbe *vdbe, struct func *func, uint32_t argc); +sql_context_new(struct func *func, uint32_t argc, struct coll *coll); /* * Create an expression to load @a column from datasource @@ -4204,7 +4204,6 @@ void sqlParser(void *, int, Token, Parse *); int sqlParserStackPeak(void *); #endif -sql_int64 sqlStmtCurrentTime(sql_context *); int sqlVdbeParameterIndex(Vdbe *, const char *, int); int sqlTransferBindings(sql_stmt *, sql_stmt *); int sqlReprepare(Vdbe *); diff --git a/src/box/sql/vdbe.c b/src/box/sql/vdbe.c index 2ff7ce8f4..12dc9126b 100644 --- a/src/box/sql/vdbe.c +++ b/src/box/sql/vdbe.c @@ -1159,23 +1159,13 @@ case OP_Remainder: { /* same as TK_REM, in1, in2, out3 */ break; } -/* Opcode: CollSeq P1 * * P4 - * - * P4 is a pointer to a CollSeq struct. If the next call to a user function - * or aggregate calls sqlGetFuncCollSeq(), this collation sequence will - * be returned. This is used by the built-in min(), max() and nullif() - * functions. +/* Opcode: SkipLoad P1 * * * * * * If P1 is not zero, then it is a register that a subsequent min() or * max() aggregate will set to true if the current row is not the minimum or * maximum. The P1 register is initialized to false by this instruction. - * - * The interface used by the implementation of the aforementioned functions - * to retrieve the collation sequence set by this opcode is not available - * publicly. Only built-in functions have access to this feature. */ -case OP_CollSeq: { - assert(pOp->p4type==P4_COLLSEQ || pOp->p4.pColl == NULL); +case OP_SkipLoad: { if (pOp->p1) { mem_set_bool(&aMem[pOp->p1], false); } @@ -1199,7 +1189,6 @@ case OP_BuiltinFunction: { assert(pOp->p4type==P4_FUNCCTX); pCtx = pOp->p4.pCtx; - pCtx->iOp = (int)(pOp - aOp); /* If this function is inside of a trigger, the register array in aMem[] * might change from one evaluation to the next. The next block of code @@ -4160,7 +4149,6 @@ case OP_AggStep: { assert(pOp->p4type==P4_FUNCCTX); pCtx = pOp->p4.pCtx; - pCtx->iOp = (int)(pOp - aOp); pMem = &aMem[pOp->p3]; /* If this function is inside of a trigger, the register array in aMem[] @@ -4195,7 +4183,7 @@ case OP_AggStep: { } assert(mem_is_null(&t)); if (pCtx->skipFlag) { - assert(pOp[-1].opcode==OP_CollSeq); + assert(pOp[-1].opcode == OP_SkipLoad); i = pOp[-1].p1; if (i) mem_set_bool(&aMem[i], true); } diff --git a/src/box/sql/vdbeInt.h b/src/box/sql/vdbeInt.h index 575ab3f3d..b9a18f1a1 100644 --- a/src/box/sql/vdbeInt.h +++ b/src/box/sql/vdbeInt.h @@ -173,9 +173,7 @@ struct sql_context { /* A pointer to function implementation. */ struct func *func; Mem *pMem; /* Memory cell used to store aggregate context */ - Vdbe *pVdbe; /* The VM that owns this context */ - /** Instruction number of OP_BuiltinFunction0. */ - int iOp; + struct coll *coll; /* * True, if an error occurred during the execution of the * function. diff --git a/src/box/sql/vdbeapi.c b/src/box/sql/vdbeapi.c index 115940227..6e598513c 100644 --- a/src/box/sql/vdbeapi.c +++ b/src/box/sql/vdbeapi.c @@ -349,33 +349,6 @@ sql_context_db_handle(sql_context * p) return p->pOut->db; } -/* - * Return the current time for a statement. If the current time - * is requested more than once within the same run of a single prepared - * statement, the exact same time is returned for each invocation regardless - * of the amount of time that elapses between invocations. In other words, - * the time returned is always the time of the first call. - */ -sql_int64 -sqlStmtCurrentTime(sql_context * p) -{ - int rc; -#ifndef SQL_ENABLE_OR_STAT4 - sql_int64 *piTime = &p->pVdbe->iCurrentTime; - assert(p->pVdbe != 0); -#else - sql_int64 iTime = 0; - sql_int64 *piTime = - p->pVdbe != 0 ? &p->pVdbe->iCurrentTime : &iTime; -#endif - if (*piTime == 0) { - rc = sqlOsCurrentTimeInt64(p->pOut->db->pVfs, piTime); - if (rc) - *piTime = 0; - } - return *piTime; -} - /* * Allocate or return the aggregate context for a user function. A new * context is allocated on the first call. Subsequent calls return the -- 2.25.1
next prev parent reply other threads:[~2021-09-21 11:01 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 ` Mergen Imeev via Tarantool-patches [this message] 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 ` [Tarantool-patches] [PATCH v2 11/15] sql: rework MIN() and MAX() Mergen Imeev via Tarantool-patches 2021-09-25 11:36 ` 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=b3d3a6af31a4bf33c2fe74c30750f6456fcc295b.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 04/15] sql: move collation to struct sql_context' \ /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