[Tarantool-patches] [PATCH v1 1/1] sql: remove SQL built-in functions from _func

imeevma at tarantool.org imeevma at tarantool.org
Fri Jul 30 01:48:23 MSK 2021


This patch removes SQL built-in functions from _func. These functions
could be called directly from Lua, however all they did was returnd an
error. After this patch, no SQL built-in functions can be called
directly from LUA.

Closes #6106
---
https://github.com/tarantool/tarantool/issues/6106
https://github.com/tarantool/tarantool/tree/imeevma/gh-6106-remove-sql-builtins-from-_func

 ...gh-6106-remove-sql-built-ins-from-_func.md |   3 +
 src/box/alter.cc                              |   7 --
 src/box/bootstrap.snap                        | Bin 6016 -> 4884 bytes
 src/box/box.cc                                |   1 +
 src/box/lua/upgrade.lua                       |  16 +--
 src/box/sql.c                                 |   1 +
 src/box/sql.h                                 |   9 ++
 src/box/sql/analyze.c                         |   6 +-
 src/box/sql/expr.c                            |  22 ++--
 src/box/sql/func.c                            | 107 ++++++++++++++++--
 src/box/sql/resolve.c                         |   2 +-
 src/box/sql/sqlInt.h                          |  11 +-
 src/box/sql/vdbemem.c                         |   4 +-
 test/box-py/bootstrap.result                  |  66 -----------
 test/box/access_bin.result                    |   4 +-
 test/box/access_bin.test.lua                  |   4 +-
 test/box/access_sysview.result                |   8 +-
 test/box/function1.result                     |  32 +-----
 test/box/function1.test.lua                   |  13 +--
 test/wal_off/func_max.result                  |   8 +-
 20 files changed, 162 insertions(+), 162 deletions(-)
 create mode 100644 changelogs/unreleased/gh-6106-remove-sql-built-ins-from-_func.md

diff --git a/changelogs/unreleased/gh-6106-remove-sql-built-ins-from-_func.md b/changelogs/unreleased/gh-6106-remove-sql-built-ins-from-_func.md
new file mode 100644
index 000000000..9708bbf02
--- /dev/null
+++ b/changelogs/unreleased/gh-6106-remove-sql-built-ins-from-_func.md
@@ -0,0 +1,3 @@
+## feature/sql
+
+* SQL built-in functions were removed from \_func system space (gh-6106).
diff --git a/src/box/alter.cc b/src/box/alter.cc
index 390199298..935790df4 100644
--- a/src/box/alter.cc
+++ b/src/box/alter.cc
@@ -3548,13 +3548,6 @@ on_replace_dd_func(struct trigger * /* trigger */, void *event)
 				  "function has references");
 			return -1;
 		}
-		/* Can't' drop a builtin function. */
-		if (old_func->def->language == FUNC_LANGUAGE_SQL_BUILTIN) {
-			diag_set(ClientError, ER_DROP_FUNCTION,
-				  (unsigned) old_func->def->uid,
-				  "function is SQL built-in");
-			return -1;
-		}
 		struct trigger *on_commit =
 			txn_alter_trigger_new(on_drop_func_commit, old_func);
 		struct trigger *on_rollback =
diff --git a/src/box/bootstrap.snap b/src/box/bootstrap.snap
index 57374decc0f9de140772d9809a227e3ba4ce61eb..a5604033ea528242af6103dc11a02350df600a65 100644

diff --git a/src/box/box.cc b/src/box/box.cc
index 0ff7ee468..a7eda4214 100644
--- a/src/box/box.cc
+++ b/src/box/box.cc
@@ -2914,6 +2914,7 @@ box_free(void)
 		gc_free();
 		engine_shutdown();
 		wal_free();
+		sql_built_in_functions_cache_free();
 	}
 }
 
diff --git a/src/box/lua/upgrade.lua b/src/box/lua/upgrade.lua
index 97afc0b4d..d0ca3db97 100644
--- a/src/box/lua/upgrade.lua
+++ b/src/box/lua/upgrade.lua
@@ -1003,19 +1003,19 @@ end
 --------------------------------------------------------------------------------
 -- Tarantool 2.9.1
 --------------------------------------------------------------------------------
