box.schema.func.create() | Tarantool



box.schema.func.create(func-name[, {options-without-body}])

Create a function tuple. without including the body option. (For functions created with the body option, see box.schema.func.create(func-name [, {options-with-body}]).

This is called a “not persistent” function because functions without bodies are not persistent. This does not create the function itself – that is done with Lua – but if it is necessary to grant privileges for a function, box.schema.func.create must be done first. For explanation of how Tarantool maintains function data, see the reference for the space.

The possible options are:

  • if_not_exists = true|false (default = false) - boolean; true means there should be no error if the _func tuple already exists.
  • setuid = true|false (default = false) - with true to make Tarantool treat the function’s caller as the function’s creator, with full privileges. Remember that SETUID works only over binary ports. SETUID doesn’t work if you invoke a function via an admin console or inside a Lua script.
  • language = ‘LUA’|’C’ (default = ‘LUA’).


These functions can be called with function-object:call(arguments); however, unlike the case with ordinary functions, array arguments will not be correctly recognized unless they are enclosed in braces.


box.schema.func.create('calculate', {if_not_exists = false})
box.schema.func.create('calculate', {setuid = false})
box.schema.func.create('calculate', {language = 'LUA'})
box.schema.func.create(func-name[, {options-with-body}])

Create a function tuple. including the body option. (For functions created without the body option, see box.schema.func.create(func-name [, {options-without-body}]).

This is called a “persistent” function because only functions with bodies are persistent. This does create the function itself, the body is a function definition. For explanation of how Tarantool maintains function data, see the reference for the space.

The possible options are:

  • func-name (string) – name of function, which should conform to the rules for object names
  • options (table) – if_not_exists, setuid, language, is_sandboxed, is_deterministic, body.


C functions are imported from .so files, Lua functions can be defined within body. We will only describe Lua functions in this section.

A function tuple with a body is “persistent” because the tuple is stored in a snapshot and is recoverable if the server restarts. All of the option values described in this section are visible in the system space.

If is_sandboxed is true, then the function will be executed in an isolated environment: any operation that accesses the world outside the sandbox will be forbidden or will have no effect. Therefore a sandboxed function can only use modules and functions which cannot affect isolation: assert, error, ipairs, math.*, next, pairs, pcall, print, select, string.*, table.*, tonumber, tostring, type, unpack, utf8.*, xpcall. Also a sandboxed function cannot refer to global variables – they will be treated as local variables because the sandbox is established with setfenv. So a sandboxed function will happen to be stateless and deterministic.

If is_deterministic is true, there is no immediate effect. Tarantool plans to use the is_deterministic value in a future version. A function is deterministic if it always returns the same outputs given the same inputs. It is the function creator’s responsibility to ensure that a function is truly deterministic.

Using a persistent Lua function

After a persistent Lua function is created, it can be found in the system space, and it can be shown with
and it can be invoked by any user with authorization to ‘execute’ it. The syntax for invoking is:
or, if the connection is remote, the syntax is as in net_box:call().


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