box.schema.func.create() | Tarantool
Документация на русском языке
поддерживается сообществом


box.schema.func.create(func_name[, function_options])

Create a function. The created function can be used in different usage scenarios, for example, in field or tuple constraints or functional indexes.

Using the body option, you can make a function persistent. In this case, the function is «persistent» because its definition is stored in a snapshot (the system space) and can be recovered if the server restarts.




box.schema.user.grant() can be used to allow the specified user or role to execute the created function.

Example 1: a non-persistent Lua function

The example below shows how to create a non-persistent Lua function:

box.schema.func.create('calculate', {if_not_exists = false})
box.schema.func.create('calculate', {setuid = false})
box.schema.func.create('calculate', {language = 'LUA'})

Example 2: a persistent Lua function

The example below shows how to create a persistent Lua function, show its definition using box.func.{func-name}, and call this function using box.func.{func-name}:call([parameters]):

tarantool> lua_code = [[function(a, b) return a + b end]]
tarantool> box.schema.func.create('sum', {body = lua_code})

tarantool> box.func.sum
- is_sandboxed: false
  is_deterministic: false
  id: 2
  setuid: false
  body: function(a, b) return a + b end
  name: sum
  language: LUA

tarantool> box.func.sum:call({1, 2})
- 3

To call functions using, use net_box:call().

Example 3: a persistent SQL expression used in a tuple constraint

The code snippet below defines a function that checks a tuple’s data using the SQL expression:

box.schema.func.create('check_person', {
    language = 'SQL_EXPR',
    is_deterministic = true,
    body = [["age" > 21 AND "name" != 'Admin']]

Then, this function is used to create a tuple constraint:

local customers ='customers', { constraint = 'check_person' })
    { name = 'id', type = 'number' },
    { name = 'name', type = 'string' },
    { name = 'age', type = 'number' },
customers:create_index('primary', { parts = { 1 } })

On an attempt to insert a tuple that doesn’t meet the required criteria, an error is raised:

customers:insert { 2, "Bob", 18 }
-- error: Check constraint 'check_person' failed for a tuple

object function_options

A table containing options passed to the box.schema.func.create(func-name [, function_options]) function.


Specify whether there should be no error if the function already exists.

Type: boolean
Default: false

Make Tarantool treat the function’s caller as the function’s creator, with full privileges. Note that setuid works only over binary ports. setuid doesn’t work if you invoke a function using the admin console or inside a Lua script.

Type: boolean
Default: false

Specify the function language. The possible values are:

  • LUA: define a Lua function in the body attribute.

  • SQL_EXPR: define an SQL expression in the body attribute. An SQL expression can only be used as a field or tuple constraint.

  • C: import a C function using its name from a .so file. Learn how to call C code from Lua in the C tutorial.


    To reload a C module with all its functions without restarting the server, call box.schema.func.reload().

Type: string
Default: LUA

Whether the function should be executed in an isolated environment. This means that any operation that accesses the world outside the sandbox is forbidden or has no effect. Therefore, a sandboxed function can only use modules and functions that cannot affect isolation:

assert, assert, error, ipairs, math.*, next, pairs, pcall, print, select, string.*, table.*, tonumber, tostring, type, unpack, xpcall, utf8.*.

Also, a sandboxed function cannot refer to global variables – they are treated as local variables because the sandbox is established with setfenv. So, a sandboxed function is stateless and deterministic.

Type: boolean
Default: false

Specify whether a function should be deterministic.

Type: boolean
Default: false

If true is set in the function definition for a functional index, the function returns multiple keys. For details, see the example.

Type: boolean
Default: false

Specify a function body. You can set a function’s language using the language attribute.

The code snippet below defines a constraint function that checks a tuple’s data using a Lua function:

box.schema.func.create('check_person', {
    language = 'LUA',
    is_deterministic = true,
    body = 'function(t, c) return (t.age >= 0 and #( > 3) end'

In the following example, an SQL expression is used to check a tuple’s data:

box.schema.func.create('check_person', {
    language = 'SQL_EXPR',
    is_deterministic = true,
    body = [["age" > 21 AND "name" != 'Admin']]

Example: A persistent SQL expression used in a tuple constraint

Type: string
Default: nil

Since: 2.10.0

If set to true for a Lua function and the function is called via (conn:call()) or by box.func.<func-name>:call(), the function arguments are passed being wrapped in a MsgPack object:

local msgpack = require('msgpack')
box.schema.func.create('my_func', {takes_raw_args = true})
local my_func = function(mp)
    local args = mp:decode() -- array of arguments

If a function forwards most of its arguments to another Tarantool instance or writes them to a database, the usage of this option can improve performance because it skips the MsgPack data decoding in Lua.

Type: boolean
Default: false

Specify the languages that can call the function.

Example: exports = {'LUA', 'SQL'}

See also: Calling Lua routines from SQL

Type: table
Default: {'LUA'}

Specify the Lua type names for each parameter of the function.

Example: param_list = {'number', 'number'}

See also: Calling Lua routines from SQL

Type: table

Specify the Lua type name for a function’s return value.

Example: returns = 'number'

See also: Calling Lua routines from SQL

Type: string
Нашли ответ на свой вопрос?
Обратная связь