# DROP CONSTRAINT
Removes a constraint from a label.
## Synopsis
DROP CONSTRAINTconstraint_nameONlabel_name
bold keywords · italic placeholders you supply · [ ] optional · ... repeatable. See Syntax conventions.
## Description
`DROP CONSTRAINT` removes one constraint from one label. It takes both forms that
[`CREATE CONSTRAINT`](create-constraint.md) creates: the exclusion constraint behind
`IS UNIQUE`, and the check constraint behind a condition. It also drops the index a unique
constraint owns.
The statement is deliberately small. These are the things it does not have:
- **The name is required.** There is no way to say "whatever constraint is on this
property".
- **There is no `IF EXISTS`.** `DROP CONSTRAINT IF EXISTS ...` is a syntax error, so a
constraint that is not there is always an error.
- **There is no `CASCADE` or `RESTRICT`,** and no name list.
- The name cannot be qualified, and neither can the label's. The label is looked up in the
graph named by `graph_path`.
- It reaches any named constraint on the label's table, not only the ones Cypher created.
The label's primary key is one of them. Read the name before you run it.
- A property index is not a constraint. Drop one with
[`DROP PROPERTY INDEX`](drop-property-index.md).
## Parameters
constraint_name
: Name of the constraint to drop. Unqualified. `\dGv`, `\dGe` and `\d` all report it; so
does `pg_constraint`.
label_name
: Label the constraint is on, in the graph named by `graph_path`.
## Examples
The examples build their own graph, `rulebooks`, rather than using
[the example dataset](../../get_started/example-dataset.md), and drop it at the end.
```cypher
CREATE GRAPH rulebooks;
SET graph_path = rulebooks;
CREATE VLABEL film;
CREATE CONSTRAINT film_title_uniq ON film ASSERT title IS UNIQUE;
CREATE CONSTRAINT ON film ASSERT year IS UNIQUE;
CREATE VLABEL teen;
CREATE CONSTRAINT teen_age ON teen ASSERT (10 <= age::int AND age::int <= 19);
CREATE CONSTRAINT ON teen ASSERT age > 9;
```
### Drop a unique constraint
```cypher
DROP CONSTRAINT film_title_uniq ON film;
```
```
DROP CONSTRAINT
```
The constraint and its index are both gone; the unnamed one created afterwards is not:
```psql
\d rulebooks.film
```
```
Table "rulebooks.film"
Column | Type | Collation | Nullable | Default
------------+---------+-----------+----------+---------------------------------------------------------------------------------------------
id | graphid | | not null | graphid(graph_labid('rulebooks.film'::cstring), nextval('rulebooks.film_id_seq'::regclass))
properties | jsonb | | not null | jsonb_build_object()
Indexes:
"film_pkey" PRIMARY KEY, btree (id)
"film_unique_constraint" EXCLUDE USING btree ((properties.'year') WITH =)
Inherits: rulebooks.ag_vertex
```
Running it a second time is an error, because there is no `IF EXISTS` to soften it:
```cypher
DROP CONSTRAINT film_title_uniq ON film;
```
```
ERROR: constraint "film_title_uniq" of relation "film" does not exist
```
```cypher
DROP CONSTRAINT IF EXISTS film_title_uniq ON film;
```
```
ERROR: syntax error at or near "EXISTS"
LINE 1: DROP CONSTRAINT IF EXISTS film_title_uniq ON film;
^
```
### Find the name of a constraint you did not name
A constraint created without a name has a derived one. `pg_constraint` lists every
constraint on the label's table:
```sql
SELECT conname FROM pg_constraint WHERE conrelid = 'rulebooks.teen'::regclass ORDER BY conname;
```
```
conname
--------------------------
teen_age
teen_id_not_null
teen_pkey
teen_properties_check
teen_properties_not_null
(5 rows)
```
`teen_age` is the named check constraint and `teen_properties_check` the derived one. The
other three belong to the label's own shape.
### Drop a check constraint
```cypher
DROP CONSTRAINT teen_properties_check ON teen;
DROP CONSTRAINT teen_age ON teen;
```
Both are gone, and `\dGv` says so by having nothing to report:
```psql
\dGv rulebooks.teen
```
```
List of labels
Graph | Name | Type | Owner
-----------+------+--------+-------
rulebooks | teen | vertex | agens
(1 row)
Vertex label "rulebooks.teen"
--
Inherits: rulebooks.ag_vertex
```
### Refusals worth recognizing
A property index is not a constraint, whatever it is named:
```cypher
CREATE PROPERTY INDEX film_year_idx ON film (year);
DROP CONSTRAINT film_year_idx ON film;
```
```
ERROR: constraint "film_year_idx" of relation "film" does not exist
```
And the name cannot carry the graph:
```cypher
DROP CONSTRAINT rulebooks.film_unique_constraint ON film;
```
```
ERROR: syntax error at or near "."
LINE 1: DROP CONSTRAINT rulebooks.film_unique_constraint ON film;
^
```
Finally, drop the graph the examples built:
```cypher
DROP GRAPH rulebooks CASCADE;
```
## Notes
```{warning}
`DROP CONSTRAINT` takes any named constraint on the label's table, and a label's primary key
is one. `DROP CONSTRAINT film_pkey ON film` succeeds and leaves the label without its
primary key on `id`, and no statement puts that back. Check the name
against `\dGv` or `pg_constraint` first, and keep to the names
[`CREATE CONSTRAINT`](create-constraint.md) produced.
```
To change a constraint, drop it and create it again;
`CREATE OR REPLACE CONSTRAINT` is refused.
A check constraint that a child label inherited can only be dropped from the label that
declares it:
```cypher
CREATE GRAPH hierarchy;
SET graph_path = hierarchy;
CREATE VLABEL work;
CREATE CONSTRAINT work_y ON work ASSERT (year::int > 1900);
CREATE VLABEL feature INHERITS (work);
```
Naming the child is refused:
```cypher
DROP CONSTRAINT work_y ON feature;
```
```
ERROR: cannot drop inherited constraint "work_y" of relation "feature"
```
Dropping it from the parent removes it from the whole family:
```cypher
DROP CONSTRAINT work_y ON work;
DROP GRAPH hierarchy CASCADE;
```
## Compatibility
### ISO/IEC 39075 (GQL)
GQL has no constraint DDL, so nothing corresponds to this statement. Its way of constraining
a graph is a graph type, dropped whole by `` (§12.7). Graph types
are tracked as planned in the
[GQL conformance matrix](../../appendix/gql-conformance.md).
### PostgreSQL
`DROP CONSTRAINT ... ON