Inheritance

Inheritance is a crucial aspect of schema modeling in EdgeDB. Schema items can extend one or more parent types. When extending, the child (subclass) inherits the definition of its parents (superclass).

You can declare abstract object types, properties, links, constraints, and annotations.

Object types

Object types can extend other object types. The extending type (AKA the subtype) inherits all links, properties, indexes, constraints, etc. from its supertypes.

  1. abstract type Animal {
  2. property species -> str;
  3. }
  4. type Dog extending Animal {
  5. property breed -> str;
  6. }

For details on querying polymorphic data, see EdgeQL > Select > Polymorphic queries.

Multiple Inheritance

Object types can extend more than one type — that’s called multiple inheritance. This mechanism allows building complex object types out of combinations of more basic types.

  1. abstract type HasName {
  2. property first_name -> str;
  3. property last_name -> str;
  4. }
  5. abstract type HasEmail {
  6. property email -> str;
  7. }
  8. type Person extending HasName, HasEmail {
  9. property profession -> str;
  10. }

Overloading

An object type can overload an inherited property or link. All overloaded declarations must be prefixed with the overloaded prefix to avoid unintentional overloads.

  1. abstract type Person {
  2. property name -> str;
  3. multi link friends -> Person;
  4. }
  5. type Student extending Person {
  6. overloaded property name -> str {
  7. constraint exclusive;
  8. }
  9. overloaded multi link friends -> Student;
  10. }

Overloaded fields cannot generalize the associated type; it can only make it more specific by setting the type to a subtype of the original or adding additional constraints.

Properties

Properties can be concrete (the default) or abstract. Abstract properties are declared independent of a source or target, can contain annotations, and can be marked as readonly.

  1. abstract property title_prop {
  2. annotation title := 'A title.';
  3. readonly := false;
  4. }

It’s possible to define abstract links that aren’t tied to a particular source or target. Abstract links can be marked as readonly and contain annotations, property declarations, constraints, and indexes.

  1. abstract link link_with_strength {
  2. property strength -> float64;
  3. index on (__subject__@strength);
  4. }
  5. type Person {
  6. multi link friends extending link_with_strength -> Person;
  7. }

Constraints

Use abstract to declare reusable, user-defined constraint types.

  1. abstract constraint in_range(min: anyreal, max: anyreal) {
  2. errmessage :=
  3. 'Value must be in range [{min}, {max}].';
  4. using (max > __subject__ and __subject__ >= min);
  5. }
  6. type Player {
  7. property points -> int64 {
  8. constraint in_range(0, 100);
  9. }
  10. }

Annotations

EdgeQL supports three annotations types by default: title, description, and deprecated. Use abstract annotation to declare custom user-defined annotation types.

  1. abstract annotation admin_note;
  2. type Status {
  3. annotation admin_note := 'system-critical';
  4. # more properties
  5. }

By default, annotations defined on abstract types, properties, and links will not be inherited by their subtypes. To override this behavior, use the inheritable modifier.

  1. abstract inheritable annotation admin_note;