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 062076EC55; Fri, 10 Sep 2021 19:03:21 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org 062076EC55 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=tarantool.org; s=dev; t=1631289801; bh=shhVkYqBpWGCBv6huDAXPLVFzv1FgDjZXyBpMmq+zw4=; 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=hiMej6nxeyktIdynEz69rHKOjXNRmYbnC9mlA/b9TyyDZU1Nuit9o6l2hDlC2ae+4 qML1Ptn+oYQ0Nm9wmt801ta/vfUEiz4Alv1sEDDF5SZZ5IxolBE4em45iSeXdJlfZv HjyHC0W2888moiuwKMUhI0O1yet90P8qQMWS8dDI= Received: from smtpng2.i.mail.ru (smtpng2.i.mail.ru [94.100.179.3]) (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 5FB796EC55 for ; Fri, 10 Sep 2021 19:01:59 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org 5FB796EC55 Received: by smtpng2.m.smailru.net with esmtpa (envelope-from ) id 1mOiyU-0000y8-LO; Fri, 10 Sep 2021 19:01:59 +0300 To: v.shpilevoy@tarantool.org Cc: tarantool-patches@dev.tarantool.org Date: Fri, 10 Sep 2021 19:01:58 +0300 Message-Id: <610b38cc1f01a80faf25a194d157cc3987f28f83.1631289462.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: B8F34718100C35BD X-77F55803: 4F1203BC0FB41BD91AE02D33A9C88A2F7B0FCECE251A4B9EABD2FC9AA46919D800894C459B0CD1B947245D4657798F87767CD7EBFA6A307859451B28AE1D565958574C2FEBD6103D X-7FA49CB5: FF5795518A3D127A4AD6D5ED66289B5278DA827A17800CE79A2E61952DECAF71EA1F7E6F0F101C67BD4B6F7A4D31EC0BCC500DACC3FED6E28638F802B75D45FF8AA50765F7900637BA14B6CBCF09CA1D8638F802B75D45FF36EB9D2243A4F8B5A6FCA7DBDB1FC311F39EFFDF887939037866D6147AF826D82FAAB9CF8B272EE59045C0499CD65D2E117882F4460429724CE54428C33FAD305F5C1EE8F4F765FCAA867293B0326636D2E47CDBA5A96583BD4B6F7A4D31EC0BC014FD901B82EE079FA2833FD35BB23D27C277FBC8AE2E8BF1175FABE1C0F9B6A471835C12D1D977C4224003CC8364762BB6847A3DEAEFB0F43C7A68FF6260569E8FC8737B5C2249EC8D19AE6D49635B68655334FD4449CB9ECD01F8117BC8BEAAAE862A0553A39223F8577A6DFFEA7C289736CE4F78F08343847C11F186F3C59DAA53EE0834AAEE X-C1DE0DAB: C20DE7B7AB408E4181F030C43753B8186998911F362727C414F749A5E30D975CBF3286B3348795C64CF2600DAB87A15DC3D8AB3CADBB40179C2B6934AE262D3EE7EAB7254005DCED7532B743992DF240BDC6A1CF3F042BAD6DF99611D93F60EFB4CA5BC574AE2910699F904B3F4130E343918A1A30D5E7FCCB5012B2E24CD356 X-C8649E89: 4E36BF7865823D7055A7F0CF078B5EC49A30900B95165D34806D3522FB05EB398458C3D31F31F4FDA022B87A8167E8BAE681D9697FDF1A755FFE859E646EA9391D7E09C32AA3244C0D2FF127A412F42C2923B26F9B02D0FB64EE5813BBCA3A9D729B2BEF169E0186 X-D57D3AED: 3ZO7eAau8CL7WIMRKs4sN3D3tLDjz0dLbV79QFUyzQ2Ujvy7cMT6pYYqY16iZVKkSc3dCLJ7zSJH7+u4VD18S7Vl4ZUrpaVfd2+vE6kuoey4m4VkSEu530nj6fImhcD4MUrOEAnl0W826KZ9Q+tr5ycPtXkTV4k65bRjmOUUP8cvGozZ33TWg5HZplvhhXbhDGzqmQDTd6OAevLeAnq3Ra9uf7zvY2zzsIhlcp/Y7m53TZgf2aB4JOg4gkr2biojFfmM42hctyTfIkmUJy5DGw== X-Mailru-Sender: 689FA8AB762F7393C37E3C1AEC41BA5D7A7D13F530EA07AB58D6AD8F9774502783D72C36FC87018B9F80AB2734326CD2FB559BB5D741EB96352A0ABBE4FDA4210A04DAD6CC59E33667EA787935ED9F1B X-Mras: Ok Subject: [Tarantool-patches] [PATCH v1 03/13] 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 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 e27dcb336..d738ba137 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