[Tarantool-patches] [PATCH v2 3/5] sql: remove struct func from struct sql_context
imeevma at tarantool.org
imeevma at tarantool.org
Thu Aug 19 08:31:30 MSK 2021
This patch removes struct func from struct sql_context since we don't
need the functionality of struct func here. Without this structure, we
can make it easier to work with SQL built-in functions.
Part of #6105
---
src/box/sql/func.c | 123 +++++++++++++++++++++++++++++++++++++-----
src/box/sql/vdbe.c | 8 +--
src/box/sql/vdbeInt.h | 6 ++-
src/box/sql/vdbeaux.c | 5 +-
4 files changed, 119 insertions(+), 23 deletions(-)
diff --git a/src/box/sql/func.c b/src/box/sql/func.c
index 4a0d2d097..adbc6d5a4 100644
--- a/src/box/sql/func.c
+++ b/src/box/sql/func.c
@@ -132,8 +132,7 @@ minmaxFunc(sql_context * context, int argc, sql_value ** argv)
int i;
int iBest;
struct coll *pColl;
- struct func *func = context->func;
- int mask = sql_func_flag_is_set(func, SQL_FUNC_MAX) ? -1 : 0;
+ int mask = (context->flags & SQL_FUNC_MAX) != 0 ? -1 : 0;
if (argc < 2) {
diag_set(ClientError, ER_FUNC_WRONG_ARG_COUNT,
mask ? "GREATEST" : "LEAST", "at least two", argc);
@@ -1799,8 +1798,6 @@ minmaxStep(sql_context * context, int NotUsed, sql_value ** argv)
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;
@@ -1816,7 +1813,7 @@ minmaxStep(sql_context * context, int NotUsed, sql_value ** argv)
* between the two being that the sense of the
* comparison is inverted.
*/
- bool is_max = (func->flags & SQL_FUNC_MAX) != 0;
+ bool is_max = (context->flags & SQL_FUNC_MAX) != 0;
int cmp = mem_cmp_scalar(pBest, pArg, pColl);
if ((is_max && cmp < 0) || (!is_max && cmp > 0)) {
mem_copy(pBest, pArg);
@@ -1930,9 +1927,7 @@ static void
sql_builtin_stub(sql_context *ctx, int argc, sql_value **argv)
{
(void) argc; (void) argv;
- diag_set(ClientError, ER_SQL_EXECUTE,
- tt_sprintf("function '%s' is not implemented",
- ctx->func->def->name));
+ diag_set(ClientError, ER_SQL_EXECUTE, "function is not implemented");
ctx->is_aborted = true;
}
@@ -2886,20 +2881,124 @@ int
sql_emit_func_call(struct Vdbe *vdbe, struct Expr *expr, int op, int mask,
int r1, int r2, uint8_t argc)
{
- struct func *func = sql_func_find(expr);
- if (func == NULL)
- return -1;
uint32_t size = sizeof(struct sql_context);
if (argc > 1)
size += (argc - 1) * sizeof(struct Mem);
struct sql_context *ctx = sqlDbMallocRawNN(sql_get(), size);
if (ctx == NULL)
return -1;
+ switch(expr->func_id) {
+ case TK_ABS:
+ ctx->call = absFunc;
+ break;
+ case TK_AVG:
+ case TK_SUM:
+ ctx->call = sum_step;
+ break;
+ case TK_CHAR:
+ ctx->call = charFunc;
+ break;
+ case TK_CHAR_LEN:
+ case TK_LENGTH:
+ ctx->call = lengthFunc;
+ break;
+ case TK_COALESCE:
+ case TK_IFNULL:
+ case TK_LIKELIHOOD:
+ case TK_LIKELY:
+ case TK_UNLIKELY:
+ ctx->call = sql_builtin_stub;
+ break;
+ case TK_COUNT:
+ ctx->call = countStep;
+ break;
+ case TK_GREATEST:
+ case TK_LEAST:
+ ctx->call = minmaxFunc;
+ break;
+ case TK_GROUP_CONCAT:
+ ctx->call = groupConcatStep;
+ break;
+ case TK_HEX:
+ ctx->call = hexFunc;
+ break;
+ case TK_LIKE_KW:
+ ctx->call = likeFunc;
+ break;
+ case TK_LOWER:
+ ctx->call = LowerICUFunc;
+ break;
+ case TK_MAX:
+ case TK_MIN:
+ ctx->call = minmaxStep;
+ break;
+ case TK_NULLIF:
+ ctx->call = nullifFunc;
+ break;
+ case TK_POSITION:
+ ctx->call = position_func;
+ break;
+ case TK_PRINTF:
+ ctx->call = printfFunc;
+ break;
+ case TK_QUOTE:
+ ctx->call = quoteFunc;
+ break;
+ case TK_RANDOM:
+ ctx->call = randomFunc;
+ break;
+ case TK_RANDOMBLOB:
+ ctx->call = randomBlob;
+ break;
+ case TK_REPLACE:
+ ctx->call = replaceFunc;
+ break;
+ case TK_ROUND:
+ ctx->call = roundFunc;
+ break;
+ case TK_ROW_COUNT:
+ ctx->call = sql_row_count;
+ break;
+ case TK_SOUNDEX:
+ ctx->call = soundexFunc;
+ break;
+ case TK_SUBSTR:
+ ctx->call = substrFunc;
+ break;
+ case TK_TOTAL:
+ ctx->call = total_step;
+ break;
+ case TK_TRIM:
+ ctx->call = trim_func;
+ break;
+ case TK_TYPEOF:
+ ctx->call = typeofFunc;
+ break;
+ case TK_UNICODE:
+ ctx->call = unicodeFunc;
+ break;
+ case TK_UPPER:
+ ctx->call = UpperICUFunc;
+ break;
+ case TK_UUID:
+ ctx->call = sql_func_uuid;
+ break;
+ case TK_VERSION:
+ ctx->call = sql_func_version;
+ break;
+ case TK_ZEROBLOB:
+ ctx->call = zeroblobFunc;
+ break;
+ default:
+ unreachable();
+ }
+ assert(strlen(expr->u.zToken) < 24);
+ strcpy(ctx->name, expr->u.zToken);
ctx->pOut = NULL;
- ctx->func = func;
ctx->iOp = 0;
ctx->pVdbe = vdbe;
ctx->argc = argc;
+ ctx->flags = sql_func_flags(expr->func_id);
sqlVdbeAddOp4(vdbe, op, mask, r1, r2, (char *)ctx, P4_FUNCCTX);
sqlVdbeChangeP5(vdbe, argc);
return 0;
diff --git a/src/box/sql/vdbe.c b/src/box/sql/vdbe.c
index 9fb103e82..c63dbaa5a 100644
--- a/src/box/sql/vdbe.c
+++ b/src/box/sql/vdbe.c
@@ -1221,9 +1221,7 @@ case OP_BuiltinFunction: {
}
#endif
pCtx->is_aborted = false;
- assert(pCtx->func->def->language == FUNC_LANGUAGE_SQL_BUILTIN);
- struct func_sql_builtin *func = (struct func_sql_builtin *)pCtx->func;
- func->call(pCtx, pCtx->argc, pCtx->argv);
+ pCtx->call(pCtx, pCtx->argc, pCtx->argv);
/* If the function returned an error, throw an exception */
if (pCtx->is_aborted)
@@ -4185,9 +4183,7 @@ case OP_AggStep: {
pCtx->pOut = &t;
pCtx->is_aborted = false;
pCtx->skipFlag = 0;
- assert(pCtx->func->def->language == FUNC_LANGUAGE_SQL_BUILTIN);
- struct func_sql_builtin *func = (struct func_sql_builtin *)pCtx->func;
- func->call(pCtx, pCtx->argc, pCtx->argv);
+ pCtx->call(pCtx, pCtx->argc, pCtx->argv);
if (pCtx->is_aborted) {
mem_destroy(&t);
goto abort_due_to_error;
diff --git a/src/box/sql/vdbeInt.h b/src/box/sql/vdbeInt.h
index 073ac0b97..0a0e6cc97 100644
--- a/src/box/sql/vdbeInt.h
+++ b/src/box/sql/vdbeInt.h
@@ -169,9 +169,8 @@ struct VdbeFrame {
* (Mem) which are only defined there.
*/
struct sql_context {
+ char name[24];
Mem *pOut; /* The return value is stored here */
- /* 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_BuiltinFunction or OP_AggStep. */
@@ -183,6 +182,9 @@ struct sql_context {
bool is_aborted;
u8 skipFlag; /* Skip accumulator loading if true */
u8 argc; /* Number of arguments */
+ uint32_t flags;
+ /* Implementation of SQL built-in function. */
+ void (*call)(struct sql_context *ctx, int argc, struct Mem **argv);
sql_value *argv[1]; /* Argument set */
};
diff --git a/src/box/sql/vdbeaux.c b/src/box/sql/vdbeaux.c
index 662fbbf81..3913dc637 100644
--- a/src/box/sql/vdbeaux.c
+++ b/src/box/sql/vdbeaux.c
@@ -1070,9 +1070,8 @@ displayP4(Op * pOp, char *zTemp, int nTemp)
}
#if defined(SQL_DEBUG) || defined(VDBE_PROFILE)
case P4_FUNCCTX:{
- struct func *func = pOp->p4.pCtx->func;
- sqlXPrintf(&x, "%s(%d)", func->def->name,
- func->def->param_count);
+ sqlXPrintf(&x, "%s(%d)", pOp->p4.pCtx->name,
+ pOp->p4.pCtx->argc);
break;
}
#endif
--
2.25.1
More information about the Tarantool-patches
mailing list