Skip to content

Commit

Permalink
Update constraint syntax (#1238)
Browse files Browse the repository at this point in the history
* Update constraint syntax, using FOR ... REQUIRE instead of ON ... ASSERT

Co-authored-by: Therese Magnusson <[email protected]>

* review fixes

* Fix more comments

Co-authored-by: Therese Magnusson <[email protected]>
  • Loading branch information
HannesSandberg and Hunterness authored Sep 3, 2021
1 parent 622086e commit 2d1e1c4
Show file tree
Hide file tree
Showing 14 changed files with 190 additions and 104 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -917,7 +917,7 @@ Predicates that can be used to enable this optimization are:
[NOTE]
====
If there is an existence constraint on the property, no predicate is required to trigger the optimization.
For example, `CREATE CONSTRAINT constraint_name ON (p:Person) ASSERT p.name IS NOT NULL`.
For example, `CREATE CONSTRAINT constraint_name FOR (p:Person) REQUIRE p.name IS NOT NULL`.
====
Expand Down Expand Up @@ -1142,7 +1142,7 @@ Predicates that will not work:
[NOTE]
====
If there is an existence constraint on the property, no predicate is required to trigger the optimization.
For example, `CREATE CONSTRAINT constraint_name ON (p:Person) ASSERT p.name IS NOT NULL`
For example, `CREATE CONSTRAINT constraint_name FOR (p:Person) REQUIRE p.name IS NOT NULL`
As of Neo4j {neo4j-version-exact}, predicates with parameters, such as `WHERE n.prop > $param`, can trigger _index-backed order by_.
The only exception are queries with parameters of type `Point`.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,39 @@ Replacement syntax for deprecated and removed features are also indicated.
| Details


a|
label:syntax[]
label:added[]
[source, cypher, role="noheader"]
----
CREATE CONSTRAINT FOR ... REQUIRE ...
----
a|
New syntax for creating constraints, applicable to all constraint types.

a|
label:syntax[]
label:deprecated[]
[source, cypher, role="noheader"]
----
CREATE CONSTRAINT ON ... ASSERT ...
----
a|
Replaced by:
[source, cypher, role="noheader"]
----
CREATE CONSTRAINT FOR ... REQUIRE ...
----


a|
label:functionality[]
label:added[]
[source, cypher, role="noheader"]
----
CREATE CONSTRAINT [constraint_name] [IF NOT EXISTS]
ON (n:LabelName)
ASSERT (n.propertyName_1, …, n.propertyName_n) IS UNIQUE
FOR (n:LabelName)
REQUIRE (n.propertyName_1, …, n.propertyName_n) IS UNIQUE
[OPTIONS "{" option: value[, ...] "}"]
----
a|
Expand Down Expand Up @@ -100,8 +125,8 @@ a| Replaced by:
[source, cypher, role="noheader"]
----
CREATE CONSTRAINT [name]
ON (node:Label)
ASSERT node.property IS NOT NULL
FOR (node:Label)
REQUIRE node.property IS NOT NULL
----


Expand All @@ -119,8 +144,8 @@ Replaced by:
[source, cypher, role="noheader"]
----
CREATE CONSTRAINT [name]
ON ()-[rel:REL]-()
ASSERT rel.property IS NOT NULL
FOR ()-[rel:REL]-()
REQUIRE rel.property IS NOT NULL
----


Expand Down
8 changes: 4 additions & 4 deletions cypher/cypher-docs/src/docs/dev/glossary.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@ This section comprises a glossary of all the keywords -- grouped by category and
|<<query-call, CALL [...YIELD]>> | Reading/Writing | Invoke a procedure deployed in the database.
|<<query-call-subquery, CALL {...}>> | Reading/Writing | Evaluates a subquery, typically used for post-union processing or aggregations.
|<<query-create, CREATE>> | Writing | Create nodes and relationships.
|<<administration-constraints-syntax, CREATE CONSTRAINT [existence] [IF NOT EXISTS] ON (n:Label) ASSERT n.property IS NOT NULL>> | Schema | Create a constraint ensuring that all nodes with a particular label have a certain property.
|<<administration-constraints-syntax, CREATE CONSTRAINT [node_key] [IF NOT EXISTS] ON (n:Label) ASSERT (n.prop1[, ..., n.propN]) IS NODE KEY [OPTIONS {optionKey: optionValue[, ...]}]>> | Schema | Create a constraint that ensures that all nodes with a particular label have all the specified properties and that the combination of property values is unique; i.e. ensures existence and uniqueness.
|<<administration-constraints-syntax, CREATE CONSTRAINT [existence] [IF NOT EXISTS] ON ()-"["r:REL_TYPE"]"-() ASSERT r.property IS NOT NULL>> | Schema | Create a constraint ensuring that all relationships with a particular type have a certain property.
|<<administration-constraints-syntax, CREATE CONSTRAINT [uniqueness] [IF NOT EXISTS] ON (n:Label) ASSERT (n.prop1[, ..., n.propN]) IS UNIQUE [OPTIONS {optionKey: optionValue[, ...]}]>> | Schema | Create a constraint that ensures the uniqueness of the combination of node label and property values for a particular property key combination across all nodes.
|<<administration-constraints-syntax, CREATE CONSTRAINT [existence] [IF NOT EXISTS] FOR (n:Label) REQUIRE n.property IS NOT NULL>> | Schema | Create a constraint ensuring that all nodes with a particular label have a certain property.
|<<administration-constraints-syntax, CREATE CONSTRAINT [node_key] [IF NOT EXISTS] FOR (n:Label) REQUIRE (n.prop1[, ..., n.propN]) IS NODE KEY [OPTIONS {optionKey: optionValue[, ...]}]>> | Schema | Create a constraint that ensures that all nodes with a particular label have all the specified properties and that the combination of property values is unique; i.e. ensures existence and uniqueness.
|<<administration-constraints-syntax, CREATE CONSTRAINT [existence] [IF NOT EXISTS] FOR ()-"["r:REL_TYPE"]"-() REQUIRE r.property IS NOT NULL>> | Schema | Create a constraint ensuring that all relationships with a particular type have a certain property.
|<<administration-constraints-syntax, CREATE CONSTRAINT [uniqueness] [IF NOT EXISTS] FOR (n:Label) REQUIRE (n.prop1[, ..., n.propN]) IS UNIQUE [OPTIONS {optionKey: optionValue[, ...]}]>> | Schema | Create a constraint that ensures the uniqueness of the combination of node label and property values for a particular property key combination across all nodes.
|<<administration-indexes-syntax, CREATE [BTREE] INDEX [single] [IF NOT EXISTS] FOR (n:Label) ON (n.property) [OPTIONS {optionKey: optionValue[, ...]}]>> | Schema | Create an index on all nodes with a particular label and a single property; i.e. create a single-property index.
|<<administration-indexes-syntax, CREATE [BTREE] INDEX [single] [IF NOT EXISTS] FOR ()-"["r:TYPE"]"-() ON (r.property) [OPTIONS {optionKey: optionValue[, ...]}]>> | Schema | Create an index on all relationships with a particular relationship type and a single property; i.e. create a single-property index.
|<<administration-indexes-syntax, CREATE [BTREE] INDEX [composite] [IF NOT EXISTS] FOR (n:Label) ON (n.prop1, ..., n.propN) [OPTIONS {optionKey: optionValue[, ...]}]>> | Schema | Create an index on all nodes with a particular label and multiple properties; i.e. create a composite index.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -156,8 +156,8 @@ This is because `(` and `)` are not special characters, and the `[` and `]` indi
[source, cypher, role=noplay]
----
CREATE CONSTRAINT [constraint_name] [IF NOT EXISTS]
ON (n:LabelName)
ASSERT n.propertyName IS NOT NULL
FOR (n:LabelName)
REQUIRE n.propertyName IS NOT NULL
----

include::administration-security-users-and-roles.adoc[leveloffset=+1]
Expand Down
18 changes: 18 additions & 0 deletions cypher/cypher-docs/src/docs/dev/ql/constraints/examples.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -127,14 +127,32 @@ include::../administration/constraints/listing-constraints-with-filtering.asciid
[[administration-constraints-deprecated-syntax]]
== Deprecated syntax

[discrete]
include::../administration/constraints/create-a-unique-constraint-using-deprecated-syntax.asciidoc[leveloffset=+1]

[discrete]
include::../administration/constraints/drop-a-unique-constraint.asciidoc[leveloffset=+1]

[discrete]
include::../administration/constraints/create-a-node-property-existence-constraint-using-deprecated-syntax-1.asciidoc[leveloffset=+1]

[discrete]
include::../administration/constraints/create-a-node-property-existence-constraint-using-deprecated-syntax-2.asciidoc[leveloffset=+1]

[discrete]
include::../administration/constraints/drop-a-node-property-existence-constraint.asciidoc[leveloffset=+1]

[discrete]
include::../administration/constraints/create-a-relationship-property-existence-constraint-using-deprecated-syntax-1.asciidoc[leveloffset=+1]

[discrete]
include::../administration/constraints/create-a-relationship-property-existence-constraint-using-deprecated-syntax-2.asciidoc[leveloffset=+1]

[discrete]
include::../administration/constraints/drop-a-relationship-property-existence-constraint.asciidoc[leveloffset=+1]

[discrete]
include::../administration/constraints/create-a-node-key-constraint-using-deprecated-syntax.asciidoc[leveloffset=+1]

[discrete]
include::../administration/constraints/drop-a-node-key-constraint.asciidoc[leveloffset=+1]
24 changes: 12 additions & 12 deletions cypher/cypher-docs/src/docs/dev/ql/constraints/syntax.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -32,16 +32,16 @@ This command creates a uniqueness constraint on nodes with the specified label a
[source, cypher, role=noplay]
----
CREATE CONSTRAINT [constraint_name] [IF NOT EXISTS]
ON (n:LabelName)
ASSERT n.propertyName IS UNIQUE
FOR (n:LabelName)
REQUIRE n.propertyName IS UNIQUE
[OPTIONS "{" option: value[, ...] "}"]
----

[source, cypher, role=noplay]
----
CREATE CONSTRAINT [constraint_name] [IF NOT EXISTS]
ON (n:LabelName)
ASSERT (n.propertyName_1, …, n.propertyName_n) IS UNIQUE
FOR (n:LabelName)
REQUIRE (n.propertyName_1, …, n.propertyName_n) IS UNIQUE
[OPTIONS "{" option: value[, ...] "}"]
----

Expand All @@ -53,8 +53,8 @@ This command creates a property existence constraint on nodes with the specified
[source, cypher, role=noplay]
----
CREATE CONSTRAINT [constraint_name] [IF NOT EXISTS]
ON (n:LabelName)
ASSERT n.propertyName IS NOT NULL
FOR (n:LabelName)
REQUIRE n.propertyName IS NOT NULL
----

[discrete]
Expand All @@ -65,8 +65,8 @@ This command creates a property existence constraint on relationships with the s
[source, cypher, role=noplay]
----
CREATE CONSTRAINT [constraint_name] [IF NOT EXISTS]
ON ()-"["R:RELATIONSHIP_TYPE"]"-()
ASSERT R.propertyName IS NOT NULL
FOR ()-"["R:RELATIONSHIP_TYPE"]"-()
REQUIRE R.propertyName IS NOT NULL
----

[discrete]
Expand All @@ -77,16 +77,16 @@ This command creates a node key constraint on nodes with the specified label and
[source, cypher, role=noplay]
----
CREATE CONSTRAINT [constraint_name] [IF NOT EXISTS]
ON (n:LabelName)
ASSERT n.propertyName IS NODE KEY
FOR (n:LabelName)
REQUIRE n.propertyName IS NODE KEY
[OPTIONS "{" option: value[, ...] "}"]
----

[source, cypher, role=noplay]
----
CREATE CONSTRAINT [constraint_name] [IF NOT EXISTS]
ON (n:LabelName)
ASSERT (n.propertyName_1, …, n.propertyName_n) IS NODE KEY
FOR (n:LabelName)
REQUIRE (n.propertyName_1, …, n.propertyName_n) IS NODE KEY
[OPTIONS "{" option: value[, ...] "}"]
----

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,12 +95,12 @@ Creating a unique constraint also creates a unique index (which is faster than a

[source, cypher]
----
CREATE CONSTRAINT person ON (person:Person) ASSERT person.id IS UNIQUE
CREATE CONSTRAINT person FOR (person:Person) REQUIRE person.id IS UNIQUE
----

[source, cypher]
----
CREATE CONSTRAINT movie ON (movie:Movie) ASSERT movie.id IS UNIQUE
CREATE CONSTRAINT movie FOR (movie:Movie) REQUIRE movie.id IS UNIQUE
----

Now importing the relationships is a matter of finding the nodes and then creating relationships between them.
Expand Down
2 changes: 1 addition & 1 deletion cypher/cypher-docs/src/docs/graphgists/intro/labels.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ Let's start out adding a constraint -- in this case we decided that all `Movie`

[source, cypher]
----
CREATE CONSTRAINT ON (movie:Movie) ASSERT movie.title IS UNIQUE
CREATE CONSTRAINT FOR (movie:Movie) REQUIRE movie.title IS UNIQUE
----

[source, querytest]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ private Collection<String> exportConstraints()
String name = quote( constraint.getName() );
String key = quote( id );
String label = quote( constraint.getLabel().name() );
result.add( "create constraint " + name + " on (n:" + label + ") assert n." + key + " is unique" );
result.add( "create constraint " + name + " for (n:" + label + ") require n." + key + " is unique" );
}
Collections.sort( result );
return result;
Expand Down
Loading

0 comments on commit 2d1e1c4

Please sign in to comment.