# `has` statement

The statement `<OWNER VAR> has <ATTRIBUTE VAR>` is used to identify the `<OWNER VAR>` as owning the `<ATTRIBUTE VAR>`.

Schema for the following examples

```typeql
#!test[schema]
define
attribute name, value string;
entity person, owns name;
```

## [](#_inserting_attribute_ownership)Inserting attribute ownership

The `has` keyword can be used to attach an attribute to an object.

```typeql
#!test[write]
#{{
match $person isa person; $name isa name;
#}}
insert $person has $name;
```

An attribute can be created in-place by providing its type and value.

```typeql
#!test[write]
#{{
match $person isa person;
#}}
insert $person has name "Alice";
```

If the value is a variable instead of a literal, you must use `==`.

```typeql
#!test[write]
#{{
match
$person isa person;
#}}
match let $name_value = "Alice";
insert $person has name == $name_value;
```

Writing `insert $person has name $name_value;` will result in an error: "_The variable 'name\_value' cannot be declared as both a 'Attribute' and as a 'Value'._"

This is best understood by rewriting syntactic short-hands into atomic constraints.

`$p has name $n;` **becomes** `$p has $n; $n isa T;`.

`$p has T == $n;` **becomes** `$p has $_a; $_a isa T; $_a == $n;`

In the first case, `$n` is clearly an attribute. The second case, introduces a new variable `$_a` as the attribute and requires its value to be the same as that of $n.

The confusion arises from being able to write `$p has name "Alice;"`. But:

`$p has name "Alice;"` **becomes** `$p has T == "Alice";`

This is syntax-sugar introduced **ONLY** for literals, and is rewritten further as above.

## [](#_deleting_attribute_ownership)Deleting attribute ownership

The `has` keyword is used to remove an attribute from its owner.

```typeql
#!test[write]
#{{
match $person isa person, has name $name;
#}}
delete has $name of $person;
```

## [](#_matching_attributes)Matching attributes

The `has` keyword can be used to match attributes of an object.

```typeql
#!test[read]
match $person has $name;
```

The attribute type may be provided.

```typeql
#!test[read]
match $person has name $name;
```

The attribute can be matched by attribute type and value instead of binding it to a variable.

```typeql
#!test[read]
match $person has name "Alice";
```

Alternatively, a comparison can be used to constrain the attribute value.

```typeql
#!test[read]
match $person has name < "Bob";
```

[links](../links/index.md) [is](../is/index.md)

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