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 7D2D76FC87; Fri, 1 Oct 2021 15:51:02 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org 7D2D76FC87 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=tarantool.org; s=dev; t=1633092662; bh=ijujhsG9sMLZWC7c5TeSyeJ01aY105ik+1IhW5m7JYI=; h=To:Cc:Date:In-Reply-To:References:Subject:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=qLfI1CVgT11SNU2FYyA2pZxRUQGLrpSq8n1NujnmVFptcOX90zrjIbabHxaJDPBcP Pn8DuXA34iB8Sf3k5QcKw0O46dx4Y2PWzvYsNcdJumXNQpMGHgnjTo+EDSAn2dFv3T nZrwBMlf7gLbRYl2vTEFFbxF7MLGwgoUIw66/+/w= 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 702ED6FC8B for ; Fri, 1 Oct 2021 15:48:40 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org 702ED6FC8B Received: by smtpng1.m.smailru.net with esmtpa (envelope-from ) id 1mWHxv-0003uN-LQ; Fri, 01 Oct 2021 15:48:40 +0300 To: v.shpilevoy@tarantool.org Cc: tarantool-patches@dev.tarantool.org Date: Fri, 1 Oct 2021 15:48:39 +0300 Message-Id: <80e58a080c2878e0e94411ff193f2be01f14125b.1633092363.git.imeevma@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-4EC0790: 10 X-7564579A: 646B95376F6C166E X-77F55803: 4F1203BC0FB41BD96A58C36AA2E99649BF631F26B0465AFD66E223DEB3A228DC182A05F5380850400FC2BCAC4A08769F887591F87C4467241BA1BA543AB34D117BF386F659B5AABD X-7FA49CB5: FF5795518A3D127A4AD6D5ED66289B5278DA827A17800CE781307CBDB76B677BEA1F7E6F0F101C67BD4B6F7A4D31EC0BCC500DACC3FED6E28638F802B75D45FF8AA50765F7900637E0B09B181166DBFC8638F802B75D45FF36EB9D2243A4F8B5A6FCA7DBDB1FC311F39EFFDF887939037866D6147AF826D80E371D76A5BFE5E6F02E16C8DB6E37AE117882F4460429724CE54428C33FAD305F5C1EE8F4F765FCAA867293B0326636D2E47CDBA5A96583BD4B6F7A4D31EC0BC014FD901B82EE079FA2833FD35BB23D27C277FBC8AE2E8BAA867293B0326636D2E47CDBA5A96583BA9C0B312567BB231DD303D21008E29813377AFFFEAFD269A417C69337E82CC2E827F84554CEF50127C277FBC8AE2E8BA83251EDC214901ED5E8D9A59859A8B66F6A3E018CF4DC80089D37D7C0E48F6C5571747095F342E88FB05168BE4CE3AF X-C1DE0DAB: C20DE7B7AB408E4181F030C43753B8186998911F362727C414F749A5E30D975CBBB17C150BCA6793BA2C344E44A1BC21B5940B4E7A1BC5ED9C2B6934AE262D3EE7EAB7254005DCED7532B743992DF240BDC6A1CF3F042BAD6DF99611D93F60EF783E2B6F79C23BED699F904B3F4130E343918A1A30D5E7FCCB5012B2E24CD356 X-C8649E89: 4E36BF7865823D7055A7F0CF078B5EC49A30900B95165D34FA5A4D623E7343BB3E20612B2914F195C7D1F3990AFDA6CB06DB846135D491A45B5DC883F21875DF1D7E09C32AA3244C4B340F9B020AA33F594280B87EA764DE3FD9C8CA1B0515E0729B2BEF169E0186 X-D57D3AED: 3ZO7eAau8CL7WIMRKs4sN3D3tLDjz0dLbV79QFUyzQ2Ujvy7cMT6pYYqY16iZVKkSc3dCLJ7zSJH7+u4VD18S7Vl4ZUrpaVfd2+vE6kuoey4m4VkSEu530nj6fImhcD4MUrOEAnl0W826KZ9Q+tr5ycPtXkTV4k65bRjmOUUP8cvGozZ33TWg5HZplvhhXbhDGzqmQDTd6OAevLeAnq3Ra9uf7zvY2zzsIhlcp/Y7m53TZgf2aB4JOg4gkr2biojJNmX3owDPmH2B96bY/4zRg== X-Mailru-Sender: 689FA8AB762F7393C37E3C1AEC41BA5D9014E760F69FC0F256F26DF8499B270A83D72C36FC87018B9F80AB2734326CD2FB559BB5D741EB96352A0ABBE4FDA4210A04DAD6CC59E33667EA787935ED9F1B X-Mras: Ok Subject: [Tarantool-patches] [PATCH v4 05/16] sql: move collation to struct sql_context 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: imeevma@tarantool.org Errors-To: tarantool-patches-bounces@dev.tarantool.org Sender: "Tarantool-patches" 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 ff0c461ce..bc2d69c49 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]); @@ -1769,7 +1755,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 5b57f57a3..6269c2868 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,8 +6762,7 @@ 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 b944b357b..87ba9e067 100644 --- a/src/box/sql/sqlInt.h +++ b/src/box/sql/sqlInt.h @@ -4128,7 +4128,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); void sql_context_delete(struct sql_context *ctx); @@ -4193,7 +4193,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 11e418e53..7f1965492 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 @@ -4152,7 +4141,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[] @@ -4187,7 +4175,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 97bd19863..65f51c21c 100644 --- a/src/box/sql/vdbeapi.c +++ b/src/box/sql/vdbeapi.c @@ -330,33 +330,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