# Define query

Define queries are used to add new types, capabilities, annotations, or functions to the schema.

## [](#_syntax)Syntax

Define queries start with the `define` keyword following by definition statements.

```typeql
define
  <definition_statements>
```

Definition statement can consist of any number of schema-related [statements](../../statements/index.md), simple or composite. Statements should be separated by semicolons. Schema statements in a define query cannot use variables or values, except for functions.

## [](#_behavior)Behavior

A define query adds schema statements to an existing schema. These statements can add new types and functions, or they can add new capabilities and annotations to existing types. Define queries cannot change schema statements already existing in a schema.

Define queries are idempotent, meaning they can be applied multiple times without changing the result of the initial application.

An error is returned (on execution or on commit), and no changes are preserved, if:

*   A definition conflicts with an existing definition.
    
*   The query results in an invalid schema.
    

### [](#_statements_behavior)Statements

*   [`entity` statements](../../statements/entity/index.md) define new entity types. This statement should be provided for every new type of kind entity.
    
*   [`relation` statements](../../statements/relation/index.md) define new relation types. This statement should be provided for every new type of kind relation.
    
*   [`attribute` statements](../../statements/attribute/index.md) define new attribute types. This statement should be provided for every new type of kind attribute.
    
*   [`relates` statements](../../statements/relates/index.md) define new role types for relations. It can be followed by the `as` keyword to define a specialization for two role types.
    
*   [`plays` statements](../../statements/plays/index.md) define new roleplayings between types and relation types. Only entity and relation types can play roles.
    
*   [`owns` statements](../../statements/owns/index.md) define new ownerships between types and attribute types. Only entity and relation types can own attributes.
    
*   [`value` statements](../../statements/value/index.md) define new value types of attribute types. An attribute type can only have up to one value type. If another `value` is already defined for the subject type, an error is returned.
    
*   [`sub` statements](../../statements/sub/index.md) define new subtyping between two types. Those types should be of the same kind: entity, relation, or attribute. If another `sub` is already defined for the subject type, an error is returned.
    
*   [@annotations](../../annotations/index.md) define new annotations. If another annotation of the same type but with different arguments is already defined, an error is returned. Can be applied to:
    
    *   Type labels for entities, relations, attributes.
        
    *   capabilities: `relates`, `plays`, `owns`.
        
    *   Attribute value types: `value`.
        
    
*   [`fun` statements](../../statements/fun/index.md) define new functions.
    

## [](#_examples)Examples

### [](#_defining_types)Defining types

Defining entity types

```typeql
#!test[schema, commit]
define entity user;
```

Defining relation types

```typeql
#!test[schema, fail_at=commit]
define relation parentship;
```

Defining attribute types

```typeql
#!test[schema, fail_at=commit]
define attribute email;
```

### [](#_defining_capabilities)Defining capabilities

Defining relation type’s relates

```typeql
#!test[schema]
#{{
define relation parentship, relates unused-role;
#}}
#!test[schema]
define parentship relates parent, relates child;
```

Defining relation types with subtyping

```typeql
#!test[schema, commit]
define relation fathership sub parentship;
```

Defining relates with role type specializing

```typeql
#!test[schema]
define fathership relates father as parent;
```

Defining roleplaying for multiple roles

```typeql
#!test[schema]
define user plays parentship:parent, plays parentship:child;
```

Defining attribute type’s value type

```typeql
#!test[schema]
define attribute email @abstract; # cheat.
#!test[schema]
define email value string;
```

Defining type’s ownership

```typeql
#!test[schema]
define user owns email;
```

### [](#_defining_annotations)Defining annotations

Defining type’s annotation without arguments

```typeql
#!test[schema]
define parentship @abstract;
```

Defining attribute type’s annotation and value type’s annotation with arguments

```typeql
#!test[schema]
define email @independent, value string @regex("^.*@\w+\.\w+$");
```

Defining type’s ownership’s annotation with arguments

```typeql
#!test[schema]
define user owns email @card(0..2);
```

Defining annotations for relates

```typeql
#!test[schema]
define parentship relates parent @abstract;
```

Defining annotations for specializing relates

```typeql
#!test[schema]
define fathership relates father as parent @abstract;
```

### [](#_defining_functions)Defining functions

```typeql
#!test[schema, commit]
define
  fun karma_with_squared_value($user: user) -> karma, double:
    match
      $user has karma $karma;
      let $karma-squared = $karma * $karma;
    return first $karma, $karma-squared;
```

[Schema queries](../index.md) [Undefine](../undefine/index.md)

[Edit on GitHub](https://github.com/typedb/typedb-docs/edit/3.x-development/typeql-reference/modules/ROOT/pages/schema/define.adoc) Edit this page on GitHub.