Light
Dark
System
v2latest
v3dev
v2latest
v1

Constraints

This section assumes a basic understanding of EdgeQL.

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

Below is a simple property constraint.

Copy
type User {
  required property username -> str {
    constraint exclusive;
  }
}

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 constraint below uses the built-in len() function, which returns the length of a string.

Copy
type User {
  required property username -> str {
    # usernames must be unique
    constraint exclusive;

    # max length (built-in)
    constraint max_len_value(25);
  };
}

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

Copy
type User {
  required property username -> str {
    # max length (as custom constraint)
    constraint expression on (len(__subject__) <= 25);
  };
}

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 simply refer to properties with the leading dot notation (e.g. .<name>).

Copy
type ConstrainedVector {
  required property x -> float64;
  required property y -> float64;

  constraint expression on (
    .x ^ 2 + .y ^ 2 <= 25
  );
}

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.

Copy
# Not valid!
type User {
  required property username -> str;
  multi link friends -> User;

  # ❌ constraints cannot contain paths with more than one hop
  constraint expression on ('bob' in .friends.username);
}

Constraints can be defined on computed properties.

Copy
type User {
  required property username -> str;
  required property clean_username := str_trim(str_lower(.username));

  constraint exclusive on (.clean_username);
}

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

Copy
type User {
  property username -> str;
}

type BlogPost {
  property title -> str;
  link author -> User;

  constraint exclusive on ((.title, .author));
}

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

Copy
type User {
  required property username -> str;
  property deleted -> bool;

  # Not deleted usernames must be unique
  constraint exclusive on (.username) except (.deleted);
}

Custom scalar types can be constrained.

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

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.

Copy
scalar type title extending str {
  constraint expression on (
    __subject__ = str_trim(__subject__)
  );
}
Light
Dark
System