From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from localhost (localhost [127.0.0.1]) by turing.freelists.org (Avenir Technologies Mail Multiplex) with ESMTP id 7404D23112 for ; Thu, 12 Sep 2019 04:06:49 -0400 (EDT) Received: from turing.freelists.org ([127.0.0.1]) by localhost (turing.freelists.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id kSMn9rNRpAxO for ; Thu, 12 Sep 2019 04:06:49 -0400 (EDT) Received: from smtpng1.m.smailru.net (smtpng1.m.smailru.net [94.100.181.251]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by turing.freelists.org (Avenir Technologies Mail Multiplex) with ESMTPS id B6936230F6 for ; Thu, 12 Sep 2019 04:06:48 -0400 (EDT) From: Kirill Shcherbatov 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 Message-Id: <68b5bf44a11ea134d4a3a52f2086aa9ea640e729.1568275504.git.kshcherbatov@tarantool.org> In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: tarantool-patches-bounce@freelists.org Errors-to: tarantool-patches-bounce@freelists.org Reply-To: tarantool-patches@freelists.org List-Help: List-Unsubscribe: List-software: Ecartis version 1.0.0 List-Id: tarantool-patches List-Subscribe: List-Owner: List-post: List-Archive: To: tarantool-patches@freelists.org, korablev@tarantool.org Cc: Kirill Shcherbatov 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