Constraints

This section assumes a basic understanding of EdgeQL.

Constraints gives users fine-grained control over which data is considered valid. The can be defined on properties, links, object types, and custom scalars.

Below is a simple property constraint.

  1. type User {
  2. required property username -> str {
  3. constraint exclusive;
  4. }
  5. }

This example uses a built-in constraint, exclusive. Refer to the table below for a complete list; click the name of a given constraint for the full documentation.

exclusive

Enforce uniqueness among all instances of the containing type

expression

Custom constraint expression

one_of

A list of allowable values

max_value

Maximum value numerically/lexicographically

max_ex_value

Maximum value numerically/lexicographically (exclusive range)

max_len_value

Maximum length (strings only)

min_value

Minimum value numerically/lexicographically

min_ex_value

Minimum value numerically/lexicographically (exclusive range)

min_len_value

Minimum length (strings only)

regexp

Regex constraint (strings only)

The expression constraint is used to define custom constraint logic. Inside custom constraints, the keyword __subject__ can used to reference the value being constrained.

Constraints on properties

The constraint below uses the built-in len() function, which returns the length of a string.

  1. type User {
  2. required property username -> str {
  3. # usernames must be unique
  4. constraint exclusive;
  5. # max length (built-in)
  6. constraint max_len_value(25);
  7. };
  8. }

Custom constraints

The expression constraint is used to define custom constraint logic. Inside custom constraints, the keyword __subject__ can used to reference the value being constrained.

  1. type User {
  2. required property username -> str {
  3. # max length (as custom constraint)
  4. constraint expression on (len(__subject__) <= 25);
  5. };
  6. }

Constraints on object types

Constraints can be defined on object types. This is useful when the constraint logic must reference multiple links or properties.

Inside an object type declaration, you can omit __subject__ and simple refer to properties with the leading dot notation (e.g. .<name>).

  1. type ConstrainedVector {
  2. required property x -> float64;
  3. required property y -> float64;
  4. constraint expression on (
  5. .x ^ 2 + .y ^ 2 <= 25
  6. );
  7. }

Note that the constraint expression cannot contain arbitrary EdgeQL! Due to how constraints are implemented, you can only reference single (non-multi) properties and links defined on the object type.

  1. # Not valid!
  2. type User {
  3. required property username -> str;
  4. multi link friends -> User;
  5. # ❌ constraints cannot contain paths with more than one hop
  6. constraint expression on ('bob' in .friends.username);
  7. }

Computed constraints

Constraints can be defined on computed properties.

  1. type User {
  2. required property username -> str;
  3. required property clean_username := str_trim(str_lower(.username));
  4. constraint exclusive on (.clean_username);
  5. }

Composite constraints

To define a composite constraint, create an exclusive constraint on a tuple of properties or links.

  1. type User {
  2. property username -> str;
  3. }
  4. type BlogPost {
  5. property title -> str;
  6. link author -> User;
  7. constraint exclusive on ((.title, .author));
  8. }

Partial constraints

New

Constraints on object types can be made partial, so that they don’t apply when some condition holds.

  1. type User {
  2. required property username -> str;
  3. property deleted -> bool;
  4. # Not deleted usernames must be unique
  5. constraint exclusive on (.username) except (.deleted);
  6. }

When defining a constraint on a link, __subject__ refers to the link itself. This is commonly used add constraints to link properties.

  1. type User {
  2. property name -> str;
  3. multi link friends -> User {
  4. single property strength -> float64;
  5. constraint expression on (
  6. __subject__@strength >= 0
  7. );
  8. }
  9. }

Constraints on custom scalars

Custom scalar types can be constrained.

  1. scalar type username extending str {
  2. constraint regexp(r'^[A-Za-z0-9_]{4,20}$');
  3. }

Note: you can’t use exclusive constraints on custom scalar types, as the concept of exclusivity is only defined in the context of a given object type.

Use expression constraints to declare custom constraints using arbitrary EdgeQL expressions. The example below uses the built-in str_trim() function.

  1. scalar type title extending str {
  2. constraint expression on (
  3. __subject__ = str_trim(__subject__)
  4. );
  5. }

See also

SDL > Constraints

DDL > Constraints

Introspection > Constraints

Standard Library > Constraints