-local function sql_builtin_function_uuid()
+local function remove_sql_builtin_functions_from_func()
     local _func = box.space._func
     local _priv = box.space._priv
-    local datetime = os.date("%Y-%m-%d %H:%M:%S")
-    local t = _func:auto_increment({ADMIN, 'UUID', 1, 'SQL_BUILTIN', '',
-                                    'function', {}, 'any', 'none', 'none',
-                                    false, false, true, {}, setmap({}), '',
-                                    datetime, datetime})
-    _priv:replace{ADMIN, PUBLIC, 'function', t.id, box.priv.X}
+    for _, v in _func:pairs() do
+        if (v.language == "SQL_BUILTIN") then
+            _priv:delete({2, 'function', v.id})
+            _func:delete({v.id})
+        end
+    end
 end
 
 local function upgrade_to_2_9_1()
-    sql_builtin_function_uuid()
+    remove_sql_builtin_functions_from_func()
 end
 
 --------------------------------------------------------------------------------
diff --git a/src/box/sql.c b/src/box/sql.c
index 433264abe..f18dfa063 100644
--- a/src/box/sql.c
+++ b/src/box/sql.c
@@ -75,6 +75,7 @@ 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 4c364306c..85e15946d 100644
--- a/src/box/sql.h
+++ b/src/box/sql.h
@@ -56,6 +56,15 @@ sql_init(void);
 struct sql *
 sql_get(void);
 
+/** Initialize global cache for built-in functions. */
+int
+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/analyze.c b/src/box/sql/analyze.c
index b87f69512..9fb97dffe 100644
--- a/src/box/sql/analyze.c
+++ b/src/box/sql/analyze.c
@@ -719,7 +719,7 @@ callStatGet(Vdbe * v, int regStat4, int iParam, int regOut)
 {
 	assert(regOut != regStat4 && regOut != regStat4 + 1);
 	sqlVdbeAddOp2(v, OP_Integer, iParam, regStat4 + 1);
-	struct func *func = sql_func_by_signature("_sql_stat_get", 2);
+	struct func *func = sql_func_by_name("_sql_stat_get", 2);
 	assert(func != NULL);
 	sqlVdbeAddOp4(v, OP_BuiltinFunction0, 0, regStat4, regOut,
 		      (char *)func, P4_FUNC);
@@ -859,7 +859,7 @@ vdbe_emit_analyze_space(struct Parse *parse, struct space *space)
 		sqlVdbeAddOp2(v, OP_Integer, part_count, stat4_reg + 1);
 		sqlVdbeAddOp2(v, OP_Integer, part_count, stat4_reg + 2);
 		struct func *init_func =
-			sql_func_by_signature("_sql_stat_init", 3);
+			sql_func_by_name("_sql_stat_init", 3);
 		assert(init_func != NULL);
 		sqlVdbeAddOp4(v, OP_BuiltinFunction0, 0, stat4_reg + 1,
 			      stat4_reg, (char *)init_func, P4_FUNC);
@@ -960,7 +960,7 @@ vdbe_emit_analyze_space(struct Parse *parse, struct space *space)
 				  pk_part_count, key_reg);
 		assert(chng_reg == (stat4_reg + 1));
 		struct func *push_func =
-			sql_func_by_signature("_sql_stat_push", 3);
+			sql_func_by_name("_sql_stat_push", 3);
 		assert(push_func != NULL);
 		sqlVdbeAddOp4(v, OP_BuiltinFunction0, 1, stat4_reg, tmp_reg,
 			      (char *)push_func, P4_FUNC);
diff --git a/src/box/sql/expr.c b/src/box/sql/expr.c
index 3772596d6..7c1616a3a 100644
--- a/src/box/sql/expr.c
+++ b/src/box/sql/expr.c
@@ -326,11 +326,13 @@ sql_expr_coll(Parse *parse, Expr *p, bool *is_explicit_coll, uint32_t *coll_id,
 			break;
 		}
 		if (op == TK_FUNCTION) {
-			uint32_t arg_count = p->x.pList == NULL ? 0 :
-					     p->x.pList->nExpr;
+			int arg_count = p->x.pList == NULL ? 0 :
+					p->x.pList->nExpr;
 			struct func *func =
-				sql_func_by_signature(p->u.zToken, arg_count);
-			if (func == NULL)
+				sql_func_by_name(p->u.zToken);
+			if (func == NULL || !func->def->exports.sql ||
+			    (func->def->param_count != -1 &&
+			     func->def->param_count != arg_count))
 				break;
 			if (sql_func_flag_is_set(func, SQL_FUNC_DERIVEDCOLL) &&
 			    arg_count > 0) {
@@ -3979,8 +3981,10 @@ sqlExprCodeTarget(Parse * pParse, Expr * pExpr, int target)
 			nFarg = pFarg ? pFarg->nExpr : 0;
 			assert(!ExprHasProperty(pExpr, EP_IntValue));
 			zId = pExpr->u.zToken;
-			struct func *func = sql_func_by_signature(zId, nFarg);
-			if (func == NULL) {
+			struct func *func = sql_func_by_name(zId);
+			if (func == NULL || !func->def->exports.sql ||
+			    (func->def->param_count != -1 &&
+			     func->def->param_count != nFarg)) {
 				diag_set(ClientError, ER_NO_SUCH_FUNCTION,
 					 zId);
 				pParse->is_aborted = true;
@@ -5449,12 +5453,8 @@ analyzeAggregate(Walker * pWalker, Expr * pExpr)
 						       (pExpr, EP_IntValue));
 						const char *name =
 							pExpr->u.zToken;
-						uint32_t argc =
-							pExpr->x.pList != NULL ?
-							pExpr->x.pList->nExpr : 0;
 						pItem->func =
-							sql_func_by_signature(
-								name, argc);
+							sql_func_by_name(name);
 						assert(pItem->func != NULL);
 						assert(pItem->func->def->
 						       language ==
diff --git a/src/box/sql/func.c b/src/box/sql/func.c
index 6ca852dec..b05038e2e 100644
--- a/src/box/sql/func.c
+++ b/src/box/sql/func.c
@@ -47,6 +47,37 @@
 #include <unicode/ucol.h>
 #include "box/coll_id_cache.h"
 #include "box/schema.h"
+#include "core/assoc.h"
+#include "box/user.h"
+
+static struct mh_strnptr_t *built_in_functions = NULL;
+
+static struct func *
+get_built_in_function(const char *name)
+{
+	uint32_t len = strlen(name);
+	mh_int_t func = mh_strnptr_find_inp(built_in_functions, name, len);
+	if (func == mh_end(built_in_functions))
+		return NULL;
+	return (struct func *) mh_strnptr_node(built_in_functions, func)->val;
+}
+
+static int
+built_in_functions_cache_insert(struct func *func)
+{
+	const char *name = func->def->name;
+	uint32_t len = strlen(name);
+	assert(get_built_in_function(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)) {
+		diag_set(OutOfMemory, sizeof(strnode), "malloc", "strnode");
+		return -1;
+	}
+	return 0;
+}
 
 static const unsigned char *
 mem_as_ustr(struct Mem *mem)
@@ -1934,22 +1965,19 @@ sql_is_like_func(struct Expr *expr)
 	    expr->x.pList->nExpr != 2)
 		return 0;
 	assert(!ExprHasProperty(expr, EP_xIsSelect));
-	struct func *func = sql_func_by_signature(expr->u.zToken, 2);
+	struct func *func = sql_func_by_name(expr->u.zToken);
 	if (func == NULL || !sql_func_flag_is_set(func, SQL_FUNC_LIKE))
 		return 0;
 	return 1;
 }
 
 struct func *
-sql_func_by_signature(const char *name, int argc)
+sql_func_by_name(const char *name)
 {
-	struct func *base = func_by_name(name, strlen(name));
-	if (base == NULL || !base->def->exports.sql)
-		return NULL;
-
-	if (base->def->param_count != -1 && base->def->param_count != argc)
-		return NULL;
-	return base;
+	struct func *base = get_built_in_function(name);
+	if (base != NULL)
+		return base;
+	return func_by_name(name, strlen(name));
 }
 
 static int
@@ -2657,6 +2685,67 @@ static struct {
 
 static struct func_vtab func_sql_builtin_vtab;
 
+int
+sql_built_in_functions_cache_init(void)
+{
+	built_in_functions = mh_strnptr_new();
+	for (uint32_t i = 0; i < nelem(sql_builtins); ++i) {
+		const char *name = sql_builtins[i].name;
+		uint32_t len = strlen(name);
+		uint32_t size = sizeof(struct func_def) + len + 1;
+		struct func_def *def = malloc(size);
+		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) {
+			diag_set(OutOfMemory, sizeof(*func), "malloc", "func");
+			return -1;
+		}
+
+		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;
+		if (built_in_functions_cache_insert(&func->base) != 0)
+			return -1;
+	}
+	return 0;
+}
+
+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;
+		mh_strnptr_del(built_in_functions, k, NULL);
+	}
+	mh_strnptr_delete(built_in_functions);
+}
+
 struct func *
 func_sql_builtin_new(struct func_def *def)
 {
diff --git a/src/box/sql/resolve.c b/src/box/sql/resolve.c
index 11b6139e3..2df2fa89a 100644
--- a/src/box/sql/resolve.c
+++ b/src/box/sql/resolve.c
@@ -598,7 +598,7 @@ resolveExprStep(Walker * pWalker, Expr * pExpr)
 			assert(!ExprHasProperty(pExpr, EP_xIsSelect));
 			zId = pExpr->u.zToken;
 			nId = sqlStrlen30(zId);
-			struct func *func = func_by_name(zId, nId);
+			struct func *func = sql_func_by_name(zId);
 			if (func == NULL) {
 				diag_set(ClientError, ER_NO_SUCH_FUNCTION, zId);
 				pParse->is_aborted = true;
diff --git a/src/box/sql/sqlInt.h b/src/box/sql/sqlInt.h
index 115c52f96..3b38bde2f 100644
--- a/src/box/sql/sqlInt.h
+++ b/src/box/sql/sqlInt.h
@@ -4361,16 +4361,13 @@ sql_func_flag_is_set(struct func *func, uint16_t flag)
 }
 
 /**
- * A SQL method to find a function in a hash by its name and
- * count of arguments. Only functions that have 'SQL' engine
- * export field set true and have exactly the same signature
- * are returned.
+ * A SQL method to find a function in SQL built-in functions hash or in global
+ * user-defined functions hash by its name.
  *
- * Returns not NULL function pointer when a valid and exported
- * to SQL engine function is found and NULL otherwise.
+ * Return pointer to function if one was found, NULL otherwise.
  */
 struct func *
-sql_func_by_signature(const char *name, int argc);
+sql_func_by_name(const char *name);
 
 /**
  * Generate VDBE code to halt execution with correct error if
diff --git a/src/box/sql/vdbemem.c b/src/box/sql/vdbemem.c
index 2c5099616..d4e4095fe 100644
--- a/src/box/sql/vdbemem.c
+++ b/src/box/sql/vdbemem.c
@@ -148,9 +148,9 @@ valueFromFunction(sql * db,	/* The database connection */
 	pList = p->x.pList;
 	if (pList)
 		nVal = pList->nExpr;
-	struct func *func = sql_func_by_signature(p->u.zToken, nVal);
+	struct func *func = sql_func_by_name(p->u.zToken);
 	if (func == NULL || func->def->language != FUNC_LANGUAGE_SQL_BUILTIN ||
-	    !func->def->is_deterministic ||
+	    !func->def->is_deterministic || func->def->param_count != nVal ||
 	    sql_func_flag_is_set(func, SQL_FUNC_NEEDCOLL))
 		return 0;
 
diff --git a/test/box-py/bootstrap.result b/test/box-py/bootstrap.result
index b2328487c..cea440c64 100644
--- a/test/box-py/bootstrap.result
+++ b/test/box-py/bootstrap.result
@@ -176,73 +176,7 @@ box.space._priv:select{}
   - [1, 0, 'universe', 0, 24]
   - [1, 1, 'universe', 0, 4294967295]
   - [1, 2, 'function', 1, 4]
-  - [1, 2, 'function', 2, 4]
-  - [1, 2, 'function', 3, 4]
-  - [1, 2, 'function', 4, 4]
-  - [1, 2, 'function', 5, 4]
-  - [1, 2, 'function', 6, 4]
-  - [1, 2, 'function', 7, 4]
-  - [1, 2, 'function', 8, 4]
-  - [1, 2, 'function', 9, 4]
-  - [1, 2, 'function', 10, 4]
-  - [1, 2, 'function', 11, 4]
-  - [1, 2, 'function', 12, 4]
-  - [1, 2, 'function', 13, 4]
-  - [1, 2, 'function', 14, 4]
-  - [1, 2, 'function', 15, 4]
-  - [1, 2, 'function', 16, 4]
-  - [1, 2, 'function', 17, 4]
-  - [1, 2, 'function', 18, 4]
-  - [1, 2, 'function', 19, 4]
-  - [1, 2, 'function', 20, 4]
-  - [1, 2, 'function', 21, 4]
-  - [1, 2, 'function', 22, 4]
-  - [1, 2, 'function', 23, 4]
-  - [1, 2, 'function', 24, 4]
-  - [1, 2, 'function', 25, 4]
-  - [1, 2, 'function', 26, 4]
-  - [1, 2, 'function', 27, 4]
-  - [1, 2, 'function', 28, 4]
-  - [1, 2, 'function', 29, 4]
-  - [1, 2, 'function', 30, 4]
-  - [1, 2, 'function', 31, 4]
-  - [1, 2, 'function', 32, 4]
-  - [1, 2, 'function', 33, 4]
-  - [1, 2, 'function', 34, 4]
-  - [1, 2, 'function', 35, 4]
-  - [1, 2, 'function', 36, 4]
-  - [1, 2, 'function', 37, 4]
-  - [1, 2, 'function', 38, 4]
-  - [1, 2, 'function', 39, 4]
-  - [1, 2, 'function', 40, 4]
-  - [1, 2, 'function', 41, 4]
-  - [1, 2, 'function', 42, 4]
-  - [1, 2, 'function', 43, 4]
-  - [1, 2, 'function', 44, 4]
-  - [1, 2, 'function', 45, 4]
-  - [1, 2, 'function', 46, 4]
-  - [1, 2, 'function', 47, 4]
-  - [1, 2, 'function', 48, 4]
-  - [1, 2, 'function', 49, 4]
-  - [1, 2, 'function', 50, 4]
-  - [1, 2, 'function', 51, 4]
-  - [1, 2, 'function', 52, 4]
-  - [1, 2, 'function', 53, 4]
-  - [1, 2, 'function', 54, 4]
-  - [1, 2, 'function', 55, 4]
-  - [1, 2, 'function', 56, 4]
-  - [1, 2, 'function', 57, 4]
-  - [1, 2, 'function', 58, 4]
-  - [1, 2, 'function', 59, 4]
-  - [1, 2, 'function', 60, 4]
-  - [1, 2, 'function', 61, 4]
-  - [1, 2, 'function', 62, 4]
-  - [1, 2, 'function', 63, 4]
-  - [1, 2, 'function', 64, 4]
   - [1, 2, 'function', 65, 4]
-  - [1, 2, 'function', 66, 4]
-  - [1, 2, 'function', 67, 4]
-  - [1, 2, 'function', 68, 4]
   - [1, 2, 'space', 276, 2]
   - [1, 2, 'space', 277, 1]
   - [1, 2, 'space', 281, 1]
diff --git a/test/box/access_bin.result b/test/box/access_bin.result
index aeb8b3bd8..7c720192f 100644
--- a/test/box/access_bin.result
+++ b/test/box/access_bin.result
@@ -295,10 +295,10 @@ test:drop()
 box.schema.user.grant('guest', 'execute', 'universe')
 ---
 ...
-function f1() return box.space._func:get(1)[4] end
+function f1() return box.space._func.index[2]:get({'f1'})[4] end
 ---
 ...
-function f2() return box.space._func:get(69)[4] end
+function f2() return box.space._func.index[2]:get({'f1'})[4] end
 ---
 ...
 box.schema.func.create('f1')
diff --git a/test/box/access_bin.test.lua b/test/box/access_bin.test.lua
index 954266858..e82ec759c 100644
--- a/test/box/access_bin.test.lua
+++ b/test/box/access_bin.test.lua
@@ -111,8 +111,8 @@ test:drop()
 --
 -- notice that guest can execute stuff, but can't read space _func
 box.schema.user.grant('guest', 'execute', 'universe')
-function f1() return box.space._func:get(1)[4] end
-function f2() return box.space._func:get(69)[4] end
+function f1() return box.space._func.index[2]:get({'f1'})[4] end
+function f2() return box.space._func.index[2]:get({'f1'})[4] end
 box.schema.func.create('f1')
 box.schema.func.create('f2',{setuid=true})
 c = net.connect(box.cfg.listen)
diff --git a/test/box/access_sysview.result b/test/box/access_sysview.result
index d7a7b7534..071fc8de2 100644
--- a/test/box/access_sysview.result
+++ b/test/box/access_sysview.result
@@ -258,11 +258,11 @@ box.session.su('guest')
 ...
 #box.space._vpriv:select{}
 ---
-- 83
+- 17
 ...
 #box.space._vfunc:select{}
 ---
-- 68
+- 2
 ...
 #box.space._vcollation:select{}
 ---
@@ -290,11 +290,11 @@ box.session.su('guest')
 ...
 #box.space._vpriv:select{}
 ---
-- 83
+- 17
 ...
 #box.space._vfunc:select{}
 ---
-- 68
+- 2
 ...
 #box.space._vsequence:select{}
 ---
diff --git a/test/box/function1.result b/test/box/function1.result
index 0166c828f..a49a133f7 100644
--- a/test/box/function1.result
+++ b/test/box/function1.result
@@ -97,7 +97,7 @@ box.func["function1.args"]
   exports:
     lua: true
     sql: false
-  id: 69
+  id: 66
   setuid: false
   is_multikey: false
   is_deterministic: false
@@ -593,7 +593,7 @@ func
   exports:
     lua: true
     sql: false
-  id: 69
+  id: 66
   setuid: false
   is_multikey: false
   is_deterministic: false
@@ -665,7 +665,7 @@ func
   exports:
     lua: true
     sql: false
-  id: 69
+  id: 66
   setuid: false
   is_multikey: false
   is_deterministic: false
@@ -1032,7 +1032,7 @@ box.func.test ~= nil
 box.func.test:drop()
 ---
 ...
--- Check SQL builtins
+-- Make sure there is no SQL built-in functions in _func.
 test_run:cmd("setopt delimiter ';'")
 ---
 - true
@@ -1048,7 +1048,7 @@ sql_builtin_list = {
 	"RANDOMBLOB", "NULLIF", "ZEROBLOB", "MIN", "MAX", "COALESCE", "EVERY",
 	"EXISTS", "EXTRACT", "SOME", "GREATER", "LESSER", "SOUNDEX",
 	"LIKELIHOOD", "LIKELY", "UNLIKELY", "_sql_stat_get", "_sql_stat_push",
-	"_sql_stat_init", "GREATEST", "LEAST"
+	"_sql_stat_init", "GREATEST", "LEAST", "UUID"
 }
 test_run:cmd("setopt delimiter ''");
 ---
@@ -1056,7 +1056,7 @@ test_run:cmd("setopt delimiter ''");
 ok = true
 ---
 ...
-for _, v in pairs(sql_builtin_list) do ok = ok and (box.space._func.index.name:get(v) ~= nil) end
+for _, v in pairs(sql_builtin_list) do ok = ok and (box.space._func.index.name:get(v) == nil) end
 ---
 ...
 ok == true
@@ -1067,26 +1067,6 @@ box.func.LUA:call({"return 1 + 1"})
 ---
 - 2
 ...
-box.schema.user.grant('guest', 'execute', 'function', 'SUM')
----
-...
-c = net.connect(box.cfg.listen)
----
-...
-c:call("SUM")
----
-- error: sql builtin function does not support Lua frontend
-...
-c:close()
----
-...
-box.schema.user.revoke('guest', 'execute', 'function', 'SUM')
----
-...
-box.schema.func.drop("SUM")
----
-- error: 'Can''t drop function 1: function is SQL built-in'
-...
 -- Introduce function options
 box.schema.func.create('test', {body = "function(tuple) return tuple end", is_deterministic = true, opts = {is_multikey = true}})
 ---
diff --git a/test/box/function1.test.lua b/test/box/function1.test.lua
index ab7b586a0..4fdd48520 100644
--- a/test/box/function1.test.lua
+++ b/test/box/function1.test.lua
@@ -363,7 +363,7 @@ f == nil
 box.func.test ~= nil
 box.func.test:drop()
 
--- Check SQL builtins
+-- Make sure there is no SQL built-in functions in _func.
 test_run:cmd("setopt delimiter ';'")
 sql_builtin_list = {
 	"TRIM", "TYPEOF", "PRINTF", "UNICODE", "CHAR", "HEX", "VERSION",
@@ -376,22 +376,15 @@ sql_builtin_list = {
 	"RANDOMBLOB", "NULLIF", "ZEROBLOB", "MIN", "MAX", "COALESCE", "EVERY",
 	"EXISTS", "EXTRACT", "SOME", "GREATER", "LESSER", "SOUNDEX",
 	"LIKELIHOOD", "LIKELY", "UNLIKELY", "_sql_stat_get", "_sql_stat_push",
-	"_sql_stat_init", "GREATEST", "LEAST"
+	"_sql_stat_init", "GREATEST", "LEAST", "UUID"
 }
 test_run:cmd("setopt delimiter ''");
 ok = true
-for _, v in pairs(sql_builtin_list) do ok = ok and (box.space._func.index.name:get(v) ~= nil) end
+for _, v in pairs(sql_builtin_list) do ok = ok and (box.space._func.index.name:get(v) == nil) end
 ok == true
 
 box.func.LUA:call({"return 1 + 1"})
 
-box.schema.user.grant('guest', 'execute', 'function', 'SUM')
-c = net.connect(box.cfg.listen)
-c:call("SUM")
-c:close()
-box.schema.user.revoke('guest', 'execute', 'function', 'SUM')
-box.schema.func.drop("SUM")
-
 -- Introduce function options
 box.schema.func.create('test', {body = "function(tuple) return tuple end", is_deterministic = true, opts = {is_multikey = true}})
 box.func['test'].is_multikey == true
diff --git a/test/wal_off/func_max.result b/test/wal_off/func_max.result
index cc5bcc141..a3ab5b431 100644
--- a/test/wal_off/func_max.result
+++ b/test/wal_off/func_max.result
@@ -42,11 +42,11 @@ test_run:cmd("setopt delimiter ''");
 ...
 func_limit()
 ---
-- error: 'Failed to create function ''func31933'': function id is too big'
+- error: 'Failed to create function ''func31936'': function id is too big'
 ...
 drop_limit_func()
 ---
-- error: Function 'func31933' does not exist
+- error: Function 'func31936' does not exist
 ...
 box.schema.user.create('testuser')
 ---
@@ -62,11 +62,11 @@ session.su('testuser')
 ...
 func_limit()
 ---
-- error: 'Failed to create function ''func31933'': function id is too big'
+- error: 'Failed to create function ''func31936'': function id is too big'
 ...
 drop_limit_func()
 ---
-- error: Function 'func31933' does not exist
+- error: Function 'func31936' does not exist
 ...
 session.su('admin')
 ---
-- 
2.25.1



More information about the Tarantool-patches mailing list