Top.Mail.Ru
box.schema.func.create() | Tarantool
 

box.schema.func.create()

box.schema.func.create()

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 box.space._func 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’).
Parameters:
Return:

nil

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.

Example:

box.schema.func.create('calculate')
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 box.space._func space.

The possible options are:

Parameters:
  • 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.
Return:

nil

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 box.space._func 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 box.space._func system space, and it can be shown with
box.func.func-name
and it can be invoked by any user with authorization to ‘execute’ it. The syntax for invoking is:
box.func.func-name:call([parameters])
or, if the connection is remote, the syntax is as in net_box:call().

Example:

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
...