diff --git a/antora.yml b/antora.yml index fc9e275..38cee10 100644 --- a/antora.yml +++ b/antora.yml @@ -7,6 +7,6 @@ nav: asciidoc: attributes: page-origin-private: false - neo4j-version: '5.23' - neo4j-version-exact: '5.23.0' - neo4j-buildnumber: '5.23' + neo4j-version: '5.24' + neo4j-version-exact: '5.24.0' + neo4j-buildnumber: '5.24' \ No newline at end of file diff --git a/modules/ROOT/content-nav.adoc b/modules/ROOT/content-nav.adoc index c115e12..37f1894 100644 --- a/modules/ROOT/content-nav.adoc +++ b/modules/ROOT/content-nav.adoc @@ -1,8 +1,8 @@ * xref:index.adoc[] -** xref:errors/index.adoc[] -*** xref:errors/all-errors.adoc[] -** xref:notifications/index.adoc[] -*** xref:notifications/all-notifications.adoc[] -** xref:changelogs.adoc[] +* xref:errors/index.adoc[] +** xref:errors/all-errors.adoc[] +* xref:notifications/index.adoc[] +** xref:notifications/all-notifications.adoc[] +* xref:changelogs.adoc[] diff --git a/modules/ROOT/pages/changelogs.adoc b/modules/ROOT/pages/changelogs.adoc index 2c60c78..6e134a6 100644 --- a/modules/ROOT/pages/changelogs.adoc +++ b/modules/ROOT/pages/changelogs.adoc @@ -1,6 +1,14 @@ :description: This page lists all changes to status codes per Neo4j version. = Changes to status codes per Neo4j version +== Neo4j 5.23 + +From version 5.23, Neo4j has a new GqlStatusObject API in addition to the existing Notification API. + +The GqlStatusObject API provides information about the status of a Cypher query or command execution in compliance with the GQL standard. +It includes GQLSTATUS code, StatusDescription, and DiagnosticRecord. +For more information, see xref:notifications/index.adoc#gqlstatus-notification-object[GQL-status notification object]. + == Neo4j 5.17 **New:** diff --git a/modules/ROOT/pages/errors/all-errors.adoc b/modules/ROOT/pages/errors/all-errors.adoc index 7f6dcc6..28942cd 100644 --- a/modules/ROOT/pages/errors/all-errors.adoc +++ b/modules/ROOT/pages/errors/all-errors.adoc @@ -2,7 +2,7 @@ [[neo4j-errors]] -= List of all error codes += List of all server error codes This page contains lists of all Neo4j errors, grouped by type. diff --git a/modules/ROOT/pages/errors/index.adoc b/modules/ROOT/pages/errors/index.adoc index f11d8ec..4d6e463 100644 --- a/modules/ROOT/pages/errors/index.adoc +++ b/modules/ROOT/pages/errors/index.adoc @@ -1,7 +1,7 @@ :description: The Neo4j error codes for Neo4j version {neo4j-version}. -[[notifications]] -= Error codes +[[error-codes]] += Server errors Error codes are Neo4j status codes returned by the server when the execution of a query fails. They always have the severity level `ERROR`. diff --git a/modules/ROOT/pages/index.adoc b/modules/ROOT/pages/index.adoc index d30fcfc..48b7d10 100644 --- a/modules/ROOT/pages/index.adoc +++ b/modules/ROOT/pages/index.adoc @@ -1,10 +1,18 @@ + +[[status-codes]] +ifdef::backend-pdf[] += Neo4j 5 Status Codes +endif::[] +ifndef::backend-pdf[] += Introduction +endif::[] :description: The Neo4j status codes for Neo4j version {neo4j-version}. :neo4j-buildnumber: {neo4j-version} -[[status-codes]] -= Neo4j Status Codes v5 + This document details all status codes that a Neo4j DBMS may return to indicate the outcome of a request. + == Format Each Neo4j status code follows the same format: @@ -14,6 +22,7 @@ Each Neo4j status code follows the same format: Neo.[Type].[SubType].[Name] ----- + == Types of Neo4j status codes The fact that a Neo4j status code is returned by the server does not always mean there is a fatal error. @@ -46,6 +55,14 @@ The type of the status code determines the effect on the transaction. |=== +[NOTE] +==== +From version 5.23, Neo4j has a new GqlStatusObject API in addition to the existing Notification API. + +The GqlStatusObject API provides information about the status of a Cypher query or command execution in compliance with the GQL standard. +It includes GQLSTATUS code, StatusDescription, and DiagnosticRecord. +For more information, see xref:notifications/index.adoc#gqlstatus-notification-object[GQL-status notification object]. +==== ifndef::backend-pdf[] License: link:{common-license-page-uri}[Creative Commons 4.0] diff --git a/modules/ROOT/pages/notifications/all-notifications.adoc b/modules/ROOT/pages/notifications/all-notifications.adoc index 58038f9..bee9bd2 100644 --- a/modules/ROOT/pages/notifications/all-notifications.adoc +++ b/modules/ROOT/pages/notifications/all-notifications.adoc @@ -1,50 +1,61 @@ :description: This section describes the notifications that Neo4j can return, grouped by category, and an example of when they can occur. [[listOfNnotifications]] -= List of all notification codes += List of all server notification codes -The following are all Neo4j notifications, grouped by category, when they are returned, and an example of improvement. +The following page provides an overview of all notifications in Neo4j, along with some scenarios and their possible solutions. -* <<_performance_notifications, `PERFORMANCE` category>> -* <<_hint_notifications, `HINT` category>> -* <<_unrecognized_notifications, `UNRECOGNIZED` category>> -* <<_unsupported_notifications, `UNSUPPORTED` category>> -* <<_deprecated_notifications, `DEPRECATION` category>> -* <<_security_notifications, `SECURITY` category>> -* <<_topology_notifications, `TOPOLOGY` category>> -* <<_schema_notifications, `SCHEMA` category>> -* <<_generic, `GENERIC` category>> +* <<_performance_notifications, `PERFORMANCE` notifications>> +* <<_hint_notifications, `HINT` notifications>> +* <<_unrecognized_notifications, `UNRECOGNIZED` notifications>> +* <<_unsupported_notifications, `UNSUPPORTED` notifications>> +* <<_deprecated_notifications, `DEPRECATION` notifications>> +* <<_security_notifications, `SECURITY` notifications>> +* <<_topology_notifications, `TOPOLOGY` notifications>> +* <<_schema_notifications, `SCHEMA` notifications>> +* <<_generic, `GENERIC` notifications>> [#_performance_notifications] -== `PERFORMANCE` category +== `PERFORMANCE` notifications Performance notifications are returned whenever the query uses costly operations and the performance may be improved by changing the query or adding an index. [#_neo_clientnotification_statement_cartesianproduct] -=== CartesianProduct +=== Cartesian product -.When is this notification returned? -[TIP] -==== -Whenever there is a cartesian product in the plan. -==== +This notification is returned when there is a Cartesian product in the plan. .Notification details [cols="<1s,<4"] |=== -|Code +|Neo4j code m|Neo.ClientNotification.Statement.CartesianProduct |Title a|This query builds a cartesian product between disconnected patterns. -|Severity -m|INFORMATION +|Description +|If a part of a query contains multiple disconnected patterns, this will build a cartesian product between all those parts. This may produce a large amount of data and slow down query processing. While occasionally intended, it may often be possible to reformulate the query that avoids the use of this cross product, perhaps by adding a relationship between the different parts or by using OPTIONAL MATCH (%s) |Category m|PERFORMANCE +|GQLSTATUS code +m|03N90 +|Status description +a|info: cartesian product. +The disconnected patterns `$pat` build a cartesian product. +A cartesian product may produce a large amount of data and slow down query processing. +|Classification +m|PERFORMANCE +|SeverityLevel +m|INFORMATION |=== -.Cartesian product -==== + +.A query that contains many disconnected patterns +[.tabbed-example] +===== +[.include-with-neo4j-code] +====== + Query:: + [source, cypher, role="noplay"] @@ -60,7 +71,7 @@ While occasionally intended, it may often be possible to reformulate the query t perhaps by adding a relationship between the different parts or by using `OPTIONAL MATCH` (identifier is: (`p`)) Suggestions for improvement:: -In case a cartesian product is needed, nothing can be done to improve this query. +In case a Cartesian product is needed, nothing can be done to improve this query. In many cases, however, you might not need a combination of all children and parents, and that is when this query could be improved. If for example, you need the children and the children's parents, you can improve this query by rewriting it to the following: + @@ -68,32 +79,74 @@ If for example, you need the children and the children's parents, you can improv ---- MATCH (c:Child)-[:ChildOf]->(p:Parent) RETURN c, p ---- -==== + +====== +[.include-with-GQLSTATUS-code] +====== + +Query:: ++ +[source, cypher, role="noplay"] +---- +MATCH (c:Child), (p:Parent) RETURN c, p +---- + +Returned GQLSTATUS code:: +03N90 + +Returned status description:: +info: cartesian product. +The disconnected patterns `(c:Child), (p:Parent)` build a cartesian product. +A cartesian product may produce a large amount of data and slow down query processing. + +Suggestions for improvement:: +In case a Cartesian product is needed, nothing can be done to improve this query. +In many cases, however, you might not need a combination of all children and parents, and that is when this query could be improved. +If for example, you need the children and the children's parents, you can improve this query by rewriting it to the following: ++ +[source, cypher, role="noplay"] +---- +MATCH (c:Child)-[:ChildOf]->(p:Parent) RETURN c, p +---- + +====== +===== [#_neo_clientnotification_statement_unboundedvariablelengthpattern] -=== UnboundedVariableLengthPattern +=== Unbounded variable length pattern -.When is this notification returned? -[TIP] -==== -When there is no upper bound specified on the variable length relationship. -==== +This notification is returned when there is no upper bound specified on the variable length relationship. .Notification details [cols="<1s,<4"] |=== -|Code +|Neo4j code m|Neo.ClientNotification.Statement.UnboundedVariableLengthPattern |Title a|The provided pattern is unbounded, consider adding an upper limit to the number of node hops. -|Severity -m|INFORMATION +|Description +|Using shortest path with an unbounded pattern will likely result in long execution times. +It is recommended to use an upper limit to the number of node hops in your pattern. |Category m|PERFORMANCE +|GQLSTATUS code +m|03N91 +|Status description +a|info: unbounded variable length pattern. The provided pattern `$pat` is unbounded. +Shortest path with an unbounded pattern may result in long execution times. +Use an upper limit (e.g. `[*..5]`) on the number of node hops in your pattern. +|Classification +m|PERFORMANCE +|SeverityLevel +m|INFORMATION |=== .Shortest path with an unbounded pattern -==== +[.tabbed-example] +===== +[.include-with-neo4j-code] +====== + Query:: + [source, cypher, role="noplay"] @@ -113,34 +166,75 @@ Consider adding an upper limit. ---- MATCH p=shortestPath((n)-[*..8]->(m)) RETURN p ---- -==== +====== +[.include-with-GQLSTATUS-code] +====== + +Query:: ++ +[source, cypher, role="noplay"] +---- +MATCH p=shortestPath((n)-[*]->(m)) RETURN p +---- + +Returned GQLSTATUS code:: +03N91 + +Returned status description:: +info: unbounded variable length pattern. +The provided pattern `(n)-[\*]->(m)` is unbounded. +Shortest path with an unbounded pattern may result in long execution times. +Use an upper limit (e.g. `[*..5]`) on the number of node hops in your pattern. + +Suggestions for improvement:: +If you have a big graph, this query might be very slow. +Consider adding an upper limit. ++ +[source, cypher, role="noplay"] +---- +MATCH p=shortestPath((n)-[*..8]->(m)) RETURN p +---- +====== +===== [#_neo_clientnotification_statement_exhaustiveshortestpath] -=== ExhaustiveShortestPath +=== Exhaustive shortest path -.When is this notification returned? -[TIP] -==== -When a predicate, given on the shortest path, needs to inspect the whole path before deciding whether it is valid, the shortest path might fall back to the exhaustive search algorithm. +This notification is returned when a predicate, given on the shortest path, needs to inspect the whole path before deciding whether it is valid, the shortest path might fall back to the exhaustive search algorithm. For more information, see link:https://neo4j.com/docs/cypher-manual/current/execution-plans/shortestpath-planning#_shortest_pathadditional_predicate_checks_on_the_paths[Cypher manual -> Shortest path - additional predicate checks on the paths]. -==== .Notification details [cols="<1s,<4"] |=== -|Code +|Neo4j code m|Neo.ClientNotification.Statement.ExhaustiveShortestPath |Title a|Exhaustive shortest path has been planned for your query that means that shortest path graph algorithm might not be used to find the shortest path. Hence an exhaustive enumeration of all paths might be used in order to find the requested shortest path. -|Severity -m|INFORMATION +|Description +|Using shortest path with an exhaustive search fallback might cause query slow down since shortest path graph algorithms might not work for this use case. +It is recommended to introduce a `WITH` to separate the `MATCH` containing the shortest path from the existential predicates on that path. |Category m|PERFORMANCE +|GQLSTATUS code +m|03N92 +|Status description +a|info: exhaustive shortest path. +The query runs with exhaustive shortest path due to the existential predicate(s) `$pred_list`. +It may be possible to use `WITH` to separate the `MATCH` from the existential predicate(s). +|Classification +m|PERFORMANCE +|SeverityLevel +m|INFORMATION |=== -.Exhaustive shortest path -==== +.A query that runs with an exhaustive shortest path +[.tabbed-example] +===== +[.include-with-neo4j-code] +====== +Query:: ++ [source, cypher, role="noplay"] ---- MATCH p = shortestPath(()-[*..42]-()) @@ -162,32 +256,76 @@ WITH p WHERE ANY(n in nodes(p) WHERE n:Label) RETURN p ---- -==== +====== +[.include-with-GQLSTATUS-code] +====== +Query:: ++ +[source, cypher, role="noplay"] +---- +MATCH p = shortestPath(()-[*..42]-()) +WHERE ANY(n in nodes(p) WHERE n:Label) +RETURN p +---- + +Returned GQLSTATUS code:: +03N92 + +Returned status description:: +info: exhaustive shortest path. +The query runs with exhaustive shortest path due to the existential predicate(s) `ANY(n in nodes(p) WHERE n:Label)`. +It may be possible to use `WITH` to separate the `MATCH` from the existential predicate(s). + +Suggestions for improvement:: +Separate the predicate by introducing a `WITH` after the `MATCH` clause. ++ +[source, cypher, role="noplay"] +---- +MATCH p = shortestPath(()-[*..42]-()) +WITH p +WHERE ANY(n in nodes(p) WHERE n:Label) +RETURN p +---- +====== +===== [#_neo_clientnotification_statement_noapplicableindex] -=== NoApplicableIndex +=== No applicable index -.When is this notification returned? -[TIP] -==== -Given a larger number of nodes, `LOAD CSV` together with a `MATCH` or a `MERGE` clause may speed up the query if you add an index. -==== +This notification is returned when using `LOAD CSV` with a `MATCH` or a `MERGE` clause that matches a non-indexed label. +This may not perform well on large data sets. +Adding an index could improve the query speed. .Notification details [cols="<1s,<4"] |=== -|Code +|Neo4j code m|Neo.ClientNotification.Statement.NoApplicableIndex |Title a|Adding a schema index may speed up this query. -|Severity -m|INFORMATION +|Description +|Using `LOAD CSV` followed by a `MATCH` or `MERGE` that matches a non-indexed label will most likely not perform well on large data sets. +Please consider using a schema index. |Category m|PERFORMANCE +|GQLSTATUS code +m|03N93 +|Status description +a|info: no applicable index. +`LOAD CSV` in combination with `MATCH` or `MERGE` on a label that does not have an index may result in long execution times. +Consider adding an index for label `$label`. +|Classification +m|PERFORMANCE +|SeverityLevel +m|INFORMATION |=== -.Load CSV with `MATCH` or `MERGE` -==== +.`LOAD CSV` with `MATCH` or `MERGE` +[.tabbed-example] +===== +[.include-with-neo4j-code] +====== + Query:: + [source, cypher, role="noplay"] @@ -206,32 +344,70 @@ Create an index on the label and property you match. ---- CREATE INDEX FOR (n:Person) ON (n.name) ---- -==== + +====== +[.include-with-GQLSTATUS-code] +====== + +Query:: ++ +[source, cypher, role="noplay"] +---- +LOAD CSV FROM 'file:///ignore/ignore.csv' AS line WITH * MATCH (n:Person{name:line[0]}) RETURN line, n +---- + +Returned GQLSTATUS code:: +03N93 + +Returned status description:: +info: no applicable index. +`LOAD CSV` in combination with `MATCH` or `MERGE` on a label that does not have an index may result in long execution times. +Consider adding an index for label `Person`. + +Suggestions for improvement:: +Create an index on the label and property you match. ++ +[source, cypher, role="noplay"] +---- +CREATE INDEX FOR (n:Person) ON (n.name) +---- +====== +===== [#_neo_clientnotification_statement_eageroperator] -=== EagerOperator +=== Eager operator -.When is this notification returned? -[TIP] -==== -When the execution plan for a query contains an eager operator. -==== +This notification is returned when the execution plan for a query contains the `Eager` operator. .Notification details [cols="<1s,<4"] |=== -|Code +|Neo4j code m|Neo.ClientNotification.Statement.EagerOperator |Title a|The execution plan for this query contains the Eager operator, which forces all dependent data to be materialized in main memory before proceeding -|Severity -m|INFORMATION +|Description +|Using `LOAD CSV` with a large data set in a query where the execution plan contains the Eager operator could potentially consume a lot of memory and is likely to not perform well. +See the Neo4j Manual entry on the Eager operator for more information and hints on how problems could be avoided. |Category m|PERFORMANCE +|GQLSTATUS code +m|03N94 +|Status description +a|info: eager operator. +The query execution plan contains the `Eager` operator. +`LOAD CSV` in combination with `Eager` can consume a lot of memory. +|Classification +m|PERFORMANCE +|SeverityLevel +m|INFORMATION |=== -.Load CSV with `MATCH` or `MERGE` -==== +.`LOAD CSV` with an Eager operator +[.tabbed-example] +===== +[.include-with-neo4j-code] +====== `LOAD CSV` together with an Eager operator can take up a lot of memory. @@ -259,26 +435,75 @@ CALL { } RETURN line ---- -==== + +====== +[.include-with-GQLSTATUS-code] +====== + +Query:: ++ +[source, cypher, role="noplay"] +---- +LOAD CSV FROM 'file:///ignore/ignore.csv' AS line MATCH (n:Person{name:line[0]}) DELETE n RETURN line +---- + +Returned GQLSTATUS code:: +03N94 + +Returned status description:: +info: eager operator. +The query execution plan contains the `Eager` operator. +`LOAD CSV` in combination with `Eager` can consume a lot of memory. + +Suggestions for improvement:: +See the link:https://neo4j.com/docs/cypher-manual/current/planning-and-tuning/operators/operators-detail/#query-plan-eager[Cypher Manual -> Eager operator] for more information and hints on how to avoid problems. +In this specific case, the query could be rewritten to the following: ++ +[source, cypher, role="noplay"] +---- +LOAD CSV FROM 'file:///ignore/ignore.csv' AS line +CALL { + WITH line + MATCH (n:Person{name:line[0]}) DELETE n +} +RETURN line +---- +====== +===== + [#_neo_clientnotification_statement_dynamicproperty] -=== DynamicProperty +=== Dynamic property .Notification details [cols="<1s,<4"] |=== -|Code +|Neo4j code m|Neo.ClientNotification.Statement.DynamicProperty |Title a|Queries using dynamic properties will use neither index seeks nor index scans for those properties -|Severity -m|INFORMATION +|Description +|Using a dynamic property makes it impossible to use an index lookup for this query (%s) |Category m|PERFORMANCE +|GQLSTATUS code +m|03N95 +|Status description +a|info: dynamic property. +An index exists on label/type(s) `$label_list`. +It is not possible to use indexes for dynamic properties. +Consider using static properties. +|Classification +m|PERFORMANCE +|SeverityLevel +m|INFORMATION |=== -.Using a dynamic node property key makes it impossible to use indexes -==== +.A dynamic node property key makes it impossible to use indexes +[.tabbed-example] +===== +[.include-with-neo4j-code] +====== Query:: + @@ -288,7 +513,7 @@ MATCH (n:Person) WHERE n[$prop] IS NOT NULL RETURN n; ---- Description of the returned code:: -Did not supply query with enough parameters. The produced query plan will not be cached and is not executable without `EXPLAIN`. (Missing parameters: `prop`) +Using a dynamic property makes it impossible to use an index lookup for this query (indexed label is: `Person`) Suggestions for improvement:: If there is an index for `(n:Person) ON (n.name)`, it will not be used for the above query because the query is using a dynamic property. @@ -299,10 +524,46 @@ For example, if `prop` is equal to `name`, the following query would be able to ---- MATCH (n:Person) WHERE n.name IS NOT NULL RETURN n; ---- -==== -.Using dynamic relationship property key makes it impossible to use indexes -==== +====== +[.include-with-GQLSTATUS-code] +====== + +Query:: ++ +[source, cypher] +---- +MATCH (n:Person) WHERE n[$prop] IS NOT NULL RETURN n; +---- + +Returned GQLSTATUS code:: +03N95 + +Returned status description:: +info: dynamic property. +An index exists on label/type(s) `Person`. +It is not possible to use indexes for dynamic properties. +Consider using static properties. + +Suggestions for improvement:: +If there is an index for `(n:Person) ON (n.name)`, it will not be used for the above query because the query is using a dynamic property. +Therefore, if there is an index, it is better to use the constant value. +For example, if `prop` is equal to `name`, the following query would be able to use the index: ++ +[source, cypher] +---- +MATCH (n:Person) WHERE n.name IS NOT NULL RETURN n; +---- + +====== +===== + +.A dynamic relationship property key makes it impossible to use indexes +[.tabbed-example] +===== +[.include-with-neo4j-code] +====== + Query:: + [source,cypher] @@ -311,7 +572,7 @@ MATCH ()-[r: KNOWS]->() WHERE r[$prop] IS NOT NULL RETURN r ---- Description of the returned code:: -Did not supply query with enough parameters. The produced query plan will not be cached and is not executable without `EXPLAIN`. (Missing parameters: `prop`) +Using a dynamic property makes it impossible to use an index lookup for this query (indexed type is: `KNOWS`) Suggestions for improvement:: Similar to dynamic node properties, use a constant value if possible, especially when there is an index on the relationship property. @@ -322,51 +583,108 @@ For example, if `$prop` is equal to `since`, you can rewrite the query to: MATCH ()-[r: KNOWS]->() WHERE r.since IS NOT NULL RETURN r ---- -==== +====== +[.include-with-GQLSTATUS-code] +====== + +Query:: ++ +[source,cypher] +---- +MATCH ()-[r: KNOWS]->() WHERE r[$prop] IS NOT NULL RETURN r +---- + +Returned GQLSTATUS code:: +03N95 + +Returned status description:: +info: dynamic property. +An index exists on label/type(s) `KNOWS`. +It is not possible to use indexes for dynamic properties. +Consider using static properties. + +Suggestions for improvement:: +Similar to dynamic node properties, use a constant value if possible, especially when there is an index on the relationship property. +For example, if `$prop` is equal to `since`, you can rewrite the query to: ++ +[source, cypher] +---- +MATCH ()-[r: KNOWS]->() WHERE r.since IS NOT NULL RETURN r +---- + +====== +===== [#_neo_clientnotification_statement_codegenerationfailed] -=== CodeGenerationFailed +=== Failed code generation + +The `CodeGenerationFailed` notification is created when it is not possible to generate a code for a query, for example, when the query is too big. +For more information about the specific query, see the stack trace in the _debug.log_ file. .Notification details [cols="<1s,<4"] |=== -|Code +|Neo4j code m|Neo.ClientNotification.Statement.CodeGenerationFailed |Title -a|The database was unable to generate code for the query. A stack trace can be found in the _debug.log_. -|Severity -m|INFORMATION +a|The database was unable to generate code for the query. A stacktrace can be found in the _debug.log_. +|Description +|The database was unable to generate code for the query. A stacktrace can be found in the debug.log. (method too big) |Category m|PERFORMANCE +|GQLSTATUS code +m|03N96 +|Status description +a|info: failed code generation. +Failed to generate code, falling back to interpreted $enginetype engine. A stacktrace can be found in the debug.log. Cause: $msg. +|Classification +m|PERFORMANCE +|SeverityLevel +m|INFORMATION |=== -The `CodeGenerationFailed` notification is created when it is not possible to generate a code for a query, for example, when the query is too big. -To find more information about the specific query, see the stack trace in the _debug.log_ file. +//TO ADD EXAMPLES +//To update the description when the code is spit out [#_hint_notifications] -== `HINT` category +== `HINT` notifications `HINT` notifications are returned by default when the Cypher planner or runtime cannot create a query plan to fulfill a specified hint, for example, `JOIN` or `INDEX`. -This behavior of the Cypher planner or runtime can be changed by setting the configuration `dbms.cypher.hints_error` to `true`, in which case, the query will return an error instead. +This behavior of the Cypher planner or runtime can be changed by setting the configuration link:https://neo4j.com/docs/operations-manual/current/configuration/configuration-settings/#config_dbms.cypher.hints_error[`dbms.cypher.hints_error`] to `true`. +In this case, the query will return an error. [#_neo_clientnotification_statement_joinhintunfulfillablewarning] -=== JoinHintUnfulfillableWarning +=== Join hint unfulfillable .Notification details [cols="<1s,<4"] |=== -|Code +|Neo4j code m|Neo.ClientNotification.Statement.JoinHintUnfulfillableWarning |Title a|The database was unable to plan a hinted join. -|Severity -m|WARNING +|Description +|The hinted join was not planned. +This could happen because no generated plan contained the join key, +please try using a different join key or restructure your query. (%s) |Category m|HINT +|GQLSTATUS code +m|01N30 +|Status description +a|warn: join hint unfulfillable. Unable to create a plan with `JOIN ON $var_list`. Try to change the join key(s) or restructure your query. +|Classification +m|HINT +|SeverityLevel +m|WARNING |=== -.A `JOIN` hint was given, but it was not possible to fulfill the hint. -==== +.Inability to fulfill the hint despite the given `JOIN` hint +[.tabbed-example] +===== +[.include-with-neo4j-code] +====== + Query:: + [source, cypher] @@ -385,28 +703,72 @@ This could happen because no generated plan contained the join key, please try using a different join key or restructure your query. (hinted join key identifier is: `a`) Suggestions for improvement:: -The join hint cannot be fulfilled because the given `JOIN` variable was introduced before the optional match and is therefore already bound. -The only option for this query is to remove the hint or change the query so it is possible to use the hint. -==== +The `JOIN` hint cannot be applied because its specified variable is before the `OPTIONAL MATCH` and, therefore, is already bound. +The only option for this query is to either remove the hint or modify the query to allow it to be used. + +====== +[.include-with-GQLSTATUS-code] +====== + +Query:: ++ +[source, cypher] +---- +MATCH (a:A) +WITH a, 1 AS horizon +OPTIONAL MATCH (a)-[r]->(b:B) +USING JOIN ON a +OPTIONAL MATCH (a)--(c) +RETURN * +---- + +Returned GQLSTATUS code:: +01N30 + +Returned status description:: +warn: joint hint unfulfillable. +Unable to create a plan with `JOIN ON a`. +Try to change the join key(s) or restructure your query. + +Suggestions for improvement:: +The `JOIN` hint cannot be applied because its specified variable is before the `OPTIONAL MATCH` and, therefore, is already bound. +The only option for this query is to either remove the hint or modify the query to allow it to be used. + +====== +===== + [#_neo_clientnotification_schema_hintedindexnotfound] -=== HintedIndexNotFound +=== Hinted index not found .Notification details [cols="<1s,<4"] |=== -|Code +|Neo4j code m|Neo.ClientNotification.Schema.HintedIndexNotFound |Title a|The request (directly or indirectly) referred to an index that does not exist. -|Severity -m|WARNING +|Description +|The hinted index does not exist, please check the schema (%s) |Category m|HINT +|GQLSTATUS code +m|01N31 +|Status description +a|warn: hinted index not found. +Unable to create a plan with `$index_descr` because the index does not exist. +|Classification +m|HINT +|SeverityLevel +m|WARNING |=== -.An index hint was given, but it was not possible to use the index. -==== +.Inability to use the label index despite the given index hint +[.tabbed-example] +===== +[.include-with-neo4j-code] +====== + Query:: + [source, cypher] @@ -424,86 +786,191 @@ Suggestions for improvement:: The hinted index does not exist, make sure the label and property are spelled correctly. If the spelling is correct, either create the index or remove the hint from the query. -==== +====== +[.include-with-GQLSTATUS-code] +====== -.A relationship index hint was given, but it was not possible to use the index -==== Query:: + [source, cypher] ---- -MATCH ()-[r:Rel]-() -USING INDEX r:Rel(id) -WHERE r.id = 1 -RETURN r +MATCH (a: Label) +USING INDEX a:Label(id) +WHERE a.id = 1 +RETURN a ---- -Description of the returned code:: -The hinted index does not exist, please check the schema (index is: INDEX FOR ()-[`r`:`Rel`]-() ON (`r`.`id`)) +Returned GQLSTATUS code:: +01N31 + +Returned status description:: +warn: hinted index not found. +Unable to create a plan with `INDEX :Label(id)` because the index does not exist. Suggestions for improvement:: The hinted index does not exist, make sure the label and property are spelled correctly. If the spelling is correct, either create the index or remove the hint from the query. +====== +===== -==== +.Inability to use the relationship index despite the given index hint +[.tabbed-example] +===== +[.include-with-neo4j-code] +====== -[#_unrecognized_notifications] -== `UNRECOGNIZED` category +Query:: ++ +[source, cypher] +---- +MATCH ()-[r:Rel]-() +USING INDEX r:Rel(id) +WHERE r.id = 1 +RETURN r +---- + +Description of the returned code:: +The hinted index does not exist, please check the schema (index is: INDEX FOR ()-[`r`:`Rel`]-() ON (`r`.`id`)) + +Suggestions for improvement:: +The hinted index does not exist, make sure the relationship type and property are spelled correctly. +If the spelling is correct, either create the index or remove the hint from the query. + +====== +[.include-with-GQLSTATUS-code] +====== + +Query:: ++ +[source, cypher] +---- +MATCH ()-[r:Rel]-() +USING INDEX r:Rel(id) +WHERE r.id = 1 +RETURN r +---- + +Returned GQLSTATUS code:: +01N31 + +Returned status description:: +warn: hinted index not found. +Unable to create a plan with `INDEX :Rel(id)` because the index does not exist. + +Suggestions for improvement:: +The hinted index does not exist, make sure the relationship type and property are spelled correctly. +If the spelling is correct, either create the index or remove the hint from the query. +====== +===== + +[#_unrecognized_notifications] +== `UNRECOGNIZED` notifications -A notification has the unrecognized category if the query or command mentions entities that are unknown to the system. +Unrecognized notifications are returned when the query or command mentions entities that are unknown to the system. [#_neo_clientnotification_database_homedatabasenotfound] -=== HomeDatabaseNotFound +=== Home database not found .Notification details [cols="<1s,<4"] |=== -|Code +|Neo4j code m|Neo.ClientNotification.Database.HomeDatabaseNotFound |Title a|The request referred to a home database that does not exist. -|Severity -m|INFORMATION +|Description +|The home database provided does not currently exist in the DBMS. +This command will not take effect until this database is created. (%s`) |Category m|UNRECOGNIZED +|GQLSTATUS code +m|00N50 +|Status description +a|note: successful completion - home database not found. +The database `$db` does not exist. +Verify that the spelling is correct or create the database for the command to take effect. +|Classification +m|UNRECOGNIZED +|SeverityLevel +m|INFORMATION |=== -.Set the `home` database to a database that does not yet exist. -==== +.Setting the `home` database to a database that does not exist +[.tabbed-example] +===== +[.include-with-neo4j-code] +====== + Query:: + [source,cypher] ---- -CREATE USER linnea SET PASSWORD "password" SET HOME DATABASE NonExistingDatabase +CREATE USER john SET PASSWORD "secret" SET HOME DATABASE nej4 ---- Description of the returned code:: The home database provided does not currently exist in the DBMS. -This command will not take effect until this database is created. (HOME DATABASE: `nonexistingdatabase`) +This command will not take effect until this database is created. (HOME DATABASE: `nej4`) Suggestions for improvement:: -Make sure the home database has not been misspelled. +Verify that the home database name is not misspelled. -==== +====== +[.include-with-GQLSTATUS-code] +====== + +Query:: ++ +[source,cypher] +---- +CREATE USER john SET PASSWORD "secret" SET HOME DATABASE nej4 +---- + +Returned GQLSTATUS code:: +00N50 + +Returned status description:: +note: successful completion - home database not found. +The database `ne4j` does not exist. +Verify that the spelling is correct or create the database for the command to take effect. + +Suggestions for improvement:: +Verify that the home database name is not misspelled. +====== +===== [#_neo_clientnotification_statement_unknownlabelwarning] -=== UnknownLabelWarning +=== Unknown label .Notification details [cols="<1s,<4"] |=== -|Code +|Neo4j code m|Neo.ClientNotification.Statement.UnknownLabelWarning |Title a|The provided label is not in the database. -|Severity -m|WARNING +|Description +|One of the labels in your query is not available in the database, make sure you didn't misspell it or that the label is available when you run this statement in your application (%s) |Category m|UNRECOGNIZED +|GQLSTATUS code +m|01N50 +|Status description +a|warn: unknown label. +The label `$label` does not exist. +Verify that the spelling is correct. +|Classification +m|UNRECOGNIZED +|SeverityLevel +m|WARNING |=== -.Match on a node with a label that does not exist in the database. -==== +.Matching on a node with a label that does not exist in the database +[.tabbed-example] +===== +[.include-with-neo4j-code] +====== + Query:: + [source,cypher] @@ -515,28 +982,66 @@ Description of the returned code:: One of the labels in your query is not available in the database, make sure you didn't misspell it or that the label is available when you run this statement in your application (the missing label name is: `Perso`) Suggestions for improvement:: -Make sure you didn't misspell the label. If nodes with the given label will be created in the future, then no change is needed. +Verify that the label is not misspelled. +If you plan to create nodes with that label in the future, then no change is needed. -==== +====== +[.include-with-GQLSTATUS-code] +====== + +Query:: ++ +[source,cypher] +---- +MATCH (n:Perso) RETURN n +---- + +Returned GQLSTATUS code:: +01N50 + +Returned status description:: +warn: unknown label. +The label `Perso` does not exist. +Verify that the spelling is correct. + +Suggestions for improvement:: +Verify that the label is not misspelled. +If you plan to create nodes with that label in the future, no change is needed. +====== +===== [#_neo_clientnotification_statement_unknownrelationshiptypewarning] -=== UnknownRelationshipTypeWarning +=== Unknown relationship type .Notification details [cols="<1s,<4"] |=== -|Code +|Neo4j code m|Neo.ClientNotification.Statement.UnknownRelationshipTypeWarning |Title a|The provided relationship type is not in the database. -|Severity -m|WARNING +|Description +|One of the relationship types in your query is not available in the database, +make sure you didn't misspell it or that the label is available when you run this statement in your application (%s) |Category m|UNRECOGNIZED +|GQLSTATUS code +m|01N51 +|Status description +a|warn: unknown relationship type. +The relationship type `$reltype` does not exist. +Verify that the spelling is correct. +|Classification +m|UNRECOGNIZED +|SeverityLevel +m|WARNING |=== -.Match on a relationship, where there are no relationships in the database with the given relationship type. -==== +.Matching a relationship with a type that does not exist +[.tabbed-example] +===== +[.include-with-neo4j-code] +====== Query:: + [source,cypher] @@ -549,68 +1054,144 @@ One of the relationship types in your query is not available in the database, make sure you didn't misspell it or that the label is available when you run this statement in your application (the missing relationship type is: `NonExistingType`) Suggestions for improvement:: -Make sure you did not misspell the relationship type. -If relationships will be created, with the given relationship type, in the future, then no change to the query is needed. +Verify that the relationship type is not misspelled. +If you plan to create relationships of this type in the future, no change is needed. -==== +====== +[.include-with-GQLSTATUS-code] +====== +Query:: ++ +[source,cypher] +---- +MATCH (n)-[:NonExistingType]->() RETURN n +---- + +Returned GQLSTATUS code:: +01N51 + +Returned status description:: +warn: unknown relationship type. +The relationship type `NonExistingType` does not exist. +Verify that the spelling is correct. + +Suggestions for improvement:: +Verify that the relationship type is not misspelled. +If you plan to create relationships of this type in the future, no change is needed. +====== +===== [#_neo_clientnotification_statement_unknownpropertykeywarning] -=== UnknownPropertyKeyWarning +=== Unknown property key .Notification details [cols="<1s,<4"] |=== -|Code +|Neo4j code m|Neo.ClientNotification.Statement.UnknownPropertyKeyWarning |Title a|The provided property key is not in the database -|Severity -m|WARNING +|Description +|One of the property names in your query is not available in the database, +make sure you didn't misspell it or that the label is available when you run this statement in your application (%s) |Category m|UNRECOGNIZED +|GQLSTATUS code +m|01N52 +|Status description +a|warn: unknown property key. +The property `$propkey` does not exist. +Verify that the spelling is correct. +|Classification +m|UNRECOGNIZED +|SeverityLevel +m|WARNING |=== -.Match on a property key that does not exist. -==== +.Matching a property key that does not exist +[.tabbed-example] +===== +[.include-with-neo4j-code] +====== Query:: + [source,cypher] ---- -MATCH (n {nonExistingProp:1}) RETURN n +MATCH (n:Person {nme:”Tom”}) +RETURN n ---- Description of the returned code:: One of the property names in your query is not available in the database, -make sure you didn't misspell it or that the label is available when you run this statement in your application (the missing property name is: `nonExistingProp`) +make sure you didn't misspell it or that the label is available when you run this statement in your application (the missing property name is: `nme`) Suggestions for improvement:: -Make sure you didn't misspell the property key. If the property key will be created in the future, then no change is needed to the query. +Verify that the property key is not misspelled. +If you plan to create that property key in the future, no change is needed. -==== +====== +[.include-with-GQLSTATUS-code] +====== +Query:: ++ +[source,cypher] +---- +MATCH (n:Person {nme:”Tom”}) +RETURN n +---- + +Returned GQLSTATUS code:: +01N52 + +Returned status description:: +warn: unknown property key. +The property `nme` does not exist. +Verify that the spelling is correct. + +Suggestions for improvement:: +Verify that the property key is not misspelled. +If you plan to create that property key in the future, no change is needed. +====== +===== [#_unsupported_notifications] == `UNSUPPORTED` category -Notifications with the unsupported category are created if the query or command is trying to use features that are not supported by the current system or using experimental features that should not be used in production. +Unsupported notifications are returned when the query or command is trying to use features that are not supported by the current system or using experimental features that should not be used in production. [#_neo_clientnotification_statement_runtimeunsupportedwarning] -=== RuntimeUnsupportedWarning +=== Unsupported runtime .Notification details [cols="<1s,<4"] |=== -|Code +|Neo4j code m|Neo.ClientNotification.Statement.RuntimeUnsupportedWarning |Title a|This query is not supported by the chosen runtime. -|Severity -m|WARNING +|Description +|Selected runtime is unsupported for this query, please use a different runtime instead or fallback to default. +(%s) |Category m|UNSUPPORTED +|GQLSTATUS code +m|01N40 +|Status description +a|warn: unsupported runtime. +The query cannot be executed with `$preparser_input1`, `$preparser_input2` is used. +Cause: `$msg`. +|Classification +m|UNSUPPORTED +|SeverityLevel +m|WARNING |=== -.The chosen runtime is not supported for the given query -==== +.A runtime is not supported by a Cypher command +[.tabbed-example] +===== +[.include-with-neo4j-code] +====== + Query:: + [source,cypher] @@ -629,22 +1210,57 @@ Use a different runtime or remove the runtime option to run the query with the d ---- SHOW INDEXES YIELD * ---- -==== +====== +[.include-with-GQLSTATUS-code] +====== +Query:: ++ +[source,cypher] +---- +EXPLAIN CYPHER runtime=pipelined SHOW INDEXES YIELD * +---- + +Returned GQLSTATUS code:: +01N40 + +Returned status description:: +warn: unsupported runtime. +The query cannot be executed with `runtime=pipelined`, `runtime=slotted` is used. +Cause: Pipelined does not yet support the plans including `ShowIndexes`, use another runtime. + +Suggestions for improvement:: +Use a different runtime or remove the runtime option to run the query with the default runtime: ++ +[source,cypher] +---- +SHOW INDEXES YIELD * +---- +====== +===== + +[role=label--deprecated-5.14] [#_neo_clientnotification_statement_runtimeexperimental] === RuntimeExperimental +[NOTE] +==== +The usage of this notification has been removed since Neo4j 5.14. +==== + .Notification details [cols="<1s,<4"] |=== -|Code +|Neo4j code m|Neo.ClientNotification.Statement.RuntimeExperimental |Title a|This feature is experimental and should not be used in production systems. -|Severity -m|WARNING +|Description +|You are using an experimental feature (%s) |Category m|UNSUPPORTED +|SeverityLevel +m|WARNING |=== .Use of the parallel runtime @@ -669,228 +1285,613 @@ MATCH (n) RETURN (n) ==== [#_deprecated_notifications] -== `DEPRECATION` category +== `DEPRECATION` notifications -Notifications within the deprecation category contain information about a feature or functionality which has been deprecated. It is important to change to the new functionality, otherwise, the query might break in a future version. +Deprecation notifications contain information about a feature or functionality that has been deprecated. +It is important to change to the new functionality, otherwise, the query might break in a future version. -[#_neo_clientnotification_statement_featuredeprecationwarning] -=== FeatureDeprecationWarning +[#_neo_clientnotification_statement_featuredeprecated] +=== Feature deprecated .Notification details [cols="<1s,<4"] |=== -|Code +|Neo4j code m|Neo.ClientNotification.Statement.FeatureDeprecationWarning |Title a|This feature is deprecated and will be removed in future versions. -|Severity -m|WARNING +|Descriptions +a| +- The procedure has a deprecated field. (%s) +- The function has a deprecated field. (%s) +- Creating an entity (%s) and referencing that entity in a property definition in the same CREATE is deprecated. +- Merging an entity (%s) and referencing that entity in a property definition in the same MERGE is deprecated. +- The Unicode character `%s` is deprecated for unescaped identifiers and will be considered as a whitespace character in the future. +To continue using it, escape the identifier by adding backticks around the identifier `%s`. +- The character with the Unicode representation `%s` is deprecated for unescaped identifiers and will not be supported in the future. +To continue using it, escape the identifier by adding backticks around the identifier `%s`. +- All subqueries in a UNION [ALL] should have the same ordering for the return columns. +Using differently ordered return items in a UNION [ALL] clause is deprecated and will be removed in a future version. +- Databases and aliases with unescaped `.` are deprecated unless to indicate that they belong to a composite database. +Names containing `.` should be escaped. (%s) |Category m|DEPRECATION +|GQLSTATUS code +m|01N00 +|Status description +a|warn: feature deprecated. $msg +|Classification +m|DEPRECATION +|SeverityLevel +m|WARNING |=== -.Colon after the | in a relationship pattern -==== +.Create a database with an unescaped name containing a dot +[.tabbed-example] +===== +[.include-with-neo4j-code] +====== Query:: + [source,cypher] ---- -MATCH (a)-[:A|:B|:C]-() RETURN * +CREATE DATABASE foo.bar ---- Description of the returned code:: -The semantics of using colon in the separation of alternative relationship types will change in a future version. (Please use ':A|B|C' instead) +Databases and aliases with unescaped `.` are deprecated unless to indicate that they belong to a composite database. +Names containing `.` should be escaped. (Name: `foo.bar`) Suggestions for improvement:: -Remove the colon inside the relationship type expression. +If not intended for a composite database, escape the name with the character ```. + [source,cypher] ---- -MATCH (a)-[:A|B|C]-() RETURN * +CREATE DATABASE `foo.bar` ---- -==== -.Setting properties using a node -==== +====== +[.include-with-GQLSTATUS-code] +====== Query:: + [source,cypher] ---- -MATCH (a)-[]-(b) -SET a = b +CREATE DATABASE foo.bar ---- -Description of the returned code:: -The use of nodes or relationships for setting properties is deprecated and will be removed in a future version. Please use `properties()` instead. +Returned GQLSTATUS code:: +01N00 + +Returned status description:: +warn: feature deprecated. +Databases and aliases with unescaped `.` are deprecated unless to indicate that they belong to a composite database. Names containing `.` should be escaped. (Name: foo.bar) Suggestions for improvement:: -Use the `properties()` function to get all properties from `b`. +If not intended for a composite database, escape the name with the character ```. + [source,cypher] ---- -MATCH (a)-[]-(b) -SET a = properties(b) +CREATE DATABASE `foo.bar` ---- -==== +====== +===== -.Setting properties using a relationship -==== +.Using differently ordered return items in a `UNION` clause +[.tabbed-example] +===== +[.include-with-neo4j-code] +====== Query:: + [source,cypher] ---- -MATCH (a)-[r]-(b) -SET a += r +RETURN 'val' as one, 'val' as two +UNION +RETURN 'val' as two, 'val' as one ---- Description of the returned code:: -The use of nodes or relationships for setting properties is deprecated and will be removed in a future version. Please use `properties()` instead. +All subqueries in a UNION [ALL] should have the same ordering for the return columns. +Using differently ordered return items in a UNION [ALL] clause is deprecated and will be removed in a future version. Suggestions for improvement:: -Use the `properties()` function to get all properties from `r` +Use the same order for the return columns in all subqueries combined by a `UNION` clause. + + [source,cypher] ---- -MATCH (a)-[r]-(b) -SET a += properties(r) +RETURN 'val' as one, 'val' as two +UNION +RETURN 'val' as one, 'val' as two ---- -==== -.Shortest path with a fixed relationship length -==== +====== +[.include-with-GQLSTATUS-code] +====== Query:: + [source,cypher] ---- -MATCH (a:Start), shortestPath((a)-[r]->()) RETURN a +RETURN 'val' as one, 'val' as two +UNION +RETURN 'val' as two, 'val' as one ---- -Description of the returned code:: -The use of `shortestPath` and `allShortestPaths` with fixed length relationships is deprecated and will be removed in a future version. -Please use a path with a length of `1 [r*1..1]` instead or a `Match` with a `limit`. +Returned GQLSTATUS code:: +01N00 + +Returned status description:: +warn: feature deprecated. +All subqueries in a UNION [ALL] should have the same ordering for the return columns. +Using differently ordered return items in a UNION [ALL] clause is deprecated and will be removed in a future version. Suggestions for improvement:: -If the relationship length is fixed, there is no reason to search for the shortest path. -Instead, you can rewrite it to the following: +Use the same order for the return columns in all subqueries combined by a `UNION` clause. + + [source,cypher] ---- -MATCH (a: Start)-[r]->(b: End) RETURN b LIMIT 1 +RETURN 'val' as one, 'val' as two +UNION +RETURN 'val' as one, 'val' as two ---- -==== +====== +===== - -.Create a database with an unescaped name containing a dot -==== +.Using the Unicode \u0085 in an unescaped identifier +[.tabbed-example] +===== +[.include-with-neo4j-code] +====== Query:: + [source,cypher] ---- -CREATE DATABASE foo.bar +RETURN 1 as my\u0085identifier ---- - Description of the returned code:: -Databases and aliases with unescaped `.` are deprecated unless to indicate that they belong to a composite database. -Names containing `.` should be escaped. (Name: `foo.bar`) +The Unicode character `\u0085` is deprecated for unescaped identifiers and will be considered as a whitespace character in the future. To continue using it, escape the identifier by adding backticks around the identifier `my\u0085identifier`. -Suggestions for improvement:: -If not intended for a composite database, escape the name with the character ```. +====== +[.include-with-GQLSTATUS-code] +====== +Query:: + [source,cypher] ---- -CREATE DATABASE `foo.bar` +RETURN 1 as my\u0085identifier ---- -==== - -.A procedure has been deprecated or renamed -==== -[source,cypher] ----- -CALL unsupported.dbms.shutdown ----- +Returned GQLSTATUS code:: +01N00 -Description of the returned code:: -The query used a deprecated procedure: `'unsupported.dbms.shutdown'`. +Returned status description:: +warn: feature deprecated. +The Unicode character `\u0085` is deprecated for unescaped identifiers and will be considered as a whitespace character in the future. +To continue using it, escape the identifier by adding backticks around the identifier `my\u0085identifier`. +====== +===== -Suggestions for improvement:: -Remove the use of the deprecated procedure. -If there is a suggested replacement, update to use the replacement instead. +[#_deprecated-feature-with-replacement] +=== Feature deprecated with a replacement -==== +.Notification details +[cols="<1s,<4"] +|=== +|Neo4j code +m|Neo.ClientNotification.Statement.FeatureDeprecationWarning +|Title +a|This feature is deprecated and will be removed in future versions. +|Descriptions +a| +- The semantics of using colon in the separation of alternative relationship types will change in a future version. (%s) +- The use of nodes or relationships for setting properties is deprecated and will be removed in a future version. +Please use properties() instead. +- The use of shortestPath and allShortestPaths with fixed length relationships is deprecated and will be removed in a future version. +Please use a path with a length of 1 [r*1..1] instead or a Match with a limit. +- The query used a deprecated function. (%s) +- The query used a deprecated procedure. (%s) +- The query used a deprecated runtime option. (%s) +- The `TextIndexProvider.DESCRIPTOR.name()` provider for text indexes is deprecated and will be removed in a future version. +Please use `TrigramIndexProvider.DESCRIPTOR.name()` instead. +|Category +m|DEPRECATION +|GQLSTATUS code +m|01N01 +|Status description +a|warn: feature deprecated with replacement. +`$thing1` is deprecated. +It is replaced by `$thing2`. +|Classification +m|DEPRECATION +|SeverityLevel +m|WARNING +|=== -.Using a deprecated runtime option -==== +.Colon after the vertical bar `|:` in a relationship pattern +[.tabbed-example] +===== +[.include-with-neo4j-code] +====== Query:: + [source,cypher] ---- -CYPHER runtime = interpreted MATCH (n) RETURN n +MATCH (a)-[:A|:B|:C]-() RETURN * ---- Description of the returned code:: -The query used a deprecated runtime option. (`'runtime=interpreted'` is deprecated, please use `'runtime=slotted'` instead) +The semantics of using colon in the separation of alternative relationship types will change in a future version. (Please use ':A|B|C' instead) Suggestions for improvement:: -Runtime `interpreted` is deprecated, use another runtime or remove the runtime option to use the default runtime. +Remove the colon inside the relationship type expression. + [source,cypher] ---- -MATCH (n) RETURN n +MATCH (a)-[:A|B|C]-() RETURN * ---- -==== -.Using the `text-1.0` index provider when creating a text index -==== +====== +[.include-with-GQLSTATUS-code] +====== Query:: + [source,cypher] ---- -CREATE TEXT INDEX FOR (n:Label) ON (n.prop) OPTIONS {indexProvider : 'text-1.0'} +MATCH (a)-[:A|:B|:C]-() RETURN * ---- -Description of the returned code:: -The `text-1.0` provider for text indexes is deprecated and will be removed in a future version. -Please use `text-2.0` instead. +Returned GQLSTATUS code:: +01N01 + +Returned status description:: +warn: feature deprecated with replacement. +`:A|:B|:C` is deprecated. +It is replaced by `:A|B|C`. Suggestions for improvement:: -Update the option `indexProvider` with the value `text-2.0`. +Remove the colon inside the relationship type expression. + [source,cypher] ---- -CREATE TEXT INDEX FOR (n:Label) ON (n.prop) OPTIONS {indexProvider : 'text-2.0'} +MATCH (a)-[:A|B|C]-() RETURN * ---- -==== -.Using differently ordered return items in a `UNION` clause -==== +====== +===== + +.Setting properties using a node +[.tabbed-example] +===== +[.include-with-neo4j-code] +====== Query:: + [source,cypher] ---- -RETURN 'val' as one, 'val' as two -UNION -RETURN 'val' as two, 'val' as one +MATCH (a)-[]-(b) +SET a = b ---- Description of the returned code:: -All subqueries in a UNION [ALL] should have the same ordering for the return columns. -Using differently ordered return items in a UNION [ALL] clause is deprecated and will be removed in a future version. +The use of nodes or relationships for setting properties is deprecated and will be removed in a future version. +Please use `properties()` instead. Suggestions for improvement:: -Use the same order for the return columns in all subqueries combined by a `UNION` clause. +Use the `properties()` function to get all properties from `b`. ++ +[source,cypher] +---- +MATCH (a)-[]-(b) +SET a = properties(b) +---- +====== +[.include-with-GQLSTATUS-code] +====== +Query:: + [source,cypher] ---- -RETURN 'val' as one, 'val' as two -UNION -RETURN 'val' as one, 'val' as two +MATCH (a)-[]-(b) +SET a = b ---- -==== + +Returned GQLSTATUS code:: +01N01 + +Returned status description:: +warn: feature deprecated with replacement. +`SET a = b` is deprecated. +It is replaced by `SET a = properties(b)`. + +Suggestions for improvement:: +Use the `properties()` function to get all properties from `b`. ++ +[source,cypher] +---- +MATCH (a)-[]-(b) +SET a = properties(b) +---- + +====== +===== + + +.Setting properties using a relationship +[.tabbed-example] +===== +[.include-with-neo4j-code] +====== +Query:: ++ +[source,cypher] +---- +MATCH (a)-[r]-(b) +SET a += r +---- + +Description of the returned code:: +The use of nodes or relationships for setting properties is deprecated and will be removed in a future version. +Please use `properties()` instead. + +Suggestions for improvement:: +Use the `properties()` function to get all properties from `r`. ++ +[source,cypher] +---- +MATCH (a)-[r]-(b) +SET a += properties(r) +---- + +====== +[.include-with-GQLSTATUS-code] +====== +Query:: ++ +[source,cypher] +---- +MATCH (a)-[r]-(b) +SET a += r +---- + +Returned GQLSTATUS code:: +01N01 + +Returned status description:: +warn: feature deprecated with replacement. +`SET a += r` is deprecated. +It is replaced by `SET a += properties(r)`. + +Suggestions for improvement:: +Use the `properties()` function to get all properties from `r`. ++ +[source,cypher] +---- +MATCH (a)-[r]-(b) +SET a += properties(r) +---- +====== +===== + + +.Shortest path with a fixed relationship length +[.tabbed-example] +===== +[.include-with-neo4j-code] +====== +Query:: ++ +[source,cypher] +---- +MATCH (a:Start), shortestPath((a)-[r]->()) RETURN a +---- + +Description of the returned code:: +The use of `shortestPath` and `allShortestPaths` with fixed length relationships is deprecated and will be removed in a future version. +Please use a path with a length of `1 [r*1..1]` instead or a `Match` with a `limit`. + +Suggestions for improvement:: +If the relationship length is fixed, there is no reason to search for the shortest path. +Instead, you can rewrite it to the following: ++ +[source,cypher] +---- +MATCH (a: Start)-[r]->(b: End) RETURN b LIMIT 1 +---- + +====== +[.include-with-GQLSTATUS-code] +====== +Query:: ++ +[source,cypher] +---- +MATCH (a:Start), shortestPath((a)-[r]->()) RETURN a +---- + +Returned GQLSTATUS code:: +01N01 + +Returned status description:: +warn: feature deprecated with replacement. +`shortestPath\((a)-[r]->())` is deprecated. +It is replaced by `shortestPath\((n)-[r*1..1]->(m))`. + +Suggestions for improvement:: +If the relationship length is fixed, there is no reason to search for the shortest path. +Instead, you can rewrite it to the following: ++ +[source,cypher] +---- +MATCH (a: Start)-[r]->(b: End) RETURN b LIMIT 1 +---- +====== +===== + +.Using a deprecated runtime option +[.tabbed-example] +===== +[.include-with-neo4j-code] +====== +Query:: ++ +[source,cypher] +---- +CYPHER runtime = interpreted MATCH (n) RETURN n +---- + +Description of the returned code:: +The query used a deprecated runtime option. (`'runtime=interpreted'` is deprecated, please use `'runtime=slotted'` instead) + +Suggestions for improvement:: +Runtime `interpreted` is deprecated and another runtime is used instead. +Alternatively, you can remove the runtime option to use the default runtime. ++ +[source,cypher] +---- +MATCH (n) RETURN n +---- + +====== +[.include-with-GQLSTATUS-code] +====== +Query:: ++ +[source,cypher] +---- +CYPHER runtime = interpreted MATCH (n) RETURN n +---- + +Returned GQLSTATUS code:: +01N01 + +Returned status description:: +warn: feature deprecated with replacement. +`runtime=interpreted` is deprecated. +It is replaced by `runtime=slotted`. + +Suggestions for improvement:: +Runtime `interpreted` is deprecated and another runtime is used instead. +Alternatively, you can remove the runtime option to use the default runtime. ++ +[source,cypher] +---- +MATCH (n) RETURN n +---- +====== +===== + +.Using the `text-1.0` index provider when creating a text index +[.tabbed-example] +===== +[.include-with-neo4j-code] +====== +Query:: ++ +[source,cypher] +---- +CREATE TEXT INDEX FOR (n:Label) ON (n.prop) OPTIONS {indexProvider : 'text-1.0'} +---- + +Description of the returned code:: +The `text-1.0` provider for text indexes is deprecated and will be removed in a future version. +Please use `text-2.0` instead. + +Suggestions for improvement:: +Update the option `indexProvider` with the value `text-2.0`. ++ +[source,cypher] +---- +CREATE TEXT INDEX FOR (n:Label) ON (n.prop) OPTIONS {indexProvider : 'text-2.0'} +---- + +====== +[.include-with-GQLSTATUS-code] +====== +Query:: ++ +[source,cypher] +---- +CREATE TEXT INDEX FOR (n:Label) ON (n.prop) OPTIONS {indexProvider : 'text-1.0'} +---- + +Returned GQLSTATUS code:: +01N01 + +Returned status description:: +warn: feature deprecated with replacement. +`text-1.0` is deprecated. +It is replaced by `text-2.0`. + +Suggestions for improvement:: +Update the option `indexProvider` with the value `text-2.0`. ++ +[source,cypher] +---- +CREATE TEXT INDEX FOR (n:Label) ON (n.prop) OPTIONS {indexProvider : 'text-2.0'} +---- +====== +===== + +.Using a renamed or a deprecated procedure +[.tabbed-example] +===== +[.include-with-neo4j-code] +====== + +[source,cypher] +---- +CALL unsupported.dbms.shutdown +---- + +Description of the returned code:: +The query used a deprecated procedure: `'unsupported.dbms.shutdown'`. + +Suggestions for improvement:: +Remove the use of the deprecated procedure. +If there is a suggested replacement, update to use the replacement instead. + +====== +[.include-with-GQLSTATUS-deprecated-with-replacement] +====== +[source,cypher] +---- +CALL cdc.query +---- + +Returned GQLSTATUS code:: +01N01 + +Returned status description:: +warn: feature deprecated with replacement. +`cdc.query` is deprecated. +It is replaced by `db.cdc.query`. + +====== +[.include-with-GQLSTATUS-deprecated-without-replacement] +====== +[source,cypher] +---- +CALL unsupported.dbms.shutdown +---- + +Returned GQLSTATUS code:: +01N02 + +Returned status description:: +warn: feature deprecated without replacement. +`unsupported.dbms.shutdown` is deprecated and will be removed without a replacement. +====== +===== .Using id() function -==== +[.tabbed-example] +===== +[.include-with-neo4j-code] +====== + Query:: + [source,cypher] @@ -898,8 +1899,10 @@ Query:: MATCH (a) RETURN id(a) ---- + Description of the returned code:: The query used a deprecated function: `id`. + Suggestions for improvement:: Use the function `elementId()` instead. + @@ -908,10 +1911,88 @@ Use the function `elementId()` instead. MATCH (a) RETURN elementId(a) ---- -==== +====== +[.include-with-GQLSTATUS-deprecated-with-replacement] +====== +Query:: ++ +[source,cypher] +---- +MATCH (a) +RETURN id(a) +---- -.Using Cypher query option connectComponentsPlanner -==== +Returned GQLSTATUS code:: +01N01 + +Returned status description:: +warn: feature deprecated with replacement. +`id` is deprecated. +It is replaced by `elementId()`. + +Suggestions for improvement:: +Use the function `elementId()` instead. ++ +[source,cypher] +---- +MATCH (a) +RETURN elementId(a) +---- +====== +[.include-with-GQLSTATUS-deprecated-without-replacement] +====== +Query:: ++ +[source,cypher] +---- +MATCH (a) +RETURN id(a) +---- + +Returned GQLSTATUS code:: +01N02 + +Returned status description:: +warn: feature deprecated without replacement. +`id` is deprecated and will be removed without a replacement. +====== +===== + +[#_deprecated-notifications-without-replacement] +=== Deprecated features without a future replacement + +.Notification details +[cols="<1s,<4"] +|=== +|Neo4j code +m|Neo.ClientNotification.Statement.FeatureDeprecationWarning +|Title +a|This feature is deprecated and will be removed in future versions. +|Descriptions +a| +- The Cypher query option `connectComponentsPlanner` is deprecated and will be removed without a replacement. +The product's default behavior of using a cost-based IDP search algorithm when combining sub-plans will be kept. +For more information, see Cypher Manual -> Cypher planner. +- The query used a deprecated function%s +- The query used a deprecated procedure%s +|Category +m|DEPRECATION +|GQLSTATUS code +m|01N02 +|Status description +a|warn: feature deprecated without replacement. +`$thing` is deprecated and will be removed without a replacement. +|Classification +m|DEPRECATION +|SeverityLevel +m|WARNING +|=== + +.Using Cypher query option `connectComponentsPlanner` +[.tabbed-example] +===== +[.include-with-neo4j-code] +====== Query:: + [source,cypher] @@ -922,35 +2003,75 @@ Description of the returned code:: The Cypher query option `connectComponentsPlanner` is deprecated and will be removed without a replacement. The product's default behavior of using a cost-based IDP search algorithm when combining sub-plans will be kept. For more information, see link:https://neo4j.com/docs/cypher-manual/current/query-tuning/query-options/#cypher-planner[Cypher manual -> Cypher planner]. -==== -.Using the unicode \u0085 in an unescaped identifier -==== +====== +[.include-with-GQLSTATUS-code] +====== Query:: + [source,cypher] ---- -RETURN 1 as my\u0085identifier +CYPHER connectComponentsPlanner=greedy MATCH (a), (b) RETURN * ---- -Description of the returned code:: -The Unicode character \`\u0085` is deprecated for unescaped identifiers and will be considered as a whitespace character in the future. To continue using it, escape the identifier by adding backticks around the identifier \`my…identifier`. -==== -[#_neo_clientnotification_request_deprecatedformat] -=== DeprecatedFormat +Returned GQLSTATUS code:: +01N02 + +Returned status description:: +warn: feature deprecated without replacement. +`connectComponentsPlanner` is deprecated and will be removed without a replacement. +====== +===== +[[_deprecated-procedure-result-column]] +=== Procedure field deprecated .Notification details [cols="<1s,<4"] |=== -|Code -m|Neo.ClientNotification.Request.DeprecatedFormat +|Neo4j code +m|Neo.ClientNotification.Statement.FeatureDeprecationWarning |Title -a|The client requested a deprecated format. -|Severity +a|This feature is deprecated and will be removed in future versions. +|Description +a|The query used a deprecated field from a procedure. (%s) +|Category +m|DEPRECATION +|GQLSTATUS code +m|01N03 +|Status description +a|warn: procedure field deprecated. +`$field` for procedure `$proc` is deprecated. +|Classification +m|DEPRECATION +|SeverityLevel m|WARNING +|=== + +[#_neo_clientnotification_request_] +=== Feature deprecated with replacement - DeprecatedFormat + +.Notification details +[cols="<1s,<4"] +|=== +|Neo4j code +m|Neo.ClientNotification.Request.DeprecatedFormat +|Title +a|The client made a request for a format which has been deprecated. +|Description +|The requested format has been deprecated. (%s) |Category m|DEPRECATION +|GQLSTATUS code +m|01N01 +|Status description +a|warn: feature deprecated with replacement. +`$thing1` is deprecated. +It is replaced by `$thing2`. +|Classification +m|DEPRECATION +|SeverityLevel +m|WARNING |=== [#_security_notifications] @@ -960,44 +2081,59 @@ Security notifications indicate that the result of the query or command might ha Verify that this is the intended behavior of your query or command. [#_neo_clientnotification_security_commandhasnoeffect] -=== CommandHasNoEffect +=== Role or privilege not assigned .Notification details [cols="<1s,<4"] |=== -|Code +|Neo4j code m|Neo.ClientNotification.Security.CommandHasNoEffect |Title a|`` has no effect.* -|Severity -m|INFORMATION +|Descriptions +a| +- The user does not have the role. See Status Codes documentation for more information. +- The role does not have the privilege. See Status Codes documentation for more information. |Category m|SECURITY +|GQLSTATUS code +m|00N71 +|Status description +|note: successful completion - role or privilege not assigned. +`$cmd` has no effect. +The role or privilege is not assigned. +|Classification +m|SECURITY +|SeverityLevel +m|INFORMATION |=== -*_`` could be either the full command given by the user or a subset of the given command._ +*_```` and `cmd` could be either the full command given by the user or a subset of the given command._ -.Granting a role to a user who already has that role -==== + +.Revoking a role from a user who does not have that role +[.tabbed-example] +===== +[.include-with-neo4j-code] +====== Command:: + [source, cypher] ---- -GRANT ROLE admin TO john +REVOKE ROLE admin, reader FROM jane ---- -Full title of the returned code:: -`GRANT ROLE admin TO john` has no effect. +Title of the returned code:: +`REVOKE ROLE reader FROM jane` has no effect. Description of the returned code:: -The user already has the role. See Status Codes documentation for more information. +The user does not have the role. See Status Codes documentation for more information. Suggestions for improvement:: Verify that this is the intended role and user. -==== - -.Revoking a role from a user who does not have that role -==== +====== +[.include-with-GQLSTATUS-code] +====== Command:: + [source, cypher] @@ -1005,19 +2141,147 @@ Command:: REVOKE ROLE admin, reader FROM jane ---- -Full title of the returned code:: +Returned GQLSTATUS code:: +00N71 + +Returned status description:: +note: successful completion - role or privilege not assigned. `REVOKE ROLE reader FROM jane` has no effect. +The role or privilege is not assigned. + +Suggestions for improvement:: +Verify that this is the intended role and user. +====== +===== + +.Revoking a privilege from a role that does not have that privilege +[.tabbed-example] +===== +[.include-with-neo4j-code] +====== +Command:: ++ +[source, cypher] +---- +REVOKE WRITE ON GRAPH * FROM reader +---- + +Title of the returned code:: +`REVOKE DENY WRITE ON GRAPH * FROM reader` has no effect. Description of the returned code:: -The user does not have the role. See Status Codes documentation for more information. +The role does not have the privilege. See Status Codes documentation for more information. + +Suggestions for improvement:: +Verify that this is the intended privilege and role. +====== +[.include-with-GQLSTATUS-code] +====== + +Command:: ++ +[source, cypher] +---- +REVOKE WRITE ON GRAPH * FROM reader +---- + +Returned GQLSTATUS code:: +00N71 + +Returned status description:: +note: successful completion - role or privilege not assigned. +`REVOKE DENY WRITE ON GRAPH * FROM reader` has no effect. +The role or privilege is not assigned. + +Suggestions for improvement:: +Verify that this is the intended privilege and role. + +====== +===== + + +[#_neo_clientnotification_security_roleorprivilegealreadyassigned] +=== Role or privilege already assigned + +.Notification details +[cols="<1s,<4"] +|=== +|Neo4j code +m|Neo.ClientNotification.Security.CommandHasNoEffect +|Title +a|`` has no effect.* +|Descriptions +a| +- The user already has the role. See Status Codes documentation for more information. +- The role already has the privilege. See Status Codes documentation for more information. +|Category +m|SECURITY +|GQLSTATUS code +m|00N70 +|Status description +|note: successful completion - role or privilege already assigned. +`$cmd` has no effect. +The role or privilege is already assigned. +|Classification +m|SECURITY +|SeverityLevel +m|INFORMATION +|=== + +*_```` and `cmd` could be either the full command given by the user or a subset of the given command._ + + +.Granting a role to a user who already has that role +[.tabbed-example] +===== +[.include-with-neo4j-code] +====== +Command:: ++ +[source,cypher] +---- +GRANT ROLE admin TO john +---- +Title of the returned code:: +`GRANT ROLE admin TO john` has no effect. + +Description of the returned code:: +The user already has the role. See Status Codes documentation for more information. Suggestions for improvement:: Verify that this is the intended role and user. -==== + +====== +[.include-with-GQLSTATUS-code] +====== +Command:: ++ +[source,cypher] +---- +GRANT ROLE admin TO john +---- + +Returned GQLSTATUS code:: +00N70 + +Returned status description:: +note: successful completion - role or privilege already assigned. +`GRANT ROLE admin TO john` has no effect. +The role or privilege is already assigned. + +Suggestions for improvement:: +Verify that this is the intended role and user. + +====== +===== + .Granting or denying a privilege to a role that already has that privilege -==== // This command returns 2 notifications, one for NODES and one for RELATIONSHIPS. +[.tabbed-example] +===== +[.include-with-neo4j-code] +====== Command:: + [source, cypher] @@ -1025,7 +2289,7 @@ Command:: GRANT TRAVERSE ON GRAPH * TO reader ---- -Full title of the returned code:: +Title of the returned code:: `GRANT TRAVERSE ON GRAPH * NODE * TO reader` has no effect. Description of the returned code:: @@ -1033,68 +2297,135 @@ The role already has the privilege. See Status Codes documentation for more info Suggestions for improvement:: Verify that this is the intended privilege and role. -==== -.Revoking a privilege from a role that does not have that privilege -==== +====== +[.include-with-GQLSTATUS-code] +====== Command:: + [source, cypher] ---- -REVOKE WRITE ON GRAPH * FROM reader +GRANT TRAVERSE ON GRAPH * TO reader ---- -Full title of the returned code:: -`REVOKE DENY WRITE ON GRAPH * FROM reader` has no effect. +Returned GQLSTATUS code:: +00N70 -Description of the returned code:: -The role does not have the privilege. See Status Codes documentation for more information. +Returned status description:: +note: successful completion - role or privilege already assigned. +`GRANT TRAVERSE ON GRAPH * TO reader` has no effect. +The role or privilege is already assigned. Suggestions for improvement:: Verify that this is the intended privilege and role. -==== +====== +===== + + [#_neo_clientnotification_security_impossiblerevokecommand] -=== ImpossibleRevokeCommand +=== Impossible revoke command .Notification details [cols="<1s,<4"] |=== -|Code +|Neo4j code m|Neo.ClientNotification.Security.ImpossibleRevokeCommand |Title a|`` has no effect.* -|Severity -m|WARNING +|Description +|Role does not exist. Make sure nothing is misspelled. +This notification will become an error in a future major version. +See Status Codes documentation for more information. |Category m|SECURITY +|GQLSTATUS code +m|01N70 +|Status description +a|warn: impossible revoke command. `cmd` has no effect. $msg +Make sure nothing is misspelled. +This notification will become an error in a future major version. +|Classification +m|SECURITY +|SeverityLevel +m|WARNING |=== -*_`` could be either the full command given by the user or a subset of the given command._ +*_```` and `cmd` could be either the full command given by the user or a subset of the given command._ .Revoking a non-existing role from a user -==== +[.tabbed-example] +===== +[.include-with-neo4j-code] +====== +Command:: ++ +[source, cypher] +---- +REVOKE ROLE manager, reader FROM jane +---- + +Title of the returned code:: +`REVOKE ROLE manager FROM jane` has no effect. + +Description of the returned code:: +Role does not exist. Make sure nothing is misspelled. +This notification will become an error in a future major version. +See Status Codes documentation for more information. + +Suggestions for improvement:: +Verify that this is the intended role and that it is spelled correctly. +====== +[.include-with-GQLSTATUS-code] +====== +Command:: ++ +[source, cypher] +---- +REVOKE ROLE manager, reader FROM jane +---- + +Returned GQLSTATUS code:: +01N70 + +Returned status description:: +warn: impossible revoke command. +`REVOKE ROLE manager FROM jane` has no effect. +Role does not exist. +Make sure nothing is misspelled. +This notification will become an error in a future major version. + +Suggestions for improvement:: +Verify that this is the intended role and that it is spelled correctly. +====== +===== + +.Revoking a role from a non-existing user +[.tabbed-example] +===== +[.include-with-neo4j-code] +====== Command:: + [source, cypher] ---- -REVOKE ROLE manager, reader FROM jane +REVOKE ROLE reader FROM alice ---- -Full title of the returned code:: -`REVOKE ROLE manager FROM jane` has no effect. +Title of the returned code:: +`REVOKE ROLE reader FROM alice` has no effect. Description of the returned code:: -Role does not exist. Make sure nothing is misspelled. +User does not exist. +Make sure nothing is misspelled. This notification will become an error in a future major version. -See Status Codes documentation for more information. Suggestions for improvement:: -Verify that this is the intended role and that it is spelled correctly. -==== +Verify that this is the intended user and that it is spelled correctly. +====== +[.include-with-GQLSTATUS-code] +====== -.Revoking a role from a non-existing user -==== Command:: + [source, cypher] @@ -1102,20 +2433,28 @@ Command:: REVOKE ROLE reader FROM alice ---- -Full title of the returned code:: -`REVOKE ROLE reader FROM alice` has no effect. +Returned GQLSTATUS code:: +01N70 -Description of the returned code:: -User does not exist. Make sure nothing is misspelled. +Returned status description:: +warn: impossible revoke command. +`REVOKE ROLE reader FROM alice` has no effect. +User does not exist. +Make sure nothing is misspelled. This notification will become an error in a future major version. See Status Codes documentation for more information. - +o Suggestions for improvement:: Verify that this is the intended user and that it is spelled correctly. -==== +====== +===== + .Revoking a privilege from a non-existing role -==== +[.tabbed-example] +===== +[.include-with-neo4j-code] +====== Command:: + [source, cypher] @@ -1123,7 +2462,7 @@ Command:: REVOKE GRANT WRITE ON GRAPH * FROM manager ---- -Full title of the returned code:: +Title of the returned code:: `REVOKE GRANT WRITE ON GRAPH * FROM manager` has no effect. Description of the returned code:: @@ -1133,10 +2472,37 @@ See Status Codes documentation for more information. Suggestions for improvement:: Verify that this is the intended role and that it is spelled correctly. -==== +====== +[.include-with-GQLSTATUS-code] +====== + +Command:: ++ +[source, cypher] +---- +REVOKE GRANT WRITE ON GRAPH * FROM manager +---- + +Returned GQLSTATUS code:: +01N70 + +Returned status description:: +warn: impossible revoke command. +`REVOKE GRANT WRITE ON GRAPH * FROM manager` has no effect. +Role does not exist. +Make sure nothing is misspelled. +This notification will become an error in a future major version. + +Suggestions for improvement:: +Verify that this is the intended role and that it is spelled correctly. +====== +===== .Revoking a privilege on a non-existing graph from a role -==== +[.tabbed-example] +===== +[.include-with-neo4j-code] +====== Command:: + [source, cypher] @@ -1144,24 +2510,46 @@ Command:: REVOKE GRANT WRITE ON GRAPH neo3j FROM editor ---- -Full title of the returned code:: +Title of the returned code:: `REVOKE GRANT WRITE ON GRAPH neo3j FROM editor` has no effect. Description of the returned code:: -// We use 'Database' here for multiple reasons -// - The user fixes the issue by doing 'create database', not 'create graph'. -// - This matches the existing behaviour when granting the privilege. -// - It is easier to implement this way. -Database 'neo3j' does not exist. Make sure nothing is misspelled. +Database `neo3j` does not exist. Make sure nothing is misspelled. This notification will become an error in a future major version. See Status Codes documentation for more information. Suggestions for improvement:: Verify that this is the intended graph and that it is spelled correctly. -==== +====== +[.include-with-GQLSTATUS-code] +====== +Command:: ++ +[source, cypher] +---- +REVOKE GRANT WRITE ON GRAPH neo3j FROM editor +---- + +Returned GQLSTATUS code:: +01N70 + +Returned status description:: +warn: impossible revoke command. +`REVOKE GRANT WRITE ON GRAPH neo3j FROM editor` has no effect. +Database `neo3j` does not exist. +Make sure nothing is misspelled. +This notification will become an error in a future major version. + +Suggestions for improvement:: +Verify that this is the intended graph and that it is spelled correctly. +====== +===== .Revoking a privilege on a non-existing database from a role -==== +[.tabbed-example] +===== +[.include-with-neo4j-code] +====== Command:: + [source, cypher] @@ -1169,20 +2557,48 @@ Command:: REVOKE GRANT ACCESS ON DATABASE neo3j FROM editor ---- -Full title of the returned code:: +Title of the returned code:: `REVOKE GRANT ACCESS ON DATABASE neo3j FROM editor` has no effect. Description of the returned code:: -Database 'neo3j' does not exist. Make sure nothing is misspelled. +Database `neo3j` does not exist. Make sure nothing is misspelled. This notification will become an error in a future major version. See Status Codes documentation for more information. Suggestions for improvement:: Verify that this is the intended database and that it is spelled correctly. -==== +====== +[.include-with-GQLSTATUS-code] +====== +Command:: ++ +[source, cypher] +---- +REVOKE GRANT ACCESS ON DATABASE neo3j FROM editor +---- + +Returned GQLSTATUS code:: +01N70 + +Returned status description:: +warn: impossible revoke command. +`REVOKE GRANT ACCESS ON DATABASE neo3j FROM editor` has no effect. +Database `neo3j` does not exist. +Make sure nothing is misspelled. +This notification will become an error in a future major version. + +Suggestions for improvement:: +Verify that this is the intended database and that it is spelled correctly. + +====== +===== + .Revoking a privilege from a role with wildcard graph parameter -==== +[.tabbed-example] +===== +[.include-with-neo4j-code] +====== Parameter:: + [source, javascript] @@ -1198,7 +2614,7 @@ Command:: REVOKE GRANT CREATE ON GRAPH $graph FROM PUBLIC ---- -Full title of the returned code:: +Title of the returned code:: `REVOKE GRANT CREATE ON GRAPH $graph FROM PUBLIC` has no effect. Description of the returned code:: @@ -1209,10 +2625,46 @@ See Status Codes documentation for more information. Suggestions for improvement:: Use `GRAPH *` without the parameter to revoke the privilege on all graphs. -==== +====== +[.include-with-GQLSTATUS-code] +====== +Parameter:: ++ +[source, javascript] +---- +{ + "graph": "*" +} +---- +Command:: ++ +[source, cypher] +---- +REVOKE GRANT CREATE ON GRAPH $graph FROM PUBLIC +---- -.Revoking a privilege from a role with wildcard database parameter -==== +Returned GQLSTATUS code:: +01N70 + +Returned status description:: +warn: impossible revoke command. +`REVOKE GRANT CREATE ON GRAPH $graph FROM PUBLIC` has no effect. +Database `*` does not exist. +Make sure nothing is misspelled. +This notification will become an error in a future major version. + +Suggestions for improvement:: +Use `GRAPH *` without the parameter to revoke the privilege on all graphs. + + +====== +===== + +.Revoking a privilege from a role with a wildcard database parameter +[.tabbed-example] +===== +[.include-with-neo4j-code] +====== Parameter:: + [source, javascript] @@ -1228,7 +2680,7 @@ Command:: REVOKE GRANT ACCESS ON DATABASE $database FROM PUBLIC ---- -Full title of the returned code:: +Title of the returned code:: `REVOKE GRANT ACCESS ON DATABASE $database FROM PUBLIC` has no effect. Description of the returned code:: @@ -1239,69 +2691,211 @@ See Status Codes documentation for more information. Suggestions for improvement:: Use `DATABASE *` without the parameter to revoke the privilege on all databases. -==== +====== +[.include-with-GQLSTATUS-code] +====== + +Parameter:: ++ +[source, javascript] +---- +{ + "database": "*" +} +---- +Command:: ++ +[source, cypher] +---- +REVOKE GRANT ACCESS ON DATABASE $database FROM PUBLIC +---- + +Returned GQLSTATUS code:: +01N70 + +Returned status description:: +warn: impossible revoke command. +`REVOKE GRANT ACCESS ON DATABASE $database FROM PUBLIC` has no effect. +Database `*` does not exist. +Make sure nothing is misspelled. +This notification will become an error in a future major version. + +Suggestions for improvement:: +Use `DATABASE *` without the parameter to revoke the privilege on all databases. + +====== +===== [#_topology_notifications] == `TOPOLOGY` category Topology notifications provide additional information related to managing databases and servers. -[#_neo_clientnotification_cluster_cordonedserversexistedduringallocation] -=== CordonedServersExistedDuringAllocation +[#_neo_clientnotification_cluster_serveralreadyenabled] +=== Server already enabled -.When is this notification returned? -[TIP] -==== -When a Cypher administration command triggers an allocation decision and some of the servers are cordoned. -For example, `CREATE DATABASE`, `ALTER DATABASE`, `DEALLOCATE DATABASES FROM SERVER[S]`, and `ALTER DATABASE` return this notification. However, `REALLOCATE DATABASES` requires that there are no cordoned servers and, therefore, does not return it. -==== .Notification details [cols="<1s,<4"] |=== -|Code -m|Neo.ClientNotification.Cluster.CordonedServersExistedDuringAllocation +|Neo4j code +m|Neo.ClientNotification.Cluster.ServerAlreadyEnabled |Title -a| Cordoned servers existed when making an allocation decision. -|Severity -m|INFORMATION +a| `` has no effect. +|Description +a|Server `%s` is already enabled. +Verify that this is the intended server. |Category m|TOPOLOGY +|GQLSTATUS code +m|00N80 +|Status description +a|note: successful completion - server already enabled. +`ENABLE SERVER` has no effect. +Server `$server` is already enabled. +Verify that this is the intended server. +|Classification +m|TOPOLOGY +|SeverityLevel +m|INFORMATION |=== -.Cordoned servers existed during an allocation decision -==== -The example assumes that you have a cluster with three servers, of which server `123e4567-e89b-12d3-a456-426614174000` is cordoned using the `dbms.cluster.cordonServer` procedure. Then the below command will return this notification. +.Enabling an already enabled server +[.tabbed-example] +===== +[.include-with-neo4j-code] +====== +Command:: ++ +[source, cypher] +---- +ENABLE SERVER "123e4567-e89b-12d3-a456-426614174000" +---- + +Description of the returned code:: +Server `123e4567-e89b-12d3-a456-426614174000` is already enabled. +Verify that this is the intended server. +====== +[.include-with-GQLSTATUS-code] +====== Command:: + [source, cypher] ---- -CREATE DATABASE foo TOPOLOGY 2 PRIMARIES +ENABLE SERVER "123e4567-e89b-12d3-a456-426614174000" +---- + +Returned GQLSTATUS code:: +00N80 + +Returned status description:: +note: successful completion - server already enabled. +`ENABLE SERVER` has no effect. +Server `123e4567-e89b-12d3-a456-426614174000` is already enabled. +Verify that this is the intended server. + +====== +===== + +[#_neo_clientnotification_cluster_serveralreadycordoned] +=== Server already cordoned + +.Notification details +[cols="<1s,<4"] +|=== +|Neo4j code +m|Neo.ClientNotification.Cluster.ServerAlreadyCordoned +|Title +a| `` has no effect. +|Description +a|Server `%s` is already cordoned. +Verify that this is the intended server. +|Category +m|TOPOLOGY +|GQLSTATUS code +m|00N81 +|Status description +a|note: successful completion - server already cordoned. +`CORDON SERVER` has no effect. +Server `$server` is already cordoned. +Verify that this is the intended server. +|Classification +m|TOPOLOGY +|SeverityLevel +m|INFORMATION +|=== + +.Cordoning an already cordoned server +[.tabbed-example] +===== +[.include-with-neo4j-code] +====== +Command:: ++ +[source, cypher] +---- +CORDON SERVER "123e4567-e89b-12d3-a456-426614174000" ---- Description of the returned code:: -Server(s) `123e4567-e89b-12d3-a456-426614174000` are cordoned. This can impact allocation decisions. -==== +Server `123e4567-e89b-12d3-a456-426614174000` is already cordoned. +Verify that this is the intended server. + +====== +[.include-with-GQLSTATUS-code] +====== +Command:: ++ +[source, cypher] +---- +CORDON SERVER "123e4567-e89b-12d3-a456-426614174000" +---- + +Returned GQLSTATUS code:: +00N81 + +Returned status description:: +note: successful completion - server already cordoned. +`CORDON SERVER` has no effect. +Server `123e4567-e89b-12d3-a456-426614174000` is already cordoned. +Verify that this is the intended server. + +====== +===== [#_neo_clientnotification_cluster_nodatabasesreallocated] -=== NoDatabasesReallocated +=== No databases reallocated .Notification details [cols="<1s,<4"] |=== -|Code +|Neo4j code m|Neo.ClientNotification.Cluster.NoDatabasesReallocated |Title a| `` has no effect. -|Severity -m|INFORMATION +|Description +a| No databases were reallocated. No better allocation is currently possible. |Category m|TOPOLOGY +|GQLSTATUS code +m|00N82 +|Status description +a|note: successful completion - no databases reallocated. +`REALLOCATE DATABASES` has no effect. +No databases were reallocated. +No better allocation is currently possible. +|Classification +m|TOPOLOGY +|SeverityLevel +m|INFORMATION |=== .Reallocating databases resulted in no allocation changes -==== +[.tabbed-example] +===== +[.include-with-neo4j-code] +====== Command:: + [source, cypher] @@ -1318,30 +2912,143 @@ Example scenarios:: For example, when there are three servers, each hosting databases `foo` and `bar`, meaning all databases are allocated to all servers. + -**Scenario 2:** The cluster appears unbalanced, but server constraints prevent you from moving to a better, more balanced, allocation. -For example, assuming server 1 hosts databases `foo` and `bar`, server 2 hosts only `foo`, and server 3 hosts no databases. -Then, a better allocation would move `foo` from server 1 to server 3, but if server 3 has the constraint `deniedDatabases:['foo']}`, then the cluster is already balanced subject to this constraint. -==== +**Scenario 2:** The cluster appears unbalanced, but server constraints prevent you from moving to a better, more balanced, allocation. +For example, assuming server 1 hosts databases `foo` and `bar`, server 2 hosts only `foo`, and server 3 hosts no databases. +Then, a better allocation would move `foo` from server 1 to server 3, but if server 3 has the constraint `deniedDatabases:['foo']}`, then the cluster is already balanced subject to this constraint. +====== +[.include-with-GQLSTATUS-code] +====== +Command:: ++ +[source, cypher] +---- +REALLOCATE DATABASES +---- + +Returned GQLSTATUS code:: +00N82 + +Returned status description:: +note: successful completion - no databases reallocated. +`REALLOCATE DATABASES` has no effect. +No databases were reallocated. +No better allocation is currently possible. + +Example scenarios:: +**Scenario 1:** The cluster is already balanced. +For example, when there are three servers, each hosting databases `foo` and `bar`, meaning all databases are allocated to all servers. ++ + +**Scenario 2:** The cluster appears unbalanced, but server constraints prevent you from moving to a better, more balanced, allocation. +For example, assuming server 1 hosts databases `foo` and `bar`, server 2 hosts only `foo`, and server 3 hosts no databases. +Then, a better allocation would move `foo` from server 1 to server 3, but if server 3 has the constraint `deniedDatabases:['foo']}`, then the cluster is already balanced subject to this constraint. +====== +===== + +[#_neo_clientnotification_cluster_cordonedserversexistedduringallocation] +=== Cordoned servers existed during allocation + +This notification is returned when a Cypher administration command triggers an allocation decision and some of the servers are cordoned. +For example, `CREATE DATABASE`, `ALTER DATABASE`, `DEALLOCATE DATABASES FROM SERVER[S]`, and `ALTER DATABASE` return this notification. However, `REALLOCATE DATABASES` requires that there are no cordoned servers and, therefore, does not return it. + +.Notification details +[cols="<1s,<4"] +|=== +|Neo4j code +m|Neo.ClientNotification.Cluster.CordonedServersExistedDuringAllocation +|Title +a| Cordoned servers existed when making an allocation decision. +|Description +a| Server(s) `%s` are cordoned. This can impact allocation decisions. +|Category +m|TOPOLOGY +|GQLSTATUS code +m|00N83 +|Status description +a|note: successful completion - cordoned servers existed during allocation. +Cordoned servers existed when making an allocation decision. +Server(s) `$server_list` are cordoned. +This can impact allocation decisions. +|Classification +m|TOPOLOGY +|SeverityLevel +m|INFORMATION +|=== + +.Cordoned servers existed during an allocation decision +[.tabbed-example] +===== +[.include-with-neo4j-code] +====== +The example assumes that you have a cluster with three servers, of which server `123e4567-e89b-12d3-a456-426614174000` is cordoned using the `dbms.cluster.cordonServer` procedure. Then the below command will return this notification. + +Command:: ++ +[source, cypher] +---- +CREATE DATABASE foo TOPOLOGY 2 PRIMARIES +---- + +Description of the returned code:: +Server(s) `123e4567-e89b-12d3-a456-426614174000` are cordoned. This can impact allocation decisions. +====== +[.include-with-GQLSTATUS-code] +====== +The example assumes that you have a cluster with three servers, of which server `123e4567-e89b-12d3-a456-426614174000` is cordoned using the `dbms.cluster.cordonServer` procedure. Then the below command will return this notification. + +Command:: ++ +[source, cypher] +---- +CREATE DATABASE foo TOPOLOGY 2 PRIMARIES +---- + +Returned GQLSTATUS code:: +00N83 + +Returned status description:: +note: successful completion - cordoned servers existed during allocation. +Cordoned servers existed when making an allocation decision. +Server(s) `123e4567-e89b-12d3-a456-426614174000` are cordoned. +This can impact allocation decisions. +====== +===== + [#_neo_clientnotification_cluster_requestedtopologymatchedcurrenttopology] -=== RequestedTopologyMatchedCurrentTopology +=== Requested topology matched current topology .Notification details [cols="<1s,<4"] |=== -|Code +|Neo4j code m|Neo.ClientNotification.Cluster.RequestedTopologyMatchedCurrentTopology |Title a| `` has no effect. -|Severity -m|INFORMATION +|Description +a|The requested topology matched the current topology. +No allocations were changed. |Category m|TOPOLOGY +|GQLSTATUS code +m|00N84 +|Status description +a|note: successful completion - requested topology matched current topology. +`ALTER DATABASE` has no effect. +The requested topology matched the current topology. +No allocations were changed. +|Classification +m|TOPOLOGY +|SeverityLevel +m|INFORMATION |=== -.Requested topology matched current topology -==== -The example assumes that you have a cluster with three servers and a database `foo` with a topology of two primaries and one secondary. +.Requested topology matched current topology +[.tabbed-example] +===== +[.include-with-neo4j-code] +====== +The example assumes that you have a cluster with three servers and a database `foo` with a topology of two primaries and one secondary. Command:: + @@ -1352,39 +3059,29 @@ ALTER DATABASE foo SET TOPOLOGY 2 PRIMARIES 1 SECONDARY Description of the returned code:: The requested topology matched the current topology. No allocations were changed. -==== - - -[#_neo_clientnotification_cluster_serveralreadyenabled] -=== ServerAlreadyEnabled - -.Notification details -[cols="<1s,<4"] -|=== -|Code -m|Neo.ClientNotification.Cluster.ServerAlreadyEnabled -|Title -a| `` has no effect. -|Severity -m|INFORMATION -|Category -m|TOPOLOGY -|=== +====== +[.include-with-GQLSTATUS-code] +====== +The example assumes that you have a cluster with three servers and a database `foo` with a topology of two primaries and one secondary. -.Enabling an already enabled server -==== Command:: + [source, cypher] ---- -ENABLE SERVER "123e4567-e89b-12d3-a456-426614174000" +ALTER DATABASE foo SET TOPOLOGY 2 PRIMARIES 1 SECONDARY ---- -Description of the returned code:: -Server `123e4567-e89b-12d3-a456-426614174000` is already enabled. -Verify that this is the intended server. +Returned GQLSTATUS code:: +00N84 -==== +Returned status description:: +note: successful completion - requested topology matched current topology. +`ALTER DATABASE` has no effect. +The requested topology matched the current topology. +No allocations were changed. + +====== +===== [#_schema_notifications] == `SCHEMA` category @@ -1392,25 +3089,38 @@ Verify that this is the intended server. Schema notifications provide additional information related to indexes and constraints. [#_neo_clientnotification_schema_indexorconstraintalreadyexists] -=== IndexOrConstraintAlreadyExists +=== Index or constraint already exists .Notification details [cols="<1s,<4"] |=== -|Code +|Neo4j code m|Neo.ClientNotification.Schema.IndexOrConstraintAlreadyExists |Title a|`` has no effect. |Description a|`` already exists. -|Severity -m|INFORMATION +|Description +a|`%s` already exists. |Category m|SCHEMA +|GQLSTATUS code +m|00NA0 +|Status description +a|note: successful completion - index or constraint already exists. +`$cmd` has no effect. +`$index_constr_pat` already exists. +|SeverityLevel +m|INFORMATION |=== +*_```` and `cmd` could be either the full command given by the user or a subset of the given command._ + .Creating an index when an equivalent index already exists -==== +[.tabbed-example] +===== +[.include-with-neo4j-code] +====== Given a range index on `(:Label \{property})` named `existingRangeIndex`. Command:: @@ -1420,16 +3130,40 @@ Command:: CREATE INDEX labelProperyRangeIndex IF NOT EXISTS FOR (n:Label) ON (n.property) ---- -Full title of the returned code:: +Title of the returned code:: `CREATE RANGE INDEX labelProperyRangeIndex IF NOT EXISTS FOR (e:Label) ON (e.property)` has no effect. Full description of the returned code:: `RANGE INDEX existingRangeIndex FOR (e:Label) ON (e.property)` already exists. -==== +====== +[.include-with-GQLSTATUS-code] +====== +Given a range index on `(:Label \{property})` named `existingRangeIndex`. + +Command:: ++ +[source, cypher] +---- +CREATE INDEX labelProperyRangeIndex IF NOT EXISTS FOR (n:Label) ON (n.property) +---- + +Returned GQLSTATUS code:: +00NA0 + +Returned status description:: +note: successful completion - index or constraint already exists. +`CREATE RANGE INDEX labelProperyRangeIndex IF NOT EXISTS FOR (e:Label) ON (e.property)` has no effect. +`RANGE INDEX existingRangeIndex FOR (e:Label) ON (e.property)` already exists. + +====== +===== .Creating an index when another unrelated index using that name already exists -==== +[.tabbed-example] +===== +[.include-with-neo4j-code] +====== Given a range index on `(:Label \{property})` named `myIndex`. Command:: @@ -1439,7 +3173,7 @@ Command:: CREATE TEXT INDEX myIndex IF NOT EXISTS FOR ()-[r:REL_TYPE]-() ON (r.property) ---- -Full title of the returned code:: +Title of the returned code:: `CREATE TEXT INDEX myIndex IF NOT EXISTS FOR ()-[e:REL_TYPE]-() ON (e.property)` has no effect. Full description of the returned code:: @@ -1453,10 +3187,42 @@ Choose a different name for the new index and try again. CREATE TEXT INDEX myIndex2 IF NOT EXISTS FOR ()-[r:REL_TYPE]-() ON (r.property) ---- -==== +====== +[.include-with-GQLSTATUS-code] +====== +Given a range index on `(:Label \{property})` named `myIndex`. + +Command:: ++ +[source, cypher] +---- +CREATE TEXT INDEX myIndex IF NOT EXISTS FOR ()-[r:REL_TYPE]-() ON (r.property) +---- + +Returned GQLSTATUS code:: +00NA0 + +Returned status description:: +note: successful completion - index or constraint already exists. +`CREATE TEXT INDEX myIndex IF NOT EXISTS FOR ()-[e:REL_TYPE]-() ON (e.property)` has no effect. +`RANGE INDEX myIndex FOR (e:Label) ON (e.property)` already exists. + +Suggestions for improvement:: +Choose a different name for the new index and try again. ++ +[source, cypher] +---- +CREATE TEXT INDEX myIndex2 IF NOT EXISTS FOR ()-[r:REL_TYPE]-() ON (r.property) +---- + +====== +===== .Creating a constraint when an identical constraint already exists -==== +[.tabbed-example] +===== +[.include-with-neo4j-code] +====== Given a node key constraint on `(:Label \{property})` named `nodeKeyLabelPropertyConstraint`. Command:: @@ -1466,16 +3232,41 @@ Command:: CREATE CONSTRAINT nodeKeyLabelPropertyConstraint IF NOT EXISTS FOR (n:Label) REQUIRE (n.property) IS NODE KEY ---- -Full title of the returned code:: +Title of the returned code:: `CREATE CONSTRAINT nodeKeyLabelPropertyConstraint IF NOT EXISTS FOR (e:Label) REQUIRE (e.property) IS NODE KEY` has no effect. Full description of the returned code:: `CONSTRAINT nodeKeyLabelPropertyConstraint FOR (e:Label) REQUIRE (e.property) IS NODE KEY` already exists. -==== +====== +[.include-with-GQLSTATUS-code] +====== +Given a node key constraint on `(:Label \{property})` named `nodeKeyLabelPropertyConstraint`. + +Command:: ++ +[source, cypher] +---- +CREATE CONSTRAINT nodeKeyLabelPropertyConstraint IF NOT EXISTS FOR (n:Label) REQUIRE (n.property) IS NODE KEY +---- + +Returned GQLSTATUS code:: +00NA0 + +Returned status description:: +note: successful completion - index or constraint already exists. +`CREATE CONSTRAINT nodeKeyLabelPropertyConstraint IF NOT EXISTS FOR (e:Label) REQUIRE (e.property) IS NODE KEY` has no effect. +`CONSTRAINT nodeKeyLabelPropertyConstraint FOR (e:Label) REQUIRE (e.property) IS NODE KEY` already exists. + +====== +===== + .Creating a constraint when another unrelated constraint using that name already exists -==== +[.tabbed-example] +===== +[.include-with-neo4j-code] +====== Given a node key constraint on `(:Label \{property})` named `myConstraint`. Command:: @@ -1485,7 +3276,7 @@ Command:: CREATE CONSTRAINT myConstraint IF NOT EXISTS FOR (n:Label2) REQUIRE (n.property2) IS NOT NULL ---- -Full title of the returned code:: +Title of the returned code:: `CREATE CONSTRAINT myConstraint IF NOT EXISTS FOR (e:Label2) REQUIRE (e.property2) IS NOT NULL` has no effect. Full description of the returned code:: @@ -1499,28 +3290,66 @@ Choose a different name for the new constraint and try again. CREATE CONSTRAINT myConstraint2 IF NOT EXISTS FOR (n:Label2) REQUIRE (n.property2) IS NOT NULL ---- -==== +====== +[.include-with-GQLSTATUS-code] +====== +Given a node key constraint on `(:Label \{property})` named `myConstraint`. + +Command:: ++ +[source, cypher] +---- +CREATE CONSTRAINT myConstraint IF NOT EXISTS FOR (n:Label2) REQUIRE (n.property2) IS NOT NULL +---- + +Returned GQLSTATUS code:: +00NA0 + +Returned status description:: +note: successful completion - index or constraint already exists. +`CREATE CONSTRAINT myConstraint IF NOT EXISTS FOR (e:Label2) REQUIRE (e.property2) IS NOT NULL` has no effect. +`CONSTRAINT myConstraint FOR (e:Label) REQUIRE (e.property) IS NODE KEY` already exists. + +Suggestions for improvement:: +Choose a different name for the new constraint and try again. ++ +[source, cypher] +---- +CREATE CONSTRAINT myConstraint2 IF NOT EXISTS FOR (n:Label2) REQUIRE (n.property2) IS NOT NULL +---- + +====== +===== [#_neo_clientnotification_schema_indexorconstraintdoesnotexist] -=== IndexOrConstraintDoesNotExist +=== Index or constraint does not exist .Notification details [cols="<1s,<4"] |=== -|Code +|Neo4j code m|Neo.ClientNotification.Schema.IndexOrConstraintDoesNotExist |Title a|`` has no effect. |Description -a|`` does not exist. -|Severity -m|INFORMATION +a|`%s` does not exist. |Category m|SCHEMA +|GQLSTATUS code +m|00NA1 +|Status description +a|note: successful completion - index or constraint does not exist. +`$cmd` has no effect. +`$index_constr_name` does not exist. +|SeverityLevel +m|INFORMATION |=== .Attempting to drop a non-existing index -==== +[.tabbed-example] +===== +[.include-with-neo4j-code] +====== Command:: + @@ -1529,7 +3358,7 @@ Command:: DROP INDEX nonExistingIndex IF EXISTS ---- -Full title of the returned code:: +Title of the returned code:: `DROP INDEX nonExistingIndex IF EXISTS` has no effect. Full description of the returned code:: @@ -1538,10 +3367,35 @@ Full description of the returned code:: Suggestions for improvement:: Verify that this is the intended index and that it is spelled correctly. -==== +====== +[.include-with-GQLSTATUS-code] +====== +Command:: ++ +[source, cypher] +---- +DROP INDEX nonExistingIndex IF EXISTS +---- + +Returned GQLSTATUS code:: +00NA1 + +Returned status description:: +note: successful completion - index or constraint does not exist. +`DROP INDEX nonExistingIndex IF EXISTS` has no effect. +`nonExistingIndex` does not exist. + +Suggestions for improvement:: +Verify that this is the intended index and that it is spelled correctly. + +====== +===== .Attempting to drop a non-existing constraint -==== +[.tabbed-example] +===== +[.include-with-neo4j-code] +====== Command:: + @@ -1550,7 +3404,7 @@ Command:: DROP CONSTRAINT nonExistingConstraint IF EXISTS ---- -Full title of the returned code:: +Title of the returned code:: `DROP CONSTRAINT nonExistingConstraint IF EXISTS` has no effect. Full description of the returned code:: @@ -1559,32 +3413,67 @@ Full description of the returned code:: Suggestions for improvement:: Verify that this is the intended constraint and that it is spelled correctly. -==== +====== +[.include-with-GQLSTATUS-code] +====== +Command:: ++ +[source, cypher] +---- +DROP CONSTRAINT nonExistingConstraint IF EXISTS +---- + +Returned GQLSTATUS code:: +00NA1 + +Returned status description:: +note: successful completion - index or constraint does not exist. +`DROP CONSTRAINT nonExistingConstraint IF EXISTS` has no effect. +`nonExistingConstraint` does not exist. +Suggestions for improvement:: +Verify that this is the intended constraint and that it is spelled correctly. + +====== +===== [#_generic] -== `GENERIC` category +== `GENERIC` notifications `GENERIC` notification codes do not belong to any wider category and do not have any connection to each other. [#_neo_clientnotification_statement_subqueryvariableshadowing] -=== SubqueryVariableShadowing +=== Subquery variable shadowing .Notification details [cols="<1s,<4"] |=== -|Code +|Neo4j code m|Neo.ClientNotification.Statement.SubqueryVariableShadowing |Title a|Variable in subquery is shadowing a variable with the same name from the outer scope. -|Severity -m|INFORMATION +|Description +|Variable in subquery is shadowing a variable with the same name from the outer scope. +If you want to use that variable instead, it must be imported into the subquery using importing WITH clause. (%s) |Category m|GENERIC +|GQLSTATUS code +m|03N60 +|Status description +a|info: subquery variable shadowing. +The variable `$var` in the subquery uses the same name as a variable from the outer query. +Use `WITH $var` in the subquery to import the one from the outer scope unless you want it to be a new variable. +|Classification +m|GENERIC +|SeverityLevel +m|INFORMATION |=== .Shadowing of a variable from the outer scope -==== +[.tabbed-example] +===== +[.include-with-neo4j-code] +====== Query:: + [source,cypher] @@ -1603,7 +3492,7 @@ If you want to use that variable instead, it must be imported into the subquery Suggestions for improvement:: If the intended behavior of the query is for the variable in the subquery to be a new variable, then nothing needs to be done. -If the intended behavior is to use the variable from the outer query, it needs to be imported to the subquery using the with clause. +If the intended behavior is to use the variable from the outer query, it needs to be imported to the subquery using the `WITH` clause. + [source,cypher] ---- @@ -1615,32 +3504,85 @@ CALL { } RETURN * ---- -==== +====== +[.include-with-GQLSTATUS-code] +====== +Query:: ++ +[source,cypher] +---- +MATCH (n) +CALL { + MATCH (n)--(m) + RETURN m +} +RETURN * +---- +Returned GQLSTATUS code:: +03N60 + +Returned status description:: +info: subquery variable shadowing. +The variable `n` in the subquery uses the same name as a variable from the outer query. +Use `WITH n` in the subquery to import the one from the outer scope unless you want it to be a new variable. + +Suggestions for improvement:: +If the intended behavior of the query is for the variable in the subquery to be a new variable, then nothing needs to be done. +If the intended behavior is to use the variable from the outer query, it needs to be imported to the subquery using the `WITH` clause. ++ +[source,cypher] +---- +MATCH (n) +CALL { + WITH n + MATCH (n)--(m) + RETURN m +} +RETURN * +---- +====== +===== [#_neo_clientnotification_statement_parameternotprovided] -=== ParameterNotProvided +=== Parameter missing .Notification details [cols="<1s,<4"] |=== -|Code +|Neo4j code m|Neo.ClientNotification.Statement.ParameterNotProvided |Title a|The statement refers to a parameter that was not provided in the request. -|Severity -m|WARNING +|Description +|Did not supply query with enough parameters. +The produced query plan will not be cached and is not executable without EXPLAIN. (%s) |Category m|GENERIC +|GQLSTATUS code +m|01N60 +|Status description +a|warn: parameter missing. +The query plan cannot be cached and is not executable without `EXPLAIN` due to the undefined parameter(s) `$param_list`. +Provide the parameter(s). +|Classification +m|GENERIC +|SeverityLevel +m|WARNING |=== + .Using an `EXPLAIN` query with parameters without providing them -==== +[.tabbed-example] +===== +[.include-with-neo4j-code] +====== Query:: + [source,cypher] ---- -EXPLAIN WITH $param as param RETURN param +EXPLAIN WITH $param as param +RETURN param ---- Description of the returned code:: @@ -1650,50 +3592,91 @@ The produced query plan will not be cached and is not executable without `EXPLAI Suggestions for improvement:: Provide the parameter to be able to cache the plan. -==== +====== +[.include-with-GQLSTATUS-code] +====== +Query:: ++ +[source,cypher] +---- +EXPLAIN WITH $param as param +RETURN param +---- + +Returned GQLSTATUS code:: +01N60 + +Returned status description:: +warn: parameter missing. +The query plan cannot be cached and is not executable without `EXPLAIN` due to the undefined parameter(s) `$param`. +Provide the parameter(s). + +Suggestions for improvement:: +Provide the parameter to be able to cache the plan. +====== +===== + [#_neo_clientnotification_procedure_procedurewarning] -=== ProcedureWarning +=== Procedure or function execution warning .Notification details [cols="<1s,<4"] |=== -|Code +|Neo4j code m|Neo.ClientNotification.Procedure.ProcedureWarning |Title a|The query used a procedure that generated a warning. -|Severity -m|WARNING +|Description +|The query used a procedure that generated a warning. (%s) |Category m|GENERIC +|GQLSTATUS code +m|01N62 +|Status description +a|warn: procedure execution warning. +The procedure `$proc` generates the warning `$msg`. +|Classification +m|GENERIC +|SeverityLevel +m|WARNING |=== -[#_neo_clientnotification_statement_unsatisfiablerelationshiptypeexpression] -=== UnsatisfiableRelationshipTypeExpression -label:introduced-in-Neo4j-5.4[Introduced in Neo4j 5.4] +[role=label--new-5.4] +[#_neo_clientnotification_statement_unsatisfiablerelationshiptypeexpression] +=== Unsatisfiable relationship type expression -.When is this notification returned? -[TIP] -==== When matching on a relationship type expression that can never be satisfied, for example asking for zero, more than one or contradictory types. -==== .Notification category details [cols="<1s,<4"] |=== -|Code +|Neo4j code m|Neo.ClientNotification.Statement.UnsatisfiableRelationshipTypeExpression |Title a|The query contains a relationship type expression that cannot be satisfied. -|Severity -m|WARNING +|Description +|Relationship type expression cannot possibly be satisfied. (%s) |Category m|GENERIC +|GQLSTATUS code +m|01N61 +|Status description +a|warn: unsatisfiable relationship type expression. +The expression `$label_expr` cannot be satisfied because relationships must have exactly one type. +|Classification +m|GENERIC +|SeverityLevel +m|WARNING |=== + .Matching on a relationship type expression that can never be satisfied -==== +[.tabbed-example] +===== +[.include-with-neo4j-code] +====== Query:: + [source,cypher] @@ -1702,28 +3685,59 @@ MATCH ()-[r:R1&R2]->() RETURN r ---- Description of the returned code:: Relationship type expression cannot possibly be satisfied. (`R1&R2` can never be fulfilled by any relationship. Relationships must have exactly one type.) -==== +====== +[.include-with-GQLSTATUS-code] +====== +Query:: ++ +[source,cypher] +---- +MATCH ()-[r:R1&R2]->() RETURN r +---- -[#_neo_clientnotification_statement_repeatedrelationshipreference] -=== RepeatedRelationshipReference +Returned GQLSTATUS code:: +01N61 + +Returned status description:: +warn: unsatisfiable relationship type expression. +The expression `R1&R2` cannot be satisfied because relationships must have exactly one type. +====== +===== -label:introduced-in-Neo4j-5.5[Introduced in Neo4j 5.5] +[role=label--new-5.5] +[#_neo_clientnotification_statement_repeatedrelationshipreference] +=== Repeated relationship reference .Notification category details [cols="<1s,<4"] |=== -|Code +|Neo4j code m|Neo.ClientNotification.Statement.RepeatedRelationshipReference |Title a|The query returns no results because a relationship variable is bound more than once. -|Severity -m|WARNING +|Description +a| +- A relationship is referenced more than once in the query, which leads to no results because relationships must not occur more than once in each result. (%s) +- A variable-length relationship variable is bound more than once, which leads to no results because relationships must not occur more than once in each result. (%s) |Category m|GENERIC +|GQLSTATUS code +m|01N63 +|Status description +a| +warn: repeated relationship reference. `$var` is repeated in `$pat`, which leads to no results. +|Classification +m|GENERIC +|SeverityLevel +m|WARNING |=== + .Binding a relationship variable more than once -==== +[.tabbed-example] +===== +[.include-with-neo4j-code] +====== Query:: + [source,cypher] @@ -1740,10 +3754,38 @@ Use one pattern to match all relationships that start with a node with the label ---- MATCH (:A)-[r]->(:B) RETURN r ---- -==== +====== +[.include-with-GQLSTATUS-code] +====== +Query:: ++ +[source,cypher] +---- +MATCH (:A)-[r]->(), ()-[r]->(:B) RETURN r +---- + +Returned GQLSTATUS code:: +01N63 + +Returned status description:: +warn: repeated relationship reference. +`r` is repeated in `(:A)-[r]->(), ()-[r]->(:B)`, which leads to no results. + +Suggestions for improvement:: +Use one pattern to match all relationships that start with a node with the label `A` and end with a node with the label `B`: ++ +[source, cypher, role="noplay"] +---- +MATCH (:A)-[r]->(:B) RETURN r +---- +====== +===== .Binding a variable-length relationship variable more than once (when run on version 5.6 or newer) -==== +[.tabbed-example] +===== +[.include-with-neo4j-code] +====== Query:: + [source,cypher] @@ -1751,5 +3793,24 @@ Query:: MATCH ()-[r*]->()<-[r*]-() RETURN count(*) AS count ---- Description of the returned code:: -A variable-length relationship variable is bound more than once, which leads to no results because relationships must not occur more than once in each result. (Relationship r was repeated) -==== +A variable-length relationship variable is bound more than once, which leads to no results because relationships must not occur more than once in each result. (Relationship `r` was repeated) + +====== +[.include-with-GQLSTATUS-code] +====== +Query:: ++ +[source,cypher] +---- +MATCH ()-[r*]->()<-[r*]-() RETURN count(*) AS count +---- + +Returned GQLSTATUS code:: +01N63 + +Returned status description:: +warn: repeated relationship reference. +`r` is repeated in `()-[r*]->()<-[r*]-()`, which leads to no results. +====== +===== + diff --git a/modules/ROOT/pages/notifications/index.adoc b/modules/ROOT/pages/notifications/index.adoc index 335eb74..60d7e86 100644 --- a/modules/ROOT/pages/notifications/index.adoc +++ b/modules/ROOT/pages/notifications/index.adoc @@ -1,35 +1,204 @@ :description: The Neo4j notifications for Neo4j version {neo4j-version}. [[notifications]] -= Notification codes += Server notifications -Notification codes are Neo4j status codes of type `ClientNotification` and are returned by the server with severity `WARNING` or `INFORMATION`. -Contrary to errors, notifications are only returned if the execution of the query is successful. +After a successful query execution, the Neo4j server sends notifications to provide advice on how to improve the query's quality or give additional information about the query execution. +The driver receives these notifications and sends them to the client, which displays them to the user. -[[notification-format]] -== Notification object fields +From version 5.23, Neo4j has a new GqlStatusObject API in addition to the existing Notification API. +The GqlStatusObject API provides information about the status of a Cypher query or command execution in compliance with the GQL standard. -The notification object, which is part of the result summary, consists of the following fields: +This page describes both the Neo4j Notification and the GQL-status object frameworks, how they are structured, the objects they provide for notifications, and how to interpret them. +It also explains the server notification grouping and filtering, the notification internals, and the server-driver compatibility for both the Notification and GqlStatusObject APIs. -* *Code* -- The Neo4j status code in the form of `Neo.ClientNotification.[SubType].[Name]`. -* *Title* -- The description of the Neo4j status code. -* *Description* -- The description of a specific notification, which can contain details about the query being executed. -* *Severity* -- The severity can be one of the following: + - ** `WARNING`: There might be a problem with your query. Please, take a look. + - ** `INFORMATION`: The query is correct, but this information can still be useful. -* *Category* -- The category of the notification. -* *Position* -- The position, given by row and column, where the notification is relevant in the query text. +[[neo4j-notification-object]] +== Neo4j notification object -[[notification-categories]] -== Notification code categories +The Neo4j notification object contains diagnostic information representing the successful outcome of a Cypher query or command execution, including severity, the `ClientNotification` code, category, title, description, and position in the query text where the notification is relevant. +Depending on the application, some of the fields from the notification object might not be visible. -All notifications are grouped by category, which can have severity `WARNING`, `WARNING OR INFORMATION`, or `INFORMATION`. +The notification object consists of the following fields: -The following categories exist, ordered by severity: +.Neo4j notification object +[cols="<1s,<4"] +|=== +|Neo4j code +a|The Neo4j status code in the form of `Neo.ClientNotification.[SubType].[Name]`. +|Title +a|The title of the Neo4j status code. +|Description +a|The description of the specific notification. +|Severity level +a|The severity can be one of the following: + +- `WARNING`: There might be a problem with your query. Please, take a look. +- `INFORMATION`: The query is correct, but this information can still be useful. +|Category +a|The category of the notification. +|Position +a|The position, given by row and column, where the notification is relevant in the query text. +|=== + + +[role=label--version-5.23] +[[gqlstatus-notification-object]] +== GQL-status notification object + +In the GQL-status object framework, notifications are an implementation-defined subset of the GQL-status objects that cover informational notes and warnings, but not errors, `SUCCESS`, `NO DATA`, or `OMITTED RESULT`. +For the latter, see <>. + + +In GQL, the execution of a query from user to server always has an outcome, called the _execution outcome_. +The execution outcome is a list of GQL-status objects, ordered by the following precedence, where the first object in the list is the primary GQL-status object: + +. `NO DATA` has precedence over `WARNING`. +. `WARNING` has precedence over the `SUCCESSFUL COMPLETION` subclass. +. `SUCCESSFUL COMPLETION` subclass has precedence over `INFORMATIONAL`. +. `INFORMATIONAL` is the condition with the least precedence. + +The primary GQL-status object describes the condition with the greatest precedence and is always present. +All other GQL-status objects in the list are additional GQL-status objects. + +The GQL-status object also includes the Neo4j-specific information, such as the severity level and the classification of the notification, which can be used for filtering. +For more information about notification grouping and filtering, see <>. + +Each GQL-status object consists of the following fields: + +.GQLSTATUS notification object +[cols="<1s,<4"] +|=== +|GQLSTATUS code +a| A 5-character string that is the concatenation of a 2-character class code followed by a 3-character subclass code. +|StatusDescription +a| A human-readable description of the GQLSTATUS, which consists of a condition, a subcondition, and a description. +The condition and subcondition are textual representations of the class and subclass codes, respectively. +| DiagnosticRecord +a| Extra information about the status, given as key-value pairs, both on the server and driver side. +To retrieve the full diagnostic record, you can use the `diagnosticRecord()` method on both the server and driver sides. +Additional helper methods are exposed for some useful fields. +[cols="<1s,<4"] +!=== +! Field ! Description +! `OPERATION` ! The operation that the notification is related to. Always defaults to empty. +! `OPERATION_CODE` ! The operation code that the notification is related to. Always defaults to `0`. +! `CURRENT_SCHEMA` ! The current schema that the notification is related to. Always defaults to `/`. +! `_severity` a! The Neo4j severity level, which can be one of the following: + +- `WARNING`: There might be a problem with your query. Please, take a look. +- `INFORMATION`: The query is correct, but this information can still be useful. + +!`_classification` ! The Neo4j category of the notification. +! `_position` ! The position, given by row and column, where the notification is relevant in the query text. +! `_status_parameters`! A map that contains all variable parts of the status description. +!=== +|=== + + +[[general-codes-for-success]] +=== General codes for success + +GQL has three general codes for success, indicated by different GQLSTATUS codes in categories S (successful completion) and N (no data), which are not covered by the Neo4j notification framework and are considered to be the default statuses for successful completion, omitted result, and no data, respectively. +The Neo4j classification, severity, position, and status parameters are not meaningful for these GQL statuses, so they are not included in the diagnostic record and are set to default values either by the server or by the driver. + +.GQLSTATUS general codes +[cols="1,2,1,4", options="header"] +|=== +|GQLSTATUS +|Condition +|Subcondition +|Description + +| 00000 +| Successful completion +| +| Successful completion with a regular non-empty result (n > 0 columns, m > 0 rows), for example, a `RETURN` clause with matches. + +| 00001 +| Successful completion +| Omitted result +| Successful completion with no return columns (n = 0 columns, m = 0 rows), for example, link:https://neo4j.com/docs/cypher-manual/current/planning-and-tuning/[`EXPLAIN` queries]. + +| 02000 +| No data +| +| Successful completion with an empty result (n > 0 columns, m = 0 rows), for example, a `MATCH` clause with no matches. +|=== + +GQLSTATUS general codes are filled in by the server unless the server is too old to be aware of GQL-status objects, in which case, it is polyfilled by the driver (see <>). +The driver tries to deduce `SUCCESS`, `OMITTED RESULT`, or `NO DATA` from the returned number of records and columns. +If that fails, it uses the GQLSTATUS 02N42 (`no data: unknown subcondition. Unknown GQLSTATUS from old server.`) to indicate that the server did not provide a GQL-status object. +Then, it poly-fills statuses from the notifications and merges the two lists according to the GQL precedence rules described in <>. + +[[gqlstatus-codes]] +=== Neo4j-defined GQLSTATUS codes + +The Neo4j-defined GQLSTATUS codes are divided into classes and subclasses, where the class code is a 2-character string (one of `00`, `01`, or `03`) and the subclass code is a 3-character string. +The class code indicates the general condition of the status (such as successful completion, warning, or information), and the subclass code provides more detailed information about the condition, such as classification and messages. + +The following table lists the Neo4j-defined groups of GQLSTATUS codes and their meanings: + +.GQLSTATUS groups of codes as defined by Neo4j +[frame="topbot", stripes=odd, grid="cols", cols="<1s,<4"] +|=== +|GQLSTATUS code +|*Description* + +| 01N0[y] +| Deprecation warnings +| 01N3[y] +| Hint warnings + +| 01N4[y] +| Unsupported warnings + +| 01N5[y] +| Unrecognized warnings + +| 01N6[y] +| Generic warnings + +| 01N7[y] +| Security warnings + +| 03N9[y] +| Performance information + +| 03N6[y] +| Generic information + +| 00N5[y] +| Unrecognized information under successful completion + +| 00N6[y] +| Generic information under successful completion + +| 00N7[y] +| Security information under successful completion + +| 00N8[y] +| Topology information under successful completion + +|=== + +[[notification-grouping-and-filtering]] +== Server notification grouping and filtering + +All server notifications are grouped by category (which is called classification in the GqlStatusObject framework) and severity level, which can be one of `WARNING`, `WARNING OR INFORMATION`, or `INFORMATION`. + +The driver-side notification configuration used for filtering notifications by category and severity is the same for both Neo4j Notification and GQL-status object frameworks. +The driver can filter notifications by category/classification and severity level, and the server will only send notifications that match the driver-side configuration. + +The driver can also choose to ignore notifications. +However, as per the GQLSTATUS framework, the server must always send the primary GQL-status object. +Therefore, if notifications are off or the notification configuration filtering is set to filter out all notifications, the server will still send the primary GQL-status object with the status `SUCCESSFUL COMPLETION`, `OMITTED RESULT` or `NO DATA`. + +The following notification groups exist in Neo4j, ordered by severity: + +.Notification groups and severity levels [options="header", cols="<1m,<1m,<3,<2"] |=== -| CATEGORY +| CATEGORY/CLASSIFICATION | SEVERITY | EXPLANATION | RECOMMENDED ACTION @@ -79,3 +248,44 @@ The following categories exist, ordered by severity: | The query uses costly operations and might be slow. Consider if it is possible to rewrite the query in a different way. | |=== + +[[notification-internals]] +== Notification internals + +The server and driver communicate with each other through the Bolt protocol. +During the handshake process, they agree on using the newest possible Bolt protocol version that both the server and the driver support. +For more information on the Bolt versions supported by different server versions, see the link:https://neo4j.com/docs/bolt/current/bolt-compatibility[Bolt Protocol documentation]. + +On the server side, notifications are part of the Result Core API. +A method called `getNotifications()` returns a list of server-side notification objects. +These notifications are then sent to the driver as success Bolt message metadata. +On the driver side, notifications are part of the ResultSummary API, which has a method called `notifications()` that returns a list of driver-side Notification objects. +The result of the `getCode()` or `code()` methods is known as the Neo4j status code. +Driver-side notification configuration filters notifications by severity and/or category at both the driver and session levels. +For more information, see <>. + +From version 5.23, Neo4j has a new GqlStatusObject API in addition to the existing Notification API. +This can be used using the `.getGqlStatusObjects()` method in the Result Core API or by using the latest Neo4j drivers. + +[[server-driver-compatibility]] +== Server-driver version compatibility + +The GqlStatusObject API is available in Neo4j 5.22 and later versions on the server side and in the 5.23 driver and later versions on the driver side. +The current Notification API is still present, and the GqlStatusObject API can be used in parallel with it. + +To fully utilize the GqlStatusObject API, both your server and the driver must support it. +Drivers that are older than 5.23 send only notifications from the Notification API, even if the server is 5.22 or later. + +If the 5.23 driver talks to a server that is too old to be aware of GQL-status objects, the driver tries to deduce `SUCCESS`, `OMITTED RESULT`, or `NO DATA` from the returned number of records and columns. +If that fails, it uses the GQLSTATUS 02N42 (`no data: unknown subcondition. Unknown GQLSTATUS from old server.`) to indicate that the server did not provide a GQL-status object. +Then, it poly-fills statuses from the notifications and merges the two lists according to the GQL precedence rules described in <>. + +// The following table illustrates the compatibility between the different server and driver versions for both the current Notification API and the GqlStatusObject API: + +// TODO + + + + + +>>>>>>> gql-notifications diff --git a/publish.yml b/publish.yml index a305469..28ffeba 100644 --- a/publish.yml +++ b/publish.yml @@ -6,7 +6,7 @@ site: content: sources: - url: ./ - branches: ['3.5','4.0','4.1','4.2','4.3','4.4','dev'] + branches: ['3.5','4.0','4.1','4.2','4.3','4.4','HEAD'] edit_url: https://github.com/neo4j/docs-status-codes/tree/{refname}/{path} exclude: - '!**/_includes/*'