* [Tarantool-patches] [PATCH v2 0/5] Change structure of SQL-built-in functions
@ 2021-08-19 5:31 Mergen Imeev via Tarantool-patches
2021-08-19 5:31 ` [Tarantool-patches] [PATCH v2 1/5] sql: remove OP_BuiltinFunction0 and OP_AggStep0 Mergen Imeev via Tarantool-patches
` (4 more replies)
0 siblings, 5 replies; 6+ messages in thread
From: Mergen Imeev via Tarantool-patches @ 2021-08-19 5:31 UTC (permalink / raw)
To: vdavydov; +Cc: tarantool-patches
This patch-set changes structure of SQL built-in functions.
https://github.com/tarantool/tarantool/issues/6105
https://github.com/tarantool/tarantool/tree/imeevma/gh-6105-properly-check-funcs-args-types
Mergen Imeev (5):
sql: remove OP_BuiltinFunction0 and OP_AggStep0
sql: remove unnecessary MEM finalization
sql: remove struct func from struct sql_context
sql: do not use struct func for finalization
sql: remove unused code
src/box/box.cc | 1 -
src/box/sql.c | 1 -
src/box/sql.h | 9 -
src/box/sql/analyze.c | 6 +-
src/box/sql/expr.c | 2 +-
src/box/sql/func.c | 999 +++++++-----------------------------------
src/box/sql/mem.c | 34 +-
src/box/sql/mem.h | 19 +-
src/box/sql/select.c | 2 +-
src/box/sql/sqlInt.h | 42 --
src/box/sql/vdbe.c | 109 +----
src/box/sql/vdbe.h | 9 +-
src/box/sql/vdbeInt.h | 10 +-
src/box/sql/vdbeapi.c | 10 +-
src/box/sql/vdbeaux.c | 11 +-
15 files changed, 184 insertions(+), 1080 deletions(-)
--
2.25.1
^ permalink raw reply [flat|nested] 6+ messages in thread
* [Tarantool-patches] [PATCH v2 1/5] sql: remove OP_BuiltinFunction0 and OP_AggStep0
2021-08-19 5:31 [Tarantool-patches] [PATCH v2 0/5] Change structure of SQL-built-in functions Mergen Imeev via Tarantool-patches
@ 2021-08-19 5:31 ` Mergen Imeev via Tarantool-patches
2021-08-19 5:31 ` [Tarantool-patches] [PATCH v2 2/5] sql: remove unnecessary MEM finalization Mergen Imeev via Tarantool-patches
` (3 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Mergen Imeev via Tarantool-patches @ 2021-08-19 5:31 UTC (permalink / raw)
To: vdavydov; +Cc: tarantool-patches
This patch moves the initialization of sql_context out of the VDBE. This
allows us to remove the opcodes OP_BuiltinFunction0 and OP_AggStep0,
which work in a rather strange way. Moreover, due to the changes these
opcodes make to the VDBEs, it is possible that the estimated size of the
VDBE could become non-constant, which could lead to various problems.
Part of #6105
---
src/box/sql/analyze.c | 6 +--
src/box/sql/expr.c | 2 +-
src/box/sql/func.c | 13 ++++++-
src/box/sql/select.c | 2 +-
src/box/sql/vdbe.c | 87 ++-----------------------------------------
src/box/sql/vdbeInt.h | 2 +-
src/box/sql/vdbeaux.c | 2 +-
7 files changed, 22 insertions(+), 92 deletions(-)
diff --git a/src/box/sql/analyze.c b/src/box/sql/analyze.c
index fb4ad2a81..b9b6f5da8 100644
--- a/src/box/sql/analyze.c
+++ b/src/box/sql/analyze.c
@@ -725,7 +725,7 @@ callStatGet(Vdbe * v, int regStat4, int iParam, int regOut)
*/
struct func *func = sql_func_by_signature("_sql_stat_get", 2);
assert(func != NULL);
- sqlVdbeAddOp4(v, OP_BuiltinFunction0, 0, regStat4, regOut,
+ sqlVdbeAddOp4(v, OP_BuiltinFunction, 0, regStat4, regOut,
(char *)func, P4_FUNC);
sqlVdbeChangeP5(v, 2);
}
@@ -869,7 +869,7 @@ vdbe_emit_analyze_space(struct Parse *parse, struct space *space)
struct func *init_func =
sql_func_by_signature("_sql_stat_init", 3);
assert(init_func != NULL);
- sqlVdbeAddOp4(v, OP_BuiltinFunction0, 0, stat4_reg + 1,
+ sqlVdbeAddOp4(v, OP_BuiltinFunction, 0, stat4_reg + 1,
stat4_reg, (char *)init_func, P4_FUNC);
sqlVdbeChangeP5(v, 3);
/*
@@ -974,7 +974,7 @@ vdbe_emit_analyze_space(struct Parse *parse, struct space *space)
struct func *push_func =
sql_func_by_signature("_sql_stat_push", 3);
assert(push_func != NULL);
- sqlVdbeAddOp4(v, OP_BuiltinFunction0, 1, stat4_reg, tmp_reg,
+ sqlVdbeAddOp4(v, OP_BuiltinFunction, 1, stat4_reg, tmp_reg,
(char *)push_func, P4_FUNC);
sqlVdbeChangeP5(v, 3);
sqlVdbeAddOp2(v, OP_Next, idx_cursor, next_row_addr);
diff --git a/src/box/sql/expr.c b/src/box/sql/expr.c
index 50dc98a94..d0bdee4fd 100644
--- a/src/box/sql/expr.c
+++ b/src/box/sql/expr.c
@@ -4168,7 +4168,7 @@ sqlExprCodeTarget(Parse * pParse, Expr * pExpr, int target)
sqlVdbeAddOp4(v, OP_CollSeq, 0, 0, 0,
(char *)coll, P4_COLLSEQ);
}
- if (sql_emit_func_call(v, pExpr, OP_BuiltinFunction0,
+ if (sql_emit_func_call(v, pExpr, OP_BuiltinFunction,
constMask, r1, target,
nFarg) != 0) {
pParse->is_aborted = true;
diff --git a/src/box/sql/func.c b/src/box/sql/func.c
index ea3b44472..4a0d2d097 100644
--- a/src/box/sql/func.c
+++ b/src/box/sql/func.c
@@ -2889,7 +2889,18 @@ sql_emit_func_call(struct Vdbe *vdbe, struct Expr *expr, int op, int mask,
struct func *func = sql_func_find(expr);
if (func == NULL)
return -1;
- sqlVdbeAddOp4(vdbe, op, mask, r1, r2, (char *)func, P4_FUNC);
+ 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;
+ ctx->pOut = NULL;
+ ctx->func = func;
+ ctx->iOp = 0;
+ ctx->pVdbe = vdbe;
+ ctx->argc = argc;
+ sqlVdbeAddOp4(vdbe, op, mask, r1, r2, (char *)ctx, P4_FUNCCTX);
sqlVdbeChangeP5(vdbe, argc);
return 0;
}
diff --git a/src/box/sql/select.c b/src/box/sql/select.c
index 87f2012f1..cb92f2ed0 100644
--- a/src/box/sql/select.c
+++ b/src/box/sql/select.c
@@ -5632,7 +5632,7 @@ updateAccumulator(Parse * pParse, AggInfo * pAggInfo)
sqlVdbeAddOp4(v, OP_CollSeq, regHit, 0, 0,
(char *)coll, P4_COLLSEQ);
}
- sql_emit_func_call(v, pF->pExpr, OP_AggStep0, 0, regAgg,
+ sql_emit_func_call(v, pF->pExpr, OP_AggStep, 0, regAgg,
pF->iMem, nArg);
sql_expr_type_cache_change(pParse, regAgg, nArg);
sqlReleaseTempRange(pParse, regAgg, nArg);
diff --git a/src/box/sql/vdbe.c b/src/box/sql/vdbe.c
index 7f86fa7b3..98ea37c67 100644
--- a/src/box/sql/vdbe.c
+++ b/src/box/sql/vdbe.c
@@ -1181,20 +1181,6 @@ case OP_CollSeq: {
break;
}
-/* Opcode: BuiltinFunction0 P1 P2 P3 P4 P5
- * Synopsis: r[P3]=func(r[P2@P5])
- *
- * Invoke a user function (P4 is a pointer to a FuncDef object that
- * defines the function) with P5 arguments taken from register P2 and
- * successors. The result of the function is stored in register P3.
- * Register P3 must not be one of the function inputs.
- *
- * P1 is a 32-bit bitmask indicating whether or not each argument to the
- * function was determined to be constant at compile time. If the first
- * argument was constant then bit 0 of P1 is set.
- *
- * See also: BuiltinFunction, AggStep, AggFinal
- */
/* Opcode: BuiltinFunction P1 P2 P3 P4 P5
* Synopsis: r[P3]=func(r[P2@P5])
*
@@ -1207,44 +1193,15 @@ case OP_CollSeq: {
* function was determined to be constant at compile time. If the first
* argument was constant then bit 0 of P1 is set.
*
- * SQL functions are initially coded as OP_BuiltinFunction0 with
- * P4 pointing to a FuncDef object. But on first evaluation,
- * the P4 operand is automatically converted into an sql_context
- * object and the operation changed to this OP_BuiltinFunction
- * opcode. In this way, the initialization of the sql_context
- * object occurs only once, rather than once for each evaluation
- * of the function.
- *
- * See also: BuiltinFunction0, AggStep, AggFinal
+ * See also: AggStep, AggFinal
*/
-case OP_BuiltinFunction0: {
- int n;
- sql_context *pCtx;
-
- assert(pOp->p4type == P4_FUNC);
- n = pOp->p5;
- assert(pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor));
- assert(n==0 || (pOp->p2>0 && pOp->p2+n<=(p->nMem+1 - p->nCursor)+1));
- assert(pOp->p3<pOp->p2 || pOp->p3>=pOp->p2+n);
- pCtx = sqlDbMallocRawNN(db, sizeof(*pCtx) + (n-1)*sizeof(sql_value*));
- if (pCtx==0) goto no_mem;
- pCtx->pOut = 0;
- pCtx->func = pOp->p4.func;
- pCtx->iOp = (int)(pOp - aOp);
- pCtx->pVdbe = p;
- pCtx->argc = n;
- pOp->p4type = P4_FUNCCTX;
- pOp->p4.pCtx = pCtx;
- pOp->opcode = OP_BuiltinFunction;
- /* Fall through into OP_BuiltinFunction */
- FALLTHROUGH;
-}
case OP_BuiltinFunction: {
int i;
sql_context *pCtx;
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
@@ -4184,17 +4141,6 @@ case OP_DecrJumpZero: { /* jump, in1 */
}
-/* Opcode: AggStep0 * P2 P3 P4 P5
- * Synopsis: accum=r[P3] step(r[P2@P5])
- *
- * Execute the step function for an aggregate. The
- * function has P5 arguments. P4 is a pointer to the FuncDef
- * structure that specifies the function. Register P3 is the
- * accumulator.
- *
- * The P5 arguments are taken from register P2 and its
- * successors.
- */
/* Opcode: AggStep * P2 P3 P4 P5
* Synopsis: accum=r[P3] step(r[P2@P5])
*
@@ -4205,35 +4151,7 @@ case OP_DecrJumpZero: { /* jump, in1 */
*
* The P5 arguments are taken from register P2 and its
* successors.
- *
- * This opcode is initially coded as OP_AggStep0. On first evaluation,
- * the FuncDef stored in P4 is converted into an sql_context and
- * the opcode is changed. In this way, the initialization of the
- * sql_context only happens once, instead of on each call to the
- * step function.
*/
-case OP_AggStep0: {
- int n;
- sql_context *pCtx;
-
- assert(pOp->p4type == P4_FUNC);
- n = pOp->p5;
- assert(pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor));
- assert(n==0 || (pOp->p2>0 && pOp->p2+n<=(p->nMem+1 - p->nCursor)+1));
- assert(pOp->p3<pOp->p2 || pOp->p3>=pOp->p2+n);
- pCtx = sqlDbMallocRawNN(db, sizeof(*pCtx) + (n-1)*sizeof(sql_value*));
- if (pCtx==0) goto no_mem;
- pCtx->pMem = 0;
- pCtx->func = pOp->p4.func;
- pCtx->iOp = (int)(pOp - aOp);
- pCtx->pVdbe = p;
- pCtx->argc = n;
- pOp->p4type = P4_FUNCCTX;
- pOp->p4.pCtx = pCtx;
- pOp->opcode = OP_AggStep;
- /* Fall through into OP_AggStep */
- FALLTHROUGH;
-}
case OP_AggStep: {
int i;
sql_context *pCtx;
@@ -4242,6 +4160,7 @@ 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[]
diff --git a/src/box/sql/vdbeInt.h b/src/box/sql/vdbeInt.h
index cfe743b94..073ac0b97 100644
--- a/src/box/sql/vdbeInt.h
+++ b/src/box/sql/vdbeInt.h
@@ -174,7 +174,7 @@ struct sql_context {
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. */
+ /** Instruction number of OP_BuiltinFunction or OP_AggStep. */
int iOp;
/*
* True, if an error occurred during the execution of the
diff --git a/src/box/sql/vdbeaux.c b/src/box/sql/vdbeaux.c
index 2d7800b17..662fbbf81 100644
--- a/src/box/sql/vdbeaux.c
+++ b/src/box/sql/vdbeaux.c
@@ -1070,7 +1070,7 @@ displayP4(Op * pOp, char *zTemp, int nTemp)
}
#if defined(SQL_DEBUG) || defined(VDBE_PROFILE)
case P4_FUNCCTX:{
- struct func *func = pOp->p4.func;
+ struct func *func = pOp->p4.pCtx->func;
sqlXPrintf(&x, "%s(%d)", func->def->name,
func->def->param_count);
break;
--
2.25.1
^ permalink raw reply [flat|nested] 6+ messages in thread
* [Tarantool-patches] [PATCH v2 2/5] sql: remove unnecessary MEM finalization
2021-08-19 5:31 [Tarantool-patches] [PATCH v2 0/5] Change structure of SQL-built-in functions Mergen Imeev via Tarantool-patches
2021-08-19 5:31 ` [Tarantool-patches] [PATCH v2 1/5] sql: remove OP_BuiltinFunction0 and OP_AggStep0 Mergen Imeev via Tarantool-patches
@ 2021-08-19 5:31 ` Mergen Imeev via Tarantool-patches
2021-08-19 5:31 ` [Tarantool-patches] [PATCH v2 3/5] sql: remove struct func from struct sql_context Mergen Imeev via Tarantool-patches
` (2 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Mergen Imeev via Tarantool-patches @ 2021-08-19 5:31 UTC (permalink / raw)
To: vdavydov; +Cc: tarantool-patches
After removing the setting of the error in the patch "sql: modify
arithmetic aggregate functions", we no longer need to finalize the MEM
that has not been finalized. The logic is this: if the MEM has not been
finalized, then something has happened, and we no longer need to
finalize it. The MEM will be freed like a normal MEM with allocated
memory.
Part of #6105
---
src/box/sql/mem.c | 34 ++--------------------------------
src/box/sql/mem.h | 19 +------------------
src/box/sql/vdbe.c | 14 +++++++++++++-
src/box/sql/vdbeapi.c | 10 ++--------
4 files changed, 18 insertions(+), 59 deletions(-)
diff --git a/src/box/sql/mem.c b/src/box/sql/mem.c
index 74febd182..01d73968c 100644
--- a/src/box/sql/mem.c
+++ b/src/box/sql/mem.c
@@ -217,11 +217,7 @@ mem_create(struct Mem *mem)
static inline void
mem_clear(struct Mem *mem)
{
- if ((mem->type & (MEM_TYPE_AGG | MEM_TYPE_FRAME)) != 0 ||
- (mem->flags & MEM_Dyn) != 0) {
- if (mem->type == MEM_TYPE_AGG)
- sql_vdbemem_finalize(mem, mem->u.func);
- assert(mem->type != MEM_TYPE_AGG);
+ if (mem->type == MEM_TYPE_FRAME || (mem->flags & MEM_Dyn) != 0) {
if ((mem->flags & MEM_Dyn) != 0) {
assert(mem->xDel != SQL_DYNAMIC && mem->xDel != NULL);
mem->xDel((void *)mem->z);
@@ -610,7 +606,7 @@ mem_set_frame(struct Mem *mem, struct VdbeFrame *frame)
}
int
-mem_set_agg(struct Mem *mem, struct func *func, int size)
+mem_set_agg(struct Mem *mem, int size)
{
mem_clear(mem);
if (size <= 0)
@@ -621,7 +617,6 @@ mem_set_agg(struct Mem *mem, struct func *func, int size)
mem->n = size;
mem->type = MEM_TYPE_AGG;
assert(mem->flags == 0);
- mem->u.func = func;
return 0;
}
@@ -3045,31 +3040,6 @@ sqlVdbeMemTooBig(Mem * p)
return 0;
}
-int
-sql_vdbemem_finalize(struct Mem *mem, struct func *func)
-{
- assert(func != NULL);
- assert(func->def->language == FUNC_LANGUAGE_SQL_BUILTIN);
- assert(func->def->aggregate == FUNC_AGGREGATE_GROUP);
- assert(mem->type == MEM_TYPE_NULL || func == mem->u.func);
- sql_context ctx;
- memset(&ctx, 0, sizeof(ctx));
- Mem t;
- memset(&t, 0, sizeof(t));
- t.type = MEM_TYPE_NULL;
- assert(t.flags == 0);
- t.db = mem->db;
- ctx.pOut = &t;
- ctx.pMem = mem;
- ctx.func = func;
- ((struct func_sql_builtin *)func)->finalize(&ctx);
- assert((mem->flags & MEM_Dyn) == 0);
- if (mem->szMalloc > 0)
- sqlDbFree(mem->db, mem->zMalloc);
- memcpy(mem, &t, sizeof(t));
- return ctx.is_aborted ? -1 : 0;
-}
-
int
sqlVdbeRecordCompareMsgpack(const void *key1,
struct UnpackedRecord *key2)
diff --git a/src/box/sql/mem.h b/src/box/sql/mem.h
index 543944b80..bddac1a67 100644
--- a/src/box/sql/mem.h
+++ b/src/box/sql/mem.h
@@ -70,11 +70,6 @@ struct Mem {
bool b; /* Boolean value used when MEM_Bool is set in flags */
int nZero; /* Used when bit MEM_Zero is set in flags */
void *p; /* Generic pointer */
- /**
- * A pointer to function implementation.
- * Used only when flags==MEM_Agg.
- */
- struct func *func;
struct VdbeFrame *pFrame; /* Used when flags==MEM_Frame */
struct tt_uuid uuid;
decimal_t d;
@@ -569,7 +564,7 @@ mem_set_frame(struct Mem *mem, struct VdbeFrame *frame);
* hold the accumulation structure for the aggregate function.
*/
int
-mem_set_agg(struct Mem *mem, struct func *func, int size);
+mem_set_agg(struct Mem *mem, int size);
/** Clear MEM and set it to special, "cleared", NULL. */
void
@@ -961,18 +956,6 @@ int sqlVdbeMemTooBig(Mem *);
#define VdbeMemDynamic(X) (((X)->flags & MEM_Dyn) != 0 ||\
((X)->type & (MEM_TYPE_AGG | MEM_TYPE_FRAME)) != 0)
-/** MEM manipulate functions. */
-
-/**
- * Memory cell mem contains the context of an aggregate function.
- * This routine calls the finalize method for that function. The
- * result of the aggregate is stored back into mem.
- *
- * Returns -1 if the finalizer reports an error. 0 otherwise.
- */
-int
-sql_vdbemem_finalize(struct Mem *mem, struct func *func);
-
/**
* Perform comparison of two tuples: unpacked (key1) and packed (key2)
*
diff --git a/src/box/sql/vdbe.c b/src/box/sql/vdbe.c
index 98ea37c67..9fb103e82 100644
--- a/src/box/sql/vdbe.c
+++ b/src/box/sql/vdbe.c
@@ -4219,8 +4219,20 @@ case OP_AggFinal: {
assert(pOp->p1>0 && pOp->p1<=(p->nMem+1 - p->nCursor));
pMem = &aMem[pOp->p1];
assert(mem_is_null(pMem) || mem_is_agg(pMem));
- if (sql_vdbemem_finalize(pMem, pOp->p4.func) != 0)
+ struct sql_context ctx;
+ memset(&ctx, 0, sizeof(ctx));
+ struct Mem t;
+ mem_create(&t);
+ ctx.pOut = &t;
+ ctx.pMem = pMem;
+ ((struct func_sql_builtin *)pOp->p4.func)->finalize(&ctx);
+ if (ctx.is_aborted)
goto abort_due_to_error;
+ assert((pMem->flags & MEM_Dyn) == 0);
+ if (pMem->szMalloc > 0)
+ sqlDbFree(pMem->db, pMem->zMalloc);
+ memcpy(pMem, &t, sizeof(t));
+
UPDATE_MAX_BLOBSIZE(pMem);
if (sqlVdbeMemTooBig(pMem)) {
goto too_big;
diff --git a/src/box/sql/vdbeapi.c b/src/box/sql/vdbeapi.c
index 8031ee0dc..52d008c5f 100644
--- a/src/box/sql/vdbeapi.c
+++ b/src/box/sql/vdbeapi.c
@@ -383,10 +383,7 @@ sqlStmtCurrentTime(sql_context * p)
void *
sql_aggregate_context(sql_context * p, int nByte)
{
- assert(p != NULL && p->func != NULL);
- assert(p->func->def->language == FUNC_LANGUAGE_SQL_BUILTIN);
- assert(p->func->def->aggregate == FUNC_AGGREGATE_GROUP);
- if (!mem_is_agg(p->pMem) && mem_set_agg(p->pMem, p->func, nByte) != 0)
+ if (!mem_is_agg(p->pMem) && mem_set_agg(p->pMem, nByte) != 0)
return NULL;
void *accum;
if (mem_get_agg(p->pMem, &accum) != 0)
@@ -397,12 +394,9 @@ sql_aggregate_context(sql_context * p, int nByte)
struct Mem *
sql_context_agg_mem(struct sql_context *ctx)
{
- assert(ctx != NULL && ctx->func != NULL);
- assert(ctx->func->def->language == FUNC_LANGUAGE_SQL_BUILTIN);
- assert(ctx->func->def->aggregate == FUNC_AGGREGATE_GROUP);
struct Mem *mem;
if (!mem_is_agg(ctx->pMem)) {
- if (mem_set_agg(ctx->pMem, ctx->func, sizeof(*mem)) != 0)
+ if (mem_set_agg(ctx->pMem, sizeof(*mem)) != 0)
return NULL;
if (mem_get_agg(ctx->pMem, (void **)&mem) != 0)
return NULL;
--
2.25.1
^ permalink raw reply [flat|nested] 6+ messages in thread
* [Tarantool-patches] [PATCH v2 3/5] sql: remove struct func from struct sql_context
2021-08-19 5:31 [Tarantool-patches] [PATCH v2 0/5] Change structure of SQL-built-in functions Mergen Imeev via Tarantool-patches
2021-08-19 5:31 ` [Tarantool-patches] [PATCH v2 1/5] sql: remove OP_BuiltinFunction0 and OP_AggStep0 Mergen Imeev via Tarantool-patches
2021-08-19 5:31 ` [Tarantool-patches] [PATCH v2 2/5] sql: remove unnecessary MEM finalization Mergen Imeev via Tarantool-patches
@ 2021-08-19 5:31 ` Mergen Imeev via Tarantool-patches
2021-08-19 5:31 ` [Tarantool-patches] [PATCH v2 4/5] sql: do not use struct func for finalization Mergen Imeev via Tarantool-patches
2021-08-19 5:31 ` [Tarantool-patches] [PATCH v2 5/5] sql: remove unused code Mergen Imeev via Tarantool-patches
4 siblings, 0 replies; 6+ messages in thread
From: Mergen Imeev via Tarantool-patches @ 2021-08-19 5:31 UTC (permalink / raw)
To: vdavydov; +Cc: tarantool-patches
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
^ permalink raw reply [flat|nested] 6+ messages in thread
* [Tarantool-patches] [PATCH v2 4/5] sql: do not use struct func for finalization
2021-08-19 5:31 [Tarantool-patches] [PATCH v2 0/5] Change structure of SQL-built-in functions Mergen Imeev via Tarantool-patches
` (2 preceding siblings ...)
2021-08-19 5:31 ` [Tarantool-patches] [PATCH v2 3/5] sql: remove struct func from struct sql_context Mergen Imeev via Tarantool-patches
@ 2021-08-19 5:31 ` Mergen Imeev via Tarantool-patches
2021-08-19 5:31 ` [Tarantool-patches] [PATCH v2 5/5] sql: remove unused code Mergen Imeev via Tarantool-patches
4 siblings, 0 replies; 6+ messages in thread
From: Mergen Imeev via Tarantool-patches @ 2021-08-19 5:31 UTC (permalink / raw)
To: vdavydov; +Cc: tarantool-patches
This patch removes struct func from finalization of SQL built-in aggregate
functions.
Part of #6105
---
src/box/sql/func.c | 30 ++++++++++++++++++++++++++----
src/box/sql/vdbe.c | 2 +-
src/box/sql/vdbe.h | 2 ++
3 files changed, 29 insertions(+), 5 deletions(-)
diff --git a/src/box/sql/func.c b/src/box/sql/func.c
index adbc6d5a4..e09224bb8 100644
--- a/src/box/sql/func.c
+++ b/src/box/sql/func.c
@@ -3008,9 +3008,31 @@ int
sql_emit_func_finalize(struct Vdbe *vdbe, struct Expr *expr, int reg,
uint8_t argc)
{
- struct func *func = sql_func_find(expr);
- if (func == NULL)
- return -1;
- sqlVdbeAddOp4(vdbe, OP_AggFinal, reg, argc, 0, (char *)func, P4_FUNC);
+ void (*finalize)(sql_context *ctx);
+ switch(expr->func_id) {
+ case TK_AVG:
+ finalize = avgFinalize;
+ break;
+ case TK_SUM:
+ finalize = sumFinalize;
+ break;
+ case TK_COUNT:
+ finalize = countFinalize;
+ break;
+ case TK_TOTAL:
+ finalize = totalFinalize;
+ break;
+ case TK_GROUP_CONCAT:
+ finalize = groupConcatFinalize;
+ break;
+ case TK_MAX:
+ case TK_MIN:
+ finalize = minMaxFinalize;
+ break;
+ default:
+ unreachable();
+ }
+ sqlVdbeAddOp4(vdbe, OP_AggFinal, reg, argc, 0, (char *)finalize,
+ P4_STATIC);
return 0;
}
diff --git a/src/box/sql/vdbe.c b/src/box/sql/vdbe.c
index c63dbaa5a..f821ac98a 100644
--- a/src/box/sql/vdbe.c
+++ b/src/box/sql/vdbe.c
@@ -4221,7 +4221,7 @@ case OP_AggFinal: {
mem_create(&t);
ctx.pOut = &t;
ctx.pMem = pMem;
- ((struct func_sql_builtin *)pOp->p4.func)->finalize(&ctx);
+ pOp->p4.finalize(&ctx);
if (ctx.is_aborted)
goto abort_due_to_error;
assert((pMem->flags & MEM_Dyn) == 0);
diff --git a/src/box/sql/vdbe.h b/src/box/sql/vdbe.h
index e40a1a0b3..1f6e566e1 100644
--- a/src/box/sql/vdbe.h
+++ b/src/box/sql/vdbe.h
@@ -97,6 +97,8 @@ struct VdbeOp {
* Information about ephemeral space field types and key parts.
*/
struct sql_space_info *space_info;
+ /* Finalize method for SQL built-in aggregate function. */
+ void (*finalize)(sql_context *ctx);
} p4;
#ifdef SQL_ENABLE_EXPLAIN_COMMENTS
char *zComment; /* Comment to improve readability */
--
2.25.1
^ permalink raw reply [flat|nested] 6+ messages in thread
* [Tarantool-patches] [PATCH v2 5/5] sql: remove unused code
2021-08-19 5:31 [Tarantool-patches] [PATCH v2 0/5] Change structure of SQL-built-in functions Mergen Imeev via Tarantool-patches
` (3 preceding siblings ...)
2021-08-19 5:31 ` [Tarantool-patches] [PATCH v2 4/5] sql: do not use struct func for finalization Mergen Imeev via Tarantool-patches
@ 2021-08-19 5:31 ` Mergen Imeev via Tarantool-patches
4 siblings, 0 replies; 6+ messages in thread
From: Mergen Imeev via Tarantool-patches @ 2021-08-19 5:31 UTC (permalink / raw)
To: vdavydov; +Cc: tarantool-patches
This patch removes code that become unused due to changes in SQL
built-in functions.
Part of #6105
---
src/box/box.cc | 1 -
src/box/sql.c | 1 -
src/box/sql.h | 9 -
src/box/sql/func.c | 837 ------------------------------------------
src/box/sql/sqlInt.h | 42 ---
src/box/sql/vdbe.h | 7 -
src/box/sql/vdbeInt.h | 2 -
src/box/sql/vdbeaux.c | 6 -
8 files changed, 905 deletions(-)
diff --git a/src/box/box.cc b/src/box/box.cc
index 0b12b1328..ce44df85b 100644
--- a/src/box/box.cc
+++ b/src/box/box.cc
@@ -3056,7 +3056,6 @@ box_free(void)
gc_free();
engine_shutdown();
wal_free();
- sql_built_in_functions_cache_free();
}
}
diff --git a/src/box/sql.c b/src/box/sql.c
index d15159d6e..7cadb8db5 100644
--- a/src/box/sql.c
+++ b/src/box/sql.c
@@ -75,7 +75,6 @@ sql_init(void)
panic("failed to initialize SQL subsystem");
sql_stmt_cache_init();
- sql_built_in_functions_cache_init();
assert(db != NULL);
}
diff --git a/src/box/sql.h b/src/box/sql.h
index 3ff00e64a..40fef2903 100644
--- a/src/box/sql.h
+++ b/src/box/sql.h
@@ -56,15 +56,6 @@ sql_init(void);
struct sql *
sql_get(void);
-/** Initialize global cache for built-in functions. */
-void
-sql_built_in_functions_cache_init(void);
-
-/** Free global cache for built-in functions. */
-void
-sql_built_in_functions_cache_free(void);
-
-
struct Expr;
struct Parse;
struct Select;
diff --git a/src/box/sql/func.c b/src/box/sql/func.c
index e09224bb8..dd2122436 100644
--- a/src/box/sql/func.c
+++ b/src/box/sql/func.c
@@ -50,8 +50,6 @@
#include "box/user.h"
#include "assoc.h"
-static struct mh_strnptr_t *built_in_functions = NULL;
-
static const unsigned char *
mem_as_ustr(struct Mem *mem)
{
@@ -1913,16 +1911,6 @@ sql_is_like_func(struct Expr *expr)
return 1;
}
-static int
-func_sql_builtin_call_stub(struct func *func, struct port *args,
- struct port *ret)
-{
- (void) func; (void) args; (void) ret;
- diag_set(ClientError, ER_UNSUPPORTED,
- "sql builtin function", "Lua frontend");
- return -1;
-}
-
static void
sql_builtin_stub(sql_context *ctx, int argc, sql_value **argv)
{
@@ -1931,831 +1919,6 @@ sql_builtin_stub(sql_context *ctx, int argc, sql_value **argv)
ctx->is_aborted = true;
}
-/**
- * A sequence of SQL builtins definitions in
- * lexicographic order.
- */
-static struct {
- /**
- * Name is used to find corresponding entry in array
- * sql_builtins applying binary search.
- */
- const char *name;
- /** Members below are related to struct func_sql_builtin. */
- uint16_t flags;
- void (*call)(sql_context *ctx, int argc, sql_value **argv);
- void (*finalize)(sql_context *ctx);
- /** Members below are related to struct func_def. */
- bool is_deterministic;
- int param_count;
- enum field_type returns;
- enum func_aggregate aggregate;
- bool export_to_sql;
-} sql_builtins[] = {
- {.name = "ABS",
- .param_count = 1,
- .returns = FIELD_TYPE_NUMBER,
- .aggregate = FUNC_AGGREGATE_NONE,
- .is_deterministic = true,
- .flags = 0,
- .call = absFunc,
- .finalize = NULL,
- .export_to_sql = true,
- }, {
- .name = "AVG",
- .param_count = 1,
- .returns = FIELD_TYPE_NUMBER,
- .is_deterministic = false,
- .aggregate = FUNC_AGGREGATE_GROUP,
- .flags = 0,
- .call = sum_step,
- .finalize = avgFinalize,
- .export_to_sql = true,
- }, {
- .name = "CEIL",
- .call = sql_builtin_stub,
- .export_to_sql = false,
- .param_count = -1,
- .returns = FIELD_TYPE_ANY,
- .aggregate = FUNC_AGGREGATE_NONE,
- .is_deterministic = false,
- .flags = 0,
- .finalize = NULL,
- }, {
- .name = "CEILING",
- .call = sql_builtin_stub,
- .export_to_sql = false,
- .param_count = -1,
- .returns = FIELD_TYPE_ANY,
- .aggregate = FUNC_AGGREGATE_NONE,
- .is_deterministic = false,
- .flags = 0,
- .finalize = NULL,
- }, {
- .name = "CHAR",
- .param_count = -1,
- .returns = FIELD_TYPE_STRING,
- .is_deterministic = true,
- .aggregate = FUNC_AGGREGATE_NONE,
- .flags = 0,
- .call = charFunc,
- .finalize = NULL,
- .export_to_sql = true,
- }, {
- .name = "CHARACTER_LENGTH",
- .param_count = 1,
- .returns = FIELD_TYPE_INTEGER,
- .aggregate = FUNC_AGGREGATE_NONE,
- .is_deterministic = true,
- .flags = 0,
- .call = lengthFunc,
- .finalize = NULL,
- .export_to_sql = true,
- }, {
- .name = "CHAR_LENGTH",
- .param_count = 1,
- .returns = FIELD_TYPE_INTEGER,
- .aggregate = FUNC_AGGREGATE_NONE,
- .is_deterministic = true,
- .flags = 0,
- .call = lengthFunc,
- .finalize = NULL,
- .export_to_sql = true,
- }, {
- .name = "COALESCE",
- .param_count = -1,
- .returns = FIELD_TYPE_SCALAR,
- .aggregate = FUNC_AGGREGATE_NONE,
- .is_deterministic = true,
- .flags = SQL_FUNC_COALESCE,
- .call = sql_builtin_stub,
- .finalize = NULL,
- .export_to_sql = true,
- }, {
- .name = "COUNT",
- .param_count = -1,
- .returns = FIELD_TYPE_INTEGER,
- .aggregate = FUNC_AGGREGATE_GROUP,
- .is_deterministic = false,
- .flags = 0,
- .call = countStep,
- .finalize = countFinalize,
- .export_to_sql = true,
- }, {
- .name = "CURRENT_DATE",
- .call = sql_builtin_stub,
- .export_to_sql = false,
- .param_count = -1,
- .returns = FIELD_TYPE_ANY,
- .aggregate = FUNC_AGGREGATE_NONE,
- .is_deterministic = false,
- .flags = 0,
- .finalize = NULL,
- }, {
- .name = "CURRENT_TIME",
- .call = sql_builtin_stub,
- .export_to_sql = false,
- .param_count = -1,
- .returns = FIELD_TYPE_ANY,
- .aggregate = FUNC_AGGREGATE_NONE,
- .is_deterministic = false,
- .flags = 0,
- .finalize = NULL,
- }, {
- .name = "CURRENT_TIMESTAMP",
- .call = sql_builtin_stub,
- .export_to_sql = false,
- .param_count = -1,
- .returns = FIELD_TYPE_ANY,
- .aggregate = FUNC_AGGREGATE_NONE,
- .is_deterministic = false,
- .flags = 0,
- .finalize = NULL,
- }, {
- .name = "DATE",
- .call = sql_builtin_stub,
- .export_to_sql = false,
- .param_count = -1,
- .returns = FIELD_TYPE_ANY,
- .aggregate = FUNC_AGGREGATE_NONE,
- .is_deterministic = false,
- .flags = 0,
- .finalize = NULL,
- }, {
- .name = "DATETIME",
- .call = sql_builtin_stub,
- .export_to_sql = false,
- .param_count = -1,
- .returns = FIELD_TYPE_ANY,
- .aggregate = FUNC_AGGREGATE_NONE,
- .is_deterministic = false,
- .flags = 0,
- .finalize = NULL,
- }, {
- .name = "EVERY",
- .call = sql_builtin_stub,
- .export_to_sql = false,
- .param_count = -1,
- .returns = FIELD_TYPE_ANY,
- .aggregate = FUNC_AGGREGATE_NONE,
- .is_deterministic = false,
- .flags = 0,
- .finalize = NULL,
- }, {
- .name = "EXISTS",
- .call = sql_builtin_stub,
- .export_to_sql = false,
- .param_count = -1,
- .returns = FIELD_TYPE_ANY,
- .aggregate = FUNC_AGGREGATE_NONE,
- .is_deterministic = false,
- .flags = 0,
- .finalize = NULL,
- }, {
- .name = "EXP",
- .call = sql_builtin_stub,
- .export_to_sql = false,
- .param_count = -1,
- .returns = FIELD_TYPE_ANY,
- .aggregate = FUNC_AGGREGATE_NONE,
- .is_deterministic = false,
- .flags = 0,
- .finalize = NULL,
- }, {
- .name = "EXTRACT",
- .call = sql_builtin_stub,
- .export_to_sql = false,
- .param_count = -1,
- .returns = FIELD_TYPE_ANY,
- .aggregate = FUNC_AGGREGATE_NONE,
- .is_deterministic = false,
- .flags = 0,
- .finalize = NULL,
- }, {
- .name = "FLOOR",
- .call = sql_builtin_stub,
- .export_to_sql = false,
- .param_count = -1,
- .returns = FIELD_TYPE_ANY,
- .aggregate = FUNC_AGGREGATE_NONE,
- .is_deterministic = false,
- .flags = 0,
- .finalize = NULL,
- }, {
- .name = "GREATER",
- .call = sql_builtin_stub,
- .export_to_sql = false,
- .param_count = -1,
- .returns = FIELD_TYPE_ANY,
- .aggregate = FUNC_AGGREGATE_NONE,
- .is_deterministic = false,
- .flags = 0,
- .finalize = NULL,
- }, {
- .name = "GREATEST",
- .param_count = -1,
- .returns = FIELD_TYPE_SCALAR,
- .aggregate = FUNC_AGGREGATE_NONE,
- .is_deterministic = true,
- .flags = SQL_FUNC_NEEDCOLL | SQL_FUNC_MAX,
- .call = minmaxFunc,
- .finalize = NULL,
- .export_to_sql = true,
- }, {
- .name = "GROUP_CONCAT",
- .param_count = -1,
- .returns = FIELD_TYPE_STRING,
- .aggregate = FUNC_AGGREGATE_GROUP,
- .is_deterministic = false,
- .flags = 0,
- .call = groupConcatStep,
- .finalize = groupConcatFinalize,
- .export_to_sql = true,
- }, {
- .name = "HEX",
- .param_count = 1,
- .returns = FIELD_TYPE_STRING,
- .aggregate = FUNC_AGGREGATE_NONE,
- .is_deterministic = true,
- .flags = 0,
- .call = hexFunc,
- .finalize = NULL,
- .export_to_sql = true,
- }, {
- .name = "IFNULL",
- .param_count = 2,
- .returns = FIELD_TYPE_SCALAR,
- .aggregate = FUNC_AGGREGATE_NONE,
- .is_deterministic = true,
- .flags = SQL_FUNC_COALESCE,
- .call = sql_builtin_stub,
- .finalize = NULL,
- .export_to_sql = true,
- }, {
- .name = "JULIANDAY",
- .call = sql_builtin_stub,
- .export_to_sql = false,
- .param_count = -1,
- .returns = FIELD_TYPE_ANY,
- .aggregate = FUNC_AGGREGATE_NONE,
- .is_deterministic = false,
- .flags = 0,
- .finalize = NULL,
- }, {
- .name = "LEAST",
- .param_count = -1,
- .returns = FIELD_TYPE_SCALAR,
- .aggregate = FUNC_AGGREGATE_NONE,
- .is_deterministic = true,
- .flags = SQL_FUNC_NEEDCOLL | SQL_FUNC_MIN,
- .call = minmaxFunc,
- .finalize = NULL,
- .export_to_sql = true,
- }, {
- .name = "LENGTH",
- .param_count = 1,
- .returns = FIELD_TYPE_INTEGER,
- .aggregate = FUNC_AGGREGATE_NONE,
- .is_deterministic = true,
- .flags = SQL_FUNC_LENGTH,
- .call = lengthFunc,
- .finalize = NULL,
- .export_to_sql = true,
- }, {
- .name = "LESSER",
- .call = sql_builtin_stub,
- .export_to_sql = false,
- .param_count = -1,
- .returns = FIELD_TYPE_ANY,
- .aggregate = FUNC_AGGREGATE_NONE,
- .is_deterministic = false,
- .flags = 0,
- .finalize = NULL,
- }, {
- .name = "LIKE",
- .param_count = -1,
- .returns = FIELD_TYPE_INTEGER,
- .aggregate = FUNC_AGGREGATE_NONE,
- .is_deterministic = true,
- .flags = SQL_FUNC_NEEDCOLL | SQL_FUNC_LIKE,
- .call = likeFunc,
- .finalize = NULL,
- .export_to_sql = true,
- }, {
- .name = "LIKELIHOOD",
- .param_count = 2,
- .returns = FIELD_TYPE_BOOLEAN,
- .aggregate = FUNC_AGGREGATE_NONE,
- .is_deterministic = true,
- .flags = SQL_FUNC_UNLIKELY,
- .call = sql_builtin_stub,
- .finalize = NULL,
- .export_to_sql = true,
- }, {
- .name = "LIKELY",
- .param_count = 1,
- .returns = FIELD_TYPE_BOOLEAN,
- .aggregate = FUNC_AGGREGATE_NONE,
- .is_deterministic = true,
- .flags = SQL_FUNC_UNLIKELY,
- .call = sql_builtin_stub,
- .finalize = NULL,
- .export_to_sql = true,
- }, {
- .name = "LN",
- .call = sql_builtin_stub,
- .export_to_sql = false,
- .param_count = -1,
- .returns = FIELD_TYPE_ANY,
- .aggregate = FUNC_AGGREGATE_NONE,
- .is_deterministic = false,
- .flags = 0,
- .finalize = NULL,
- }, {
- .name = "LOWER",
- .param_count = 1,
- .returns = FIELD_TYPE_STRING,
- .aggregate = FUNC_AGGREGATE_NONE,
- .is_deterministic = true,
- .flags = SQL_FUNC_DERIVEDCOLL | SQL_FUNC_NEEDCOLL,
- .call = LowerICUFunc,
- .finalize = NULL,
- .export_to_sql = true,
- }, {
- .name = "MAX",
- .param_count = 1,
- .returns = FIELD_TYPE_SCALAR,
- .aggregate = FUNC_AGGREGATE_GROUP,
- .is_deterministic = false,
- .flags = SQL_FUNC_NEEDCOLL | SQL_FUNC_MAX,
- .call = minmaxStep,
- .finalize = minMaxFinalize,
- .export_to_sql = true,
- }, {
- .name = "MIN",
- .param_count = 1,
- .returns = FIELD_TYPE_SCALAR,
- .aggregate = FUNC_AGGREGATE_GROUP,
- .is_deterministic = false,
- .flags = SQL_FUNC_NEEDCOLL | SQL_FUNC_MIN,
- .call = minmaxStep,
- .finalize = minMaxFinalize,
- .export_to_sql = true,
- }, {
- .name = "MOD",
- .call = sql_builtin_stub,
- .export_to_sql = false,
- .param_count = -1,
- .returns = FIELD_TYPE_ANY,
- .aggregate = FUNC_AGGREGATE_NONE,
- .is_deterministic = false,
- .flags = 0,
- .finalize = NULL,
- }, {
- .name = "NULLIF",
- .param_count = 2,
- .returns = FIELD_TYPE_SCALAR,
- .aggregate = FUNC_AGGREGATE_NONE,
- .is_deterministic = true,
- .flags = SQL_FUNC_NEEDCOLL,
- .call = nullifFunc,
- .finalize = NULL,
- .export_to_sql = true,
- }, {
- .name = "OCTET_LENGTH",
- .call = sql_builtin_stub,
- .export_to_sql = false,
- .param_count = -1,
- .returns = FIELD_TYPE_ANY,
- .aggregate = FUNC_AGGREGATE_NONE,
- .is_deterministic = false,
- .flags = 0,
- .finalize = NULL,
- }, {
- .name = "POSITION",
- .param_count = 2,
- .returns = FIELD_TYPE_INTEGER,
- .aggregate = FUNC_AGGREGATE_NONE,
- .is_deterministic = true,
- .flags = SQL_FUNC_NEEDCOLL,
- .call = position_func,
- .finalize = NULL,
- .export_to_sql = true,
- }, {
- .name = "POWER",
- .call = sql_builtin_stub,
- .export_to_sql = false,
- .param_count = -1,
- .returns = FIELD_TYPE_ANY,
- .aggregate = FUNC_AGGREGATE_NONE,
- .is_deterministic = false,
- .flags = 0,
- .finalize = NULL,
- }, {
- .name = "PRINTF",
- .param_count = -1,
- .returns = FIELD_TYPE_STRING,
- .aggregate = FUNC_AGGREGATE_NONE,
- .is_deterministic = true,
- .flags = 0,
- .call = printfFunc,
- .finalize = NULL,
- .export_to_sql = true,
- }, {
- .name = "QUOTE",
- .param_count = 1,
- .returns = FIELD_TYPE_STRING,
- .aggregate = FUNC_AGGREGATE_NONE,
- .is_deterministic = true,
- .flags = 0,
- .call = quoteFunc,
- .finalize = NULL,
- .export_to_sql = true,
- }, {
- .name = "RANDOM",
- .param_count = 0,
- .returns = FIELD_TYPE_INTEGER,
- .aggregate = FUNC_AGGREGATE_NONE,
- .is_deterministic = false,
- .flags = 0,
- .call = randomFunc,
- .finalize = NULL,
- .export_to_sql = true,
- }, {
- .name = "RANDOMBLOB",
- .param_count = 1,
- .returns = FIELD_TYPE_VARBINARY,
- .aggregate = FUNC_AGGREGATE_NONE,
- .is_deterministic = false,
- .flags = 0,
- .call = randomBlob,
- .finalize = NULL,
- .export_to_sql = true,
- }, {
- .name = "REPLACE",
- .param_count = 3,
- .returns = FIELD_TYPE_STRING,
- .aggregate = FUNC_AGGREGATE_NONE,
- .is_deterministic = true,
- .flags = SQL_FUNC_DERIVEDCOLL,
- .call = replaceFunc,
- .finalize = NULL,
- .export_to_sql = true,
- }, {
- .name = "ROUND",
- .param_count = -1,
- .returns = FIELD_TYPE_INTEGER,
- .aggregate = FUNC_AGGREGATE_NONE,
- .is_deterministic = true,
- .flags = 0,
- .call = roundFunc,
- .finalize = NULL,
- .export_to_sql = true,
- }, {
- .name = "ROW_COUNT",
- .param_count = 0,
- .returns = FIELD_TYPE_INTEGER,
- .aggregate = FUNC_AGGREGATE_NONE,
- .is_deterministic = true,
- .flags = 0,
- .call = sql_row_count,
- .finalize = NULL,
- .export_to_sql = true,
- }, {
- .name = "SOME",
- .call = sql_builtin_stub,
- .export_to_sql = false,
- .param_count = -1,
- .returns = FIELD_TYPE_ANY,
- .aggregate = FUNC_AGGREGATE_NONE,
- .is_deterministic = false,
- .flags = 0,
- .finalize = NULL,
- }, {
- .name = "SOUNDEX",
- .param_count = 1,
- .returns = FIELD_TYPE_STRING,
- .aggregate = FUNC_AGGREGATE_NONE,
- .is_deterministic = true,
- .flags = 0,
- .call = soundexFunc,
- .finalize = NULL,
- .export_to_sql = true,
- }, {
- .name = "SQRT",
- .call = sql_builtin_stub,
- .export_to_sql = false,
- .param_count = -1,
- .returns = FIELD_TYPE_ANY,
- .aggregate = FUNC_AGGREGATE_NONE,
- .is_deterministic = false,
- .flags = 0,
- .finalize = NULL,
- }, {
- .name = "STRFTIME",
- .call = sql_builtin_stub,
- .export_to_sql = false,
- .param_count = -1,
- .returns = FIELD_TYPE_ANY,
- .aggregate = FUNC_AGGREGATE_NONE,
- .is_deterministic = false,
- .flags = 0,
- .finalize = NULL,
- }, {
- .name = "SUBSTR",
- .param_count = -1,
- .returns = FIELD_TYPE_STRING,
- .aggregate = FUNC_AGGREGATE_NONE,
- .is_deterministic = true,
- .flags = SQL_FUNC_DERIVEDCOLL,
- .call = substrFunc,
- .finalize = NULL,
- .export_to_sql = true,
- }, {
- .name = "SUM",
- .param_count = 1,
- .returns = FIELD_TYPE_NUMBER,
- .aggregate = FUNC_AGGREGATE_GROUP,
- .is_deterministic = false,
- .flags = 0,
- .call = sum_step,
- .finalize = sumFinalize,
- .export_to_sql = true,
- }, {
- .name = "TIME",
- .call = sql_builtin_stub,
- .export_to_sql = false,
- .param_count = -1,
- .returns = FIELD_TYPE_ANY,
- .aggregate = FUNC_AGGREGATE_NONE,
- .is_deterministic = false,
- .flags = 0,
- .finalize = NULL,
- }, {
- .name = "TOTAL",
- .param_count = 1,
- .returns = FIELD_TYPE_NUMBER,
- .aggregate = FUNC_AGGREGATE_GROUP,
- .is_deterministic = false,
- .flags = 0,
- .call = total_step,
- .finalize = totalFinalize,
- .export_to_sql = true,
- }, {
- .name = "TRIM",
- .param_count = -1,
- .returns = FIELD_TYPE_STRING,
- .aggregate = FUNC_AGGREGATE_NONE,
- .is_deterministic = true,
- .flags = SQL_FUNC_DERIVEDCOLL,
- .call = trim_func,
- .finalize = NULL,
- .export_to_sql = true,
- }, {
- .name = "TYPEOF",
- .param_count = 1,
- .returns = FIELD_TYPE_STRING,
- .aggregate = FUNC_AGGREGATE_NONE,
- .is_deterministic = true,
- .flags = SQL_FUNC_TYPEOF,
- .call = typeofFunc,
- .finalize = NULL,
- .export_to_sql = true,
- }, {
- .name = "UNICODE",
- .param_count = 1,
- .returns = FIELD_TYPE_STRING,
- .aggregate = FUNC_AGGREGATE_NONE,
- .is_deterministic = true,
- .flags = 0,
- .call = unicodeFunc,
- .finalize = NULL,
- .export_to_sql = true,
- }, {
- .name = "UNLIKELY",
- .param_count = 1,
- .returns = FIELD_TYPE_BOOLEAN,
- .aggregate = FUNC_AGGREGATE_NONE,
- .is_deterministic = true,
- .flags = SQL_FUNC_UNLIKELY,
- .call = sql_builtin_stub,
- .finalize = NULL,
- .export_to_sql = true,
- }, {
- .name = "UPPER",
- .param_count = 1,
- .returns = FIELD_TYPE_STRING,
- .aggregate = FUNC_AGGREGATE_NONE,
- .is_deterministic = true,
- .flags = SQL_FUNC_DERIVEDCOLL | SQL_FUNC_NEEDCOLL,
- .call = UpperICUFunc,
- .finalize = NULL,
- .export_to_sql = true,
- }, {
- .name = "UUID",
- .param_count = -1,
- .returns = FIELD_TYPE_UUID,
- .aggregate = FUNC_AGGREGATE_NONE,
- .is_deterministic = false,
- .flags = 0,
- .call = sql_func_uuid,
- .finalize = NULL,
- .export_to_sql = true,
- }, {
- .name = "VERSION",
- .param_count = 0,
- .returns = FIELD_TYPE_STRING,
- .aggregate = FUNC_AGGREGATE_NONE,
- .is_deterministic = true,
- .flags = 0,
- .call = sql_func_version,
- .finalize = NULL,
- .export_to_sql = true,
- }, {
- .name = "ZEROBLOB",
- .param_count = 1,
- .returns = FIELD_TYPE_VARBINARY,
- .aggregate = FUNC_AGGREGATE_NONE,
- .is_deterministic = true,
- .flags = 0,
- .call = zeroblobFunc,
- .finalize = NULL,
- .export_to_sql = true,
- }, {
- .name = "_sql_stat_get",
- .call = sql_builtin_stub,
- .export_to_sql = false,
- .param_count = -1,
- .returns = FIELD_TYPE_ANY,
- .aggregate = FUNC_AGGREGATE_NONE,
- .is_deterministic = false,
- .flags = 0,
- .finalize = NULL,
- }, {
- .name = "_sql_stat_init",
- .call = sql_builtin_stub,
- .export_to_sql = false,
- .param_count = -1,
- .returns = FIELD_TYPE_ANY,
- .aggregate = FUNC_AGGREGATE_NONE,
- .is_deterministic = false,
- .flags = 0,
- .finalize = NULL,
- }, {
- .name = "_sql_stat_push",
- .call = sql_builtin_stub,
- .export_to_sql = false,
- .param_count = -1,
- .returns = FIELD_TYPE_ANY,
- .aggregate = FUNC_AGGREGATE_NONE,
- .is_deterministic = false,
- .flags = 0,
- .finalize = NULL,
- },
-};
-
-static struct func *
-built_in_func_get(const char *name)
-{
- uint32_t len = strlen(name);
- mh_int_t k = mh_strnptr_find_inp(built_in_functions, name, len);
- if (k == mh_end(built_in_functions))
- return NULL;
- return mh_strnptr_node(built_in_functions, k)->val;
-}
-
-static void
-built_in_func_put(struct func *func)
-{
- const char *name = func->def->name;
- uint32_t len = strlen(name);
- assert(built_in_func_get(name) == NULL);
-
- uint32_t hash = mh_strn_hash(name, len);
- const struct mh_strnptr_node_t strnode = {name, len, hash, func};
- mh_int_t k = mh_strnptr_put(built_in_functions, &strnode, NULL, NULL);
- if (k == mh_end(built_in_functions)) {
- panic("Out of memory on insertion into SQL built-in functions "
- "hash");
- }
-}
-
-struct func *
-sql_func_find(struct Expr *expr)
-{
- const char *name = expr->u.zToken;
- int n = expr->x.pList ? expr->x.pList->nExpr : 0;
- struct func *func = built_in_func_get(name);
- if (func != NULL) {
- assert(func->def->exports.sql);
- int param_count = func->def->param_count;
- if (param_count != -1 && param_count != n) {
- diag_set(ClientError, ER_FUNC_WRONG_ARG_COUNT, name,
- tt_sprintf("%d", func->def->param_count), n);
- return NULL;
- }
- return func;
- }
- func = func_by_name(name, strlen(name));
- if (func == NULL) {
- diag_set(ClientError, ER_NO_SUCH_FUNCTION, name);
- return NULL;
- }
- if (!func->def->exports.sql) {
- diag_set(ClientError, ER_SQL_PARSER_GENERIC,
- tt_sprintf("function %s() is not available in SQL",
- name));
- return NULL;
- }
- if (func->def->param_count != n) {
- diag_set(ClientError, ER_FUNC_WRONG_ARG_COUNT, name,
- tt_sprintf("%d", func->def->param_count), n);
- return NULL;
- }
- return func;
-}
-
-static struct func_vtab func_sql_builtin_vtab;
-
-void
-sql_built_in_functions_cache_init(void)
-{
- built_in_functions = mh_strnptr_new();
- if (built_in_functions == NULL)
- panic("Out of memory on creating SQL built-in functions hash");
- for (uint32_t i = 0; i < nelem(sql_builtins); ++i) {
- const char *name = sql_builtins[i].name;
- if (!sql_builtins[i].export_to_sql)
- continue;
- uint32_t len = strlen(name);
- uint32_t size = sizeof(struct func_def) + len + 1;
- struct func_def *def = malloc(size);
- if (def == NULL)
- panic("Out of memory on creating SQL built-in");
- def->fid = i;
- def->uid = 1;
- def->body = NULL;
- def->comment = NULL;
- def->setuid = true;
- def->is_deterministic = sql_builtins[i].is_deterministic;
- def->is_sandboxed = false;
- def->param_count = sql_builtins[i].param_count;
- def->returns = sql_builtins[i].returns;
- def->aggregate = sql_builtins[i].aggregate;
- def->language = FUNC_LANGUAGE_SQL_BUILTIN;
- def->name_len = len;
- def->exports.sql = sql_builtins[i].export_to_sql;
- func_opts_create(&def->opts);
- memcpy(def->name, name, len + 1);
-
- struct func_sql_builtin *func = malloc(sizeof(*func));
- if (func == NULL)
- panic("Out of memory on creating SQL built-in");
-
- func->base.def = def;
- func->base.vtab = &func_sql_builtin_vtab;
- credentials_create_empty(&func->base.owner_credentials);
- memset(func->base.access, 0, sizeof(func->base.access));
-
- func->flags = sql_builtins[i].flags;
- func->call = sql_builtins[i].call;
- func->finalize = sql_builtins[i].finalize;
- built_in_func_put(&func->base);
- }
-}
-
-void
-sql_built_in_functions_cache_free(void)
-{
- if (built_in_functions == NULL)
- return;
- for (uint32_t i = 0; i < nelem(sql_builtins); ++i) {
- const char *name = sql_builtins[i].name;
- uint32_t len = strlen(name);
- mh_int_t k = mh_strnptr_find_inp(built_in_functions, name, len);
- if (k == mh_end(built_in_functions))
- continue;
- struct func *func = mh_strnptr_node(built_in_functions, k)->val;
- mh_strnptr_del(built_in_functions, k, NULL);
- func_delete(func);
- }
- assert(mh_size(built_in_functions) == 0);
- mh_strnptr_delete(built_in_functions);
-}
-
-static void
-func_sql_builtin_destroy(struct func *func)
-{
- assert(func->vtab == &func_sql_builtin_vtab);
- assert(func->def->language == FUNC_LANGUAGE_SQL_BUILTIN);
- free(func);
-}
-
-static struct func_vtab func_sql_builtin_vtab = {
- .call = func_sql_builtin_call_stub,
- .destroy = func_sql_builtin_destroy,
-};
-
uint32_t
sql_func_flags(uint8_t id)
{
diff --git a/src/box/sql/sqlInt.h b/src/box/sql/sqlInt.h
index 8edee0cef..a4257fc0f 100644
--- a/src/box/sql/sqlInt.h
+++ b/src/box/sql/sqlInt.h
@@ -4359,48 +4359,6 @@ Expr *sqlExprForVectorField(Parse *, Expr *, int);
*/
extern int sqlSubProgramsRemaining;
-struct func_sql_builtin {
- /** Function object base class. */
- struct func base;
- /** A bitmask of SQL flags. */
- uint16_t flags;
- /**
- * A VDBE-memory-compatible call method.
- * SQL built-ins don't use func base class "call"
- * method to provide a best performance for SQL requests.
- * Access checks are redundant, because all SQL built-ins
- * are predefined and are executed on SQL privilege level.
- */
- void (*call)(sql_context *ctx, int argc, sql_value **argv);
- /**
- * A VDBE-memory-compatible finalize method
- * (is valid only for aggregate function).
- */
- void (*finalize)(sql_context *ctx);
-};
-
-/**
- * Test whether SQL-specific flag is set for given function.
- * Currently only SQL Builtin Functions have such hint flags,
- * so function returns false for other functions. Such approach
- * decreases code complexity and allows do not distinguish
- * functions by implementation details where it is unnecessary.
- *
- * Returns true when given flag is set for a given function and
- * false otherwise.
- */
-static inline bool
-sql_func_flag_is_set(struct func *func, uint16_t flag)
-{
- if (func->def->language != FUNC_LANGUAGE_SQL_BUILTIN)
- return false;
- return (((struct func_sql_builtin *)func)->flags & flag) != 0;
-}
-
-/** Return a function that matches the parameters described in given expr. */
-struct func *
-sql_func_find(struct Expr *expr);
-
/** Return user-defined function with given name and number of arguments. */
struct func *
sql_func_by_signature(const char *name, uint32_t argc);
diff --git a/src/box/sql/vdbe.h b/src/box/sql/vdbe.h
index 1f6e566e1..eef472ed9 100644
--- a/src/box/sql/vdbe.h
+++ b/src/box/sql/vdbe.h
@@ -72,11 +72,6 @@ struct VdbeOp {
char *z; /* Pointer to data for string (char array) types */
i64 *pI64; /* Used when p4type is P4_INT64/UINT64 */
double *pReal; /* Used when p4type is P4_REAL */
- /**
- * A pointer to function implementation.
- * Used when p4type is P4_FUNC.
- */
- struct func *func;
sql_context *pCtx; /* Used when p4type is P4_FUNCCTX */
struct coll *pColl; /* Used when p4type is P4_COLLSEQ */
Mem *pMem; /* Used when p4type is P4_MEM */
@@ -132,8 +127,6 @@ struct SubProgram {
#define P4_DYNAMIC (-1) /* Pointer to a string obtained from sqlMalloc() */
#define P4_STATIC (-2) /* Pointer to a static string */
#define P4_COLLSEQ (-3) /* P4 is a pointer to a CollSeq structure */
-/** P4 is a pointer to a func structure. */
-#define P4_FUNC (-4)
#define P4_MEM (-7) /* P4 is a pointer to a Mem* structure */
#define P4_TRANSIENT 0 /* P4 is a pointer to a transient string */
#define P4_REAL (-9) /* P4 is a 64-bit floating point value */
diff --git a/src/box/sql/vdbeInt.h b/src/box/sql/vdbeInt.h
index 0a0e6cc97..231605e61 100644
--- a/src/box/sql/vdbeInt.h
+++ b/src/box/sql/vdbeInt.h
@@ -46,8 +46,6 @@
*/
typedef struct VdbeOp Op;
-struct func;
-
/*
* Boolean values
*/
diff --git a/src/box/sql/vdbeaux.c b/src/box/sql/vdbeaux.c
index 3913dc637..0c37a30f9 100644
--- a/src/box/sql/vdbeaux.c
+++ b/src/box/sql/vdbeaux.c
@@ -1062,12 +1062,6 @@ displayP4(Op * pOp, char *zTemp, int nTemp)
sqlXPrintf(&x, "(binary)");
break;
}
- case P4_FUNC:{
- struct func *func = pOp->p4.func;
- sqlXPrintf(&x, "%s(%d)", func->def->name,
- func->def->param_count);
- break;
- }
#if defined(SQL_DEBUG) || defined(VDBE_PROFILE)
case P4_FUNCCTX:{
sqlXPrintf(&x, "%s(%d)", pOp->p4.pCtx->name,
--
2.25.1
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2021-08-19 5:34 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-08-19 5:31 [Tarantool-patches] [PATCH v2 0/5] Change structure of SQL-built-in functions Mergen Imeev via Tarantool-patches
2021-08-19 5:31 ` [Tarantool-patches] [PATCH v2 1/5] sql: remove OP_BuiltinFunction0 and OP_AggStep0 Mergen Imeev via Tarantool-patches
2021-08-19 5:31 ` [Tarantool-patches] [PATCH v2 2/5] sql: remove unnecessary MEM finalization Mergen Imeev via Tarantool-patches
2021-08-19 5:31 ` [Tarantool-patches] [PATCH v2 3/5] sql: remove struct func from struct sql_context Mergen Imeev via Tarantool-patches
2021-08-19 5:31 ` [Tarantool-patches] [PATCH v2 4/5] sql: do not use struct func for finalization Mergen Imeev via Tarantool-patches
2021-08-19 5:31 ` [Tarantool-patches] [PATCH v2 5/5] sql: remove unused code Mergen Imeev via Tarantool-patches
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox