Tarantool development patches archive
 help / color / mirror / Atom feed
From: Kirill Shcherbatov <kshcherbatov@tarantool.org>
To: tarantool-patches@freelists.org, korablev@tarantool.org
Cc: Kirill Shcherbatov <kshcherbatov@tarantool.org>
Subject: [tarantool-patches] [PATCH v2 3/3] sql: use name instead of function pointer for UDF
Date: Thu, 12 Sep 2019 11:06:43 +0300	[thread overview]
Message-ID: <68b5bf44a11ea134d4a3a52f2086aa9ea640e729.1568275504.git.kshcherbatov@tarantool.org> (raw)
In-Reply-To: <cover.1568275504.git.kshcherbatov@tarantool.org>

This patch changes OP_Function parameters convention: now a
function's name is passed instead of pointer to the function
object. This allows to normally handle the situation, when UDF
had been deleted to the moment of the VDBE code execution.
In particular case this may happen with CK constraints that
refer to a persistent function.
---
 src/box/sql/expr.c       | 17 ++++++++++++-----
 src/box/sql/vdbe.c       | 17 +++++++++++------
 src/box/sql/vdbe.h       |  1 +
 test/sql/checks.result   | 10 +++++++---
 test/sql/checks.test.lua |  3 ++-
 5 files changed, 33 insertions(+), 15 deletions(-)

diff --git a/src/box/sql/expr.c b/src/box/sql/expr.c
index 6d5ad2a27..04c9393be 100644
--- a/src/box/sql/expr.c
+++ b/src/box/sql/expr.c
@@ -4136,11 +4136,18 @@ sqlExprCodeTarget(Parse * pParse, Expr * pExpr, int target)
 				sqlVdbeAddOp4(v, OP_CollSeq, 0, 0, 0,
 						  (char *)coll, P4_COLLSEQ);
 			}
-			int op = func->def->language ==
-				 FUNC_LANGUAGE_SQL_BUILTIN ?
-				 OP_BuiltinFunction0 : OP_Function;
-			sqlVdbeAddOp4(v, op, constMask, r1, target,
-				      (char *)func, P4_FUNC);
+			if (func->def->language == FUNC_LANGUAGE_SQL_BUILTIN) {
+				sqlVdbeAddOp4(v, OP_BuiltinFunction0, constMask,
+					      r1, target, (char *)func,
+					      P4_FUNC);
+			} else {
+				sqlVdbeAddOp4(v, OP_Function,
+					      func->def->name_len, r1, target,
+					      sqlDbStrNDup(sql_get(),
+							   func->def->name,
+							   func->def->name_len),
+					      P4_DYNAMIC);
+			}
 			sqlVdbeChangeP5(v, (u8) nFarg);
 			if (nFarg && constMask == 0) {
 				sqlReleaseTempRange(pParse, r1, nFarg);
diff --git a/src/box/sql/vdbe.c b/src/box/sql/vdbe.c
index 02e16da19..4c6245348 100644
--- a/src/box/sql/vdbe.c
+++ b/src/box/sql/vdbe.c
@@ -1795,16 +1795,21 @@ case OP_BuiltinFunction: {
 	break;
 }
 
-/* Opcode: Function * P2 P3 P4 P5
+/* Opcode: Function P1 P2 P3 P4 P5
  * Synopsis: r[P3]=func(r[P2@P5])
  *
- * Invoke a user function (P4 is a pointer to a function object
- * that defines the function) with P5 arguments taken from
- * register P2 and successors. The result of the function is
- * stored in register P3.
+ * Invoke a user function (P4 is a name of the function while P1
+ * is a function name length) with P5 arguments taken from register P2 and
+ * successors. The result of the function is stored in
+ * register P3.
  */
 case OP_Function: {
-	struct func *func = pOp->p4.func;
+	assert(pOp->p4type == P4_DYNAMIC);
+	struct func *func = func_by_name(pOp->p4.z, pOp->p1);
+	if (unlikely(func == NULL)) {
+		diag_set(ClientError, ER_NO_SUCH_FUNCTION, pOp->p4.z);
+		goto abort_due_to_error;
+	}
 	int argc = pOp->p5;
 	struct Mem *argv = &aMem[pOp->p2];
 	struct port args, ret;
diff --git a/src/box/sql/vdbe.h b/src/box/sql/vdbe.h
index 29ff99867..e57d7f979 100644
--- a/src/box/sql/vdbe.h
+++ b/src/box/sql/vdbe.h
@@ -128,6 +128,7 @@ struct SubProgram {
 #define P4_COLLSEQ  (-3)	/* P4 is a pointer to a CollSeq structure */
 /** P4 is a pointer to a func structure. */
 #define P4_FUNC     (-4)
+/** P4 is a function identifier. */
 #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/test/sql/checks.result b/test/sql/checks.result
index 7939d46df..02951b3cf 100644
--- a/test/sql/checks.result
+++ b/test/sql/checks.result
@@ -867,12 +867,16 @@ box.space.T6:insert({11})
 ---
 - error: 'Check constraint failed ''ck_unnamed_T6_1'': myfunc(a)'
 ...
+box.func.MYFUNC:drop()
+---
+...
+box.space.T6:insert({11})
+---
+- error: Function 'MYFUNC' does not exist
+...
 box.space.T6:drop()
 ---
 ...
-box.func.MYFUNC:drop()
----
-...
 test_run:cmd("clear filter")
 ---
 - true
diff --git a/test/sql/checks.test.lua b/test/sql/checks.test.lua
index 051c9ae38..d64f3305a 100644
--- a/test/sql/checks.test.lua
+++ b/test/sql/checks.test.lua
@@ -291,7 +291,8 @@ box.space.T6:insert({11})
 test_run:cmd("restart server default")
 box.space.T6:insert({11})
 
+box.func.MYFUNC:drop()
+box.space.T6:insert({11})
 box.space.T6:drop()
-box.func.MYFUNC:drop()
 
 test_run:cmd("clear filter")
-- 
2.23.0

  parent reply	other threads:[~2019-09-12  8:06 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-09-12  8:06 [tarantool-patches] [PATCH v2 0/3] sql: fixes for ck constraints involving a function Kirill Shcherbatov
2019-09-12  8:06 ` [tarantool-patches] [PATCH v2 1/3] box: an ability to disable CK constraints Kirill Shcherbatov
2019-09-12 14:00   ` [tarantool-patches] " Nikita Pettik
2019-09-12 14:15     ` Kirill Shcherbatov
2019-09-12  8:06 ` [tarantool-patches] [PATCH v2 2/3] sql: disallow ck using non-persistent function Kirill Shcherbatov
2019-09-12 11:54   ` [tarantool-patches] " Nikita Pettik
2019-09-12  8:06 ` Kirill Shcherbatov [this message]
2019-09-12 12:13   ` [tarantool-patches] Re: [PATCH v2 3/3] sql: use name instead of function pointer for UDF Nikita Pettik

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=68b5bf44a11ea134d4a3a52f2086aa9ea640e729.1568275504.git.kshcherbatov@tarantool.org \
    --to=kshcherbatov@tarantool.org \
    --cc=korablev@tarantool.org \
    --cc=tarantool-patches@freelists.org \
    --subject='Re: [tarantool-patches] [PATCH v2 3/3] sql: use name instead of function pointer for UDF' \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox