[Tarantool-patches] [PATCH v2 5/5] sql: encapsulate SQL built-in functions opcodes

imeevma at tarantool.org imeevma at tarantool.org
Wed Aug 18 17:35:05 MSK 2021


This patch encapsulates opcodes for SQL built-in functions, which allows
us to modify the structure of SQL built-in functions and add an
ApplyType opcode if necessary.

Part of #6105
---
 src/box/sql/expr.c   |  8 +++-----
 src/box/sql/func.c   | 23 +++++++++++++++++++++++
 src/box/sql/select.c | 12 ++++--------
 src/box/sql/sqlInt.h |  8 ++++++++
 4 files changed, 38 insertions(+), 13 deletions(-)

diff --git a/src/box/sql/expr.c b/src/box/sql/expr.c
index 0544539d2..bf3ee359b 100644
--- a/src/box/sql/expr.c
+++ b/src/box/sql/expr.c
@@ -4165,14 +4165,12 @@ sqlExprCodeTarget(Parse * pParse, Expr * pExpr, int target)
 				sqlVdbeAddOp4(v, OP_CollSeq, 0, 0, 0,
 						  (char *)coll, P4_COLLSEQ);
 			}
-			struct func *func = sql_func_find(pExpr);
-			if (func == NULL) {
+			if (sql_emit_func_call(v, pExpr, OP_BuiltinFunction0,
+					       constMask, r1, target,
+					       nFarg) != 0) {
 				pParse->is_aborted = true;
 				break;
 			}
-			sqlVdbeAddOp4(v, OP_BuiltinFunction0, constMask, r1,
-				      target, (char *)func, P4_FUNC);
-			sqlVdbeChangeP5(v, (u8) nFarg);
 			if (nFarg && constMask == 0) {
 				sqlReleaseTempRange(pParse, r1, nFarg);
 			}
diff --git a/src/box/sql/func.c b/src/box/sql/func.c
index 29235ed62..5b42fa767 100644
--- a/src/box/sql/func.c
+++ b/src/box/sql/func.c
@@ -2877,3 +2877,26 @@ sql_func_result(struct Expr *expr)
 	}
 	return field_type_MAX;
 }
+
+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;
+	sqlVdbeAddOp4(vdbe, op, mask, r1, r2, (char *)func, P4_FUNC);
+	sqlVdbeChangeP5(vdbe, argc);
+	return 0;
+}
+
+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);
+	return 0;
+}
diff --git a/src/box/sql/select.c b/src/box/sql/select.c
index 2f8a7a031..87f2012f1 100644
--- a/src/box/sql/select.c
+++ b/src/box/sql/select.c
@@ -5572,10 +5572,8 @@ finalizeAggFunctions(Parse * pParse, AggInfo * pAggInfo)
 	for (i = 0, pF = pAggInfo->aFunc; i < pAggInfo->nFunc; i++, pF++) {
 		ExprList *pList = pF->pExpr->x.pList;
 		assert(!ExprHasProperty(pF->pExpr, EP_xIsSelect));
-		sqlVdbeAddOp2(v, OP_AggFinal, pF->iMem,
-				  pList ? pList->nExpr : 0);
-		struct func *func = sql_func_find(pF->pExpr);
-		sqlVdbeAppendP4(v, func, P4_FUNC);
+		sql_emit_func_finalize(v, pF->pExpr, pF->iMem,
+				       pList ? pList->nExpr : 0);
 	}
 }
 
@@ -5634,10 +5632,8 @@ updateAccumulator(Parse * pParse, AggInfo * pAggInfo)
 			sqlVdbeAddOp4(v, OP_CollSeq, regHit, 0, 0,
 					  (char *)coll, P4_COLLSEQ);
 		}
-		sqlVdbeAddOp3(v, OP_AggStep0, 0, regAgg, pF->iMem);
-		struct func *func = sql_func_find(pF->pExpr);
-		sqlVdbeAppendP4(v, func, P4_FUNC);
-		sqlVdbeChangeP5(v, (u8) nArg);
+		sql_emit_func_call(v, pF->pExpr, OP_AggStep0, 0, regAgg,
+				   pF->iMem, nArg);
 		sql_expr_type_cache_change(pParse, regAgg, nArg);
 		sqlReleaseTempRange(pParse, regAgg, nArg);
 		if (addrNext) {
diff --git a/src/box/sql/sqlInt.h b/src/box/sql/sqlInt.h
index 01701e271..5966f841f 100644
--- a/src/box/sql/sqlInt.h
+++ b/src/box/sql/sqlInt.h
@@ -4410,6 +4410,14 @@ sql_func_flags(uint8_t id);
 enum field_type
 sql_func_result(struct Expr *expr);
 
+int
+sql_emit_func_call(struct Vdbe *vdbe, struct Expr *expr, int op, int mask,
+		   int r1, int r2, uint8_t argc);
+
+int
+sql_emit_func_finalize(struct Vdbe *vdbe, struct Expr *expr, int reg,
+		       uint8_t argc);
+
 /**
  * Generate VDBE code to halt execution with correct error if
  * the object with specified key is already present (or doesn't
-- 
2.25.1



More information about the Tarantool-patches mailing list