# `@range` annotation

The `@range` annotation is used to specify a range of permitted values for attributes.

## [](#_syntax)Syntax

Value annotation syntax

```typeql
<type label> value <value type> @range(N..M);
<type label> value <value type> @range(N..);
<type label> value <value type> @range(..M);
```

Ownership annotation syntax

```typeql
<type label> owns <attribute type label> @range(N..M);
<type label> owns <attribute type label> @range(N..);
<type label> owns <attribute type label> @range(..M);
```

The `@range` annotation can be defined for either an attribute type’s value type or an ownership.

The `@range` annotation accepts either a range argument or a single scalar argument. Arguments must match the value type of `<attribute type label>`. See [Supported value types](#_value_types) for the list of supported value types.

Partially unbounded ranges `N..` and `..M` represent ranges without an upper and lower bounds, respectively.

## [](#_usage)Usage

The `@range` annotation adds a constraint on values of attributes of a given attribute type to be within the specified range.

When defined for an attribute type’s value type, the annotation creates a constraint for any attribute of this attribute type.

```typeql
#!test[schema]
define
  attribute latitude value double @range(-90.0..90.0);
```

When defined for an ownership, the annotation creates a constraint for any attribute of this attribute type owned by the owner type. In the following example, an instance of the `creation-timestamp` type can contain any value, but a `post` can have (`has`) only the `creation-timestamp` s with the suitable values.

```typeql
#!test[schema]
define
  entity post owns creation-timestamp @range(1970-01-01T00:00:00..);
  attribute creation-timestamp, value datetime;
```

### [](#_subtyping_for_attribute_types_values)Subtyping for attribute types' values

The `range` constraint put on an attribute types' value type is inherited. This means that values of all subtypes of a constrained type are also constrained, and this constraint cannot be relaxed from the subtypes.

A subtype can introduce an even stricter constraint to allow only a subrange of the inherited range for its values.

### [](#_subtyping_for_ownerships)Subtyping for ownerships

The `range` constraint put on an ownership should be respected by all the sub attribute types owned by this owner. This way, any instance of any subtype of the `creation-timestamp` [owned by](#_example_owns) any instance of any subtype of the `post` should comply to the defined `range`.

Ownerships of these subtypes can have their own `range` constraints, and they will be respected similarly down the inheritance line.

## [](#_limitations)Limitations

See [Supported value types](#_value_types) for the list of supported value types.

## [](#_references)References

### [](#_value_types)Supported value types

The `@range` annotation is applicable only to value types with a defined ordering for their values.

Table 1. Supported value types   

Value type

Supported?

Comment

`boolean`

✓

`integer`

✓

`double`

✓

`decimal`

✓

`string`

✓

`date`

✓

`datetime`

✓

`datetime-tz`

✓

`duration`

✗

[@values](../values/index.md) [@regex](../regex/index.md)

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