Functions

The Fauna Query Language provides many built-in functions that can be used to query and modify a database. Functions, also known as user-defined functions (or UDFs), provide a mechanism to store and run commonly used FaunaDB queries.

This section describes functions, their anatomy, how to create them, and how execute them:

Overview

FaunaDB supports two different types of functions:

  1. Built-in functions: these are used as the building blocks to query or mutate FaunaDB databases.

  2. User-defined functions (UDFs): these are used to combine functions, built-in or user-defined, into queries that can be executed repeatedly.

UDFs can be anonymous, when declared with the Lambda function, or can be named by using the CreateFunction function.

For example, a simple query that uses a built-in function could be:

Add(1, 1)

That query always returns the same result (2).

Suppose that we want to add 1 to several numbers. We could use an anonymous function:

Map(
  [ 1, 2, 3, 4, 5 ],
  Lambda(
    "number",
    Add(1, Var("number"))
  )
)

The result should be:

[ 2, 3, 4, 5, 6 ]

That query executes the anonymous Lambda function once per entry in the array that Map processes.

For more complex functions, where it might be unwieldy to include the function itself in each query that needs to use it, we can create a named function:

CreateFunction({
  name: "increment",
  body: Query(Lambda("number", Add(1, Var("number"))))
})

Now that the function has been stored and has a name, we can run a query that executes our function like this:

Call(Function("increment"), 50)

When we do so, the result should be:

51
CreateFunction must be called with "server" or "admin" privileges.

Schema for named functions

UDFs are documents that exist within internal "functions" collection of FaunaDB, which can be referred to by name using the built-in Function function. Each function document is stored within the context of the enclosing database: peer, parent, and child databases store functions independently.

When a function is deleted, its definition and associated data becomes inaccessible and is deleted asynchronously.

Field Type Definition and Requirements

name

The name of the function. Cannot be events, sets, self, documents, or _.

body

The query to be run when the function is executed. Must be wrapped in a Query function. See Lambda for more details.

role

Optional- When the function is executed, it should be granted the privileges of the specified role. Can be one of admin, server, server-readonly, or client. See Permissions for more details.

data

Optional - A JSON object that can be used to store metadata about a function.

Signature

The signature of a UDF takes two parameters: an parameter list and a query expression to be executed.

The parameter list specifies the name(s) of the parameters passed to the function upon execution. The parameter list could be a single String name, or an array of string names.

The query expression is any valid FQL query.

To use named parameters within the query expression, use the Var function.

Examples

Consider the following anonymous function (which would result in an error if you attempt to execute it as is; there is no calling context):

Lambda("X", Var("X"))

This function’s parameter list is simply X, which specifies that this function accepts only one parameter and that the parameter’s name is X.

The function’s expression is Var("X"), which means that the function’s output, or return value, is simply the value of the X variable: this function returns the value that was provided to it.

A multi-parameter function might look like this:

Lambda(
  ["X", "Y", "Z"],
  Format("%s %s %s", Var("X"), Var("Y"), Var("Z"))
)

This function accepts an array of parameters, called X, Y, and Z, and then formats the parameter values into a string showing all three values.

Functions must be executed with the same number of parameters that they are defined to accept.

Permissions

By default, UDFs are executed with the privileges of the current query session. For example, if your client code connects to FaunaDB using a "client" key, any called UDFs would, by default, execute with "client" privileges. See Keys for more details.

You can specify a role for named UDFs, which grants the functions of the named role while the UDF executes. This feature is similar to the Unix setuid facility. For example, a function whose role field is set to admin can perform the same query that an "admin" key makes possible, even for sessions authenticated with "client" keys.

Limitations

  • A 30-second transaction timeout is imposed, which would typically be reached by a UDF that does not complete. When the timeout is reached, the transaction is terminated.

  • If a UDF causes a query process to exhaust available memory, the transaction is terminated.

  • Recursion is possible, but is limited to a depth of 200 calls.

  • In some contexts, such as within index bindings, using "server read-only" keys, or attribute-based access control, functions may be restricted from performing write or read operations.

Was this article helpful?

We're sorry to hear that.
Tell us how we can improve!
Visit Fauna's Discourse forums or email docs@fauna.com

Thank you for your feedback!