collection.check

Define a check constraint.

A check constraint is a user-defined rule that constrains the values of a document field. Check constraints are implemented as predicates that control whether a document is written to a collection by validating that the value of a field is in an allowed set of values or range.

Check constraints are subject to the same memory and timeout limits as queries without check constraints.

Syntax

check <functionName> (predicateBody: () => Boolean | Null): Boolean

Properties

Parameter Type Required Description

functionName

String

Yes

Check constraint predicate name, which must be unique for the collection.

The functionName identifies the constraint in error messages.

predicateBody

Function

Yes

Check constraint predicate to apply to the given field. The predicateBody must be a pure function and can be an anonymous function. The function can’t read outside the document or write, and can only reference data inside the document.

Discussion

Check constraints can read, call UDFs, and use computed fields but can’t write. A constraint that tries to write results in an evaluation error.

Multiple check constraints can be defined for the collection and a check constraint can evaluate multiple document fields, or multiple values or ranges for a field..

When a document is created, updated, or replaced, all defined check constraints are evaluated by applying the check constraint, which can have four possible outcomes:

  • The predicate returns true. The write to the document is allowed.

  • The predicate returns false or null. The transaction, including the write to the document, fails.

  • The predicate returns a non-boolean non-null value. The transaction, including the write to the document, fails.

  • The predicate fails to evaluate, possibly caused by divide-by-zero, stack overflow, timeout errors, or abort() is called. The transaction, including the write to the document, fails. If a check constraint is failed by calling abort, the argument to abort is returned as if the transaction were failed by calling abort in the query.

Check constraints aren’t applied retroactively to existing data in the database.

Check constraints should be defined defensively to handle the conditions that the field might not exist or might have a different type.

The check constraint is evaluated on the document version when the document is written, not what currently exists. When a check constraint runs on an update operation, it operates on the document with the update applied. When a check constraint runs on a replace operation, it operates on the version that is replacing the original.

Check constraints aren’t evaluated on delete queries.

Check constraint errors

When a document fails check constraints because the check returns false or null, the error includes information about all check constraints that failed for that document:

Failed to create document in collection `Foo`.
constraint failures:
  Document failed check constraint `ok`
  Document failed check constraint `cool`

When a document fails a check constraint by returning a non-boolean value or because evaluation fails, the transaction fails with the following error, and more check constraints aren’t evaluated:

error: Failed to create document in collection `Foo`.
constraint failures:
  Error evaluating check constraint `ok`: function returned a non-boolean value

Check constraint behavior

Check constraints are evaluated instantly after the write is registered in the transaction. The following query:

CC.create({ a: 0, b: 1 }).a

Effectively, evaluates like:

let doc = CC.create({ a: 0, b: 1 })
if (!x(doc)) abort()
if (!noTripleAs(doc)) abort()
doc.a

where x(doc) means the check constraint x is evaluated on doc. If a check constraint fails, no part of the query after the write is evaluated, and no part before the write takes effect because it is a transaction. Another implication is that check constraints see the document write. For example, this means that CC.byA(doc.a).count() in the noTripleAs check evaluates to 1 because the check constraint sees the write of the document to the CC collection.

Examples

  1. Given a hasFunds check constraint for the Customer collection, which validates that a customer balance is greater than or equal to zero, and a customer who currently has a positive balance:

    collection Customer {
      history_days 0
      check hasFunds(.balance >= 0)
    }
    {
      user: "Andy",
      balance: 21
    }
  2. Verify check constraint validation by trying to set the balance to less than zero:

    Customer.byId("388093102421704737")!.update({ balance: -50 })
    constraint_failure
    
    error: Failed to update document with id 388093102421704737 in collection `Customer`.
    constraint failures:
      Document failed check constraint `hasFunds`
    at *query*:1:44
      |
    1 | Customer.byId("388093102421704737")!.update({balance: -50})
      |                                            ^^^^^^^^^^^^^^^^
      |

    The hasFunds check constraint catches the constraint violation. Notice that the error message includes the name of the check constraint predicate.

Is this article helpful? 

Tell Fauna how the article can be improved:
Visit Fauna's forums or email docs@fauna.com

Thank you for your feedback!