From d7b5128c76a01c2125a8419d150315ba5bc225c9 Mon Sep 17 00:00:00 2001 From: Tobias Lindaaker Date: Fri, 19 Oct 2018 15:23:12 +0200 Subject: [PATCH 01/14] Specify the behaviour of deleted elements --- .../CIP2018-10-19-Delete-Semantics.adoc | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 cip/1.accepted/CIP2018-10-19-Delete-Semantics.adoc diff --git a/cip/1.accepted/CIP2018-10-19-Delete-Semantics.adoc b/cip/1.accepted/CIP2018-10-19-Delete-Semantics.adoc new file mode 100644 index 0000000000..afdb64f238 --- /dev/null +++ b/cip/1.accepted/CIP2018-10-19-Delete-Semantics.adoc @@ -0,0 +1,49 @@ += CIP2018-10-19 Semantics of Deleted Elements +:numbered: +:toc: +:toc-placement: macro +:source-highlighter: codemirror + +*Author:* Tobias Lindaaker + +toc::[] + +== Semantics of Deleted Elements + +Cypher allows read statements to occur after update statements. +This includes reading statements after statements that delete elements. +Since the driving table of the preceding query is retained into the succeeding reading statements, this means that entries in the driving table that previously contained elements might now contain elements that have been deleted. + +The semantics of accessing such elements is the same as accessing `NULL` values. + +This can be thought of as replacing all occurrences of the deleted elements (anywhere) in the driving table (including in nested values) with `NULL`, or as treating the deleted elements as _effectively_ `NULL`. + +These semantics effect the `DELETE` statement itself, even if not succeeded by further read statements, since the same element can occur in multiple rows in the driving table. + + +=== Accessing properties of deleted Elements + +Accessing properties of deleted elements produces a `NULL` value, just like accessing a property from a `NULL` value would. + +=== Pattern matching on deleted Elements + +Pattern matching on deleted elements produces a single row containing only `NULL` bindings, in the same way as `OPTIONAL MATCH` would. + +=== Deleting deleted Elements + +Deleting a deleted element (or any `NULL` value) is a no-op. + +=== Equality of deleted Elements + +The normal semantics is that two `NULL` values are never considered equal. +This extends to deleted elements, since they are equivalent to `NULL` for _all_ intents and purposes. + +[source, cypher] +.This query returns `same1: *true*; same2: *false*` for all rows +---- +MATCH (n), (m) +WHERE n = m AND NOT EXISTS { (n)-() } +WITH n, m, n = m AS same1 +DELETE n +RETURN same1, n = m AS same2 +---- From 4c2c9718b31ecd04cc33aa272cbd2a0af057e9bf Mon Sep 17 00:00:00 2001 From: Tobias Lindaaker Date: Fri, 19 Oct 2018 15:42:46 +0200 Subject: [PATCH 02/14] Add a note on the effect DELETE has on type system analysis --- cip/1.accepted/CIP2018-10-19-Delete-Semantics.adoc | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/cip/1.accepted/CIP2018-10-19-Delete-Semantics.adoc b/cip/1.accepted/CIP2018-10-19-Delete-Semantics.adoc index afdb64f238..52b42de5bb 100644 --- a/cip/1.accepted/CIP2018-10-19-Delete-Semantics.adoc +++ b/cip/1.accepted/CIP2018-10-19-Delete-Semantics.adoc @@ -47,3 +47,11 @@ WITH n, m, n = m AS same1 DELETE n RETURN same1, n = m AS same2 ---- + +=== Effects of DELETE on types + +In the part of a query following a `DELETE` statement that deletes elements of type node, all elements of type node may now be nullable. +In the part of a query following a `DELETE` statement that deletes elements of type relationship, all elements of type relationship may now be nullable. +In the part of a query following a `DETACH DELETE` statement, all elements of type node and of type relationship may now be nullable. + +An implementation that tracks the types of nodes and relationships more closely, such as by which labels they have, it is allowed to not treat elements as nullable in the part of the query following `DELETE` iff it can be proven that those entities are unaffected by the `DELETE`. From dd5991111e580e17b655f85c2afe0e4e79b56185 Mon Sep 17 00:00:00 2001 From: Tobias Lindaaker Date: Fri, 19 Oct 2018 15:57:40 +0200 Subject: [PATCH 03/14] Adding notes on deleted elements in paths --- cip/1.accepted/CIP2018-10-19-Delete-Semantics.adoc | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/cip/1.accepted/CIP2018-10-19-Delete-Semantics.adoc b/cip/1.accepted/CIP2018-10-19-Delete-Semantics.adoc index 52b42de5bb..d1433fd5ef 100644 --- a/cip/1.accepted/CIP2018-10-19-Delete-Semantics.adoc +++ b/cip/1.accepted/CIP2018-10-19-Delete-Semantics.adoc @@ -48,6 +48,18 @@ DELETE n RETURN same1, n = m AS same2 ---- +=== Deleted elements in paths + +If an element is deleted that is part of a path value, such a path can no longer exist, therefore the path value is to be treated as _effectively_ `NULL` (in the same way that the deleted element that is part of it would). + +[source, cypher] +.This query returns `a: *null*; b: *null*; c: *null*` for all rows +---- +MATCH p=()-[r]->() +DELETE r +RETURN p AS a, nodes(p) AS b, relationships(p) AS c +---- + === Effects of DELETE on types In the part of a query following a `DELETE` statement that deletes elements of type node, all elements of type node may now be nullable. From b93ce498e7a9b127cfa0a9317d9a675038da9335 Mon Sep 17 00:00:00 2001 From: Tobias Lindaaker Date: Fri, 19 Oct 2018 16:04:50 +0200 Subject: [PATCH 04/14] Marry the section on paths with the section on type system --- cip/1.accepted/CIP2018-10-19-Delete-Semantics.adoc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/cip/1.accepted/CIP2018-10-19-Delete-Semantics.adoc b/cip/1.accepted/CIP2018-10-19-Delete-Semantics.adoc index d1433fd5ef..525136dbad 100644 --- a/cip/1.accepted/CIP2018-10-19-Delete-Semantics.adoc +++ b/cip/1.accepted/CIP2018-10-19-Delete-Semantics.adoc @@ -60,10 +60,11 @@ DELETE r RETURN p AS a, nodes(p) AS b, relationships(p) AS c ---- -=== Effects of DELETE on types +=== Effects of DELETE on the nullability of types In the part of a query following a `DELETE` statement that deletes elements of type node, all elements of type node may now be nullable. In the part of a query following a `DELETE` statement that deletes elements of type relationship, all elements of type relationship may now be nullable. In the part of a query following a `DETACH DELETE` statement, all elements of type node and of type relationship may now be nullable. +In the part of a query following a `DELETE` statement, all elements of type path may now be nullable. -An implementation that tracks the types of nodes and relationships more closely, such as by which labels they have, it is allowed to not treat elements as nullable in the part of the query following `DELETE` iff it can be proven that those entities are unaffected by the `DELETE`. +An implementation that tracks the types of nodes and relationships more closely, such as by which labels they have, it is allowed to not treat elements as nullable in the part of the query following `DELETE` iff it can be proven that those elements are unaffected by the `DELETE`. From ca75a4d7df3e79a8f00ddf7ebbf6de86290113ca Mon Sep 17 00:00:00 2001 From: Mats Rydberg Date: Tue, 14 Jun 2022 17:53:52 +0200 Subject: [PATCH 05/14] Add author and apply CIP template --- .../CIP2018-10-19-Delete-Semantics.adoc | 138 +++++++++++++++++- 1 file changed, 135 insertions(+), 3 deletions(-) diff --git a/cip/1.accepted/CIP2018-10-19-Delete-Semantics.adoc b/cip/1.accepted/CIP2018-10-19-Delete-Semantics.adoc index 525136dbad..7292f2b52e 100644 --- a/cip/1.accepted/CIP2018-10-19-Delete-Semantics.adoc +++ b/cip/1.accepted/CIP2018-10-19-Delete-Semantics.adoc @@ -4,15 +4,31 @@ :toc-placement: macro :source-highlighter: codemirror -*Author:* Tobias Lindaaker +*Authors:* Tobias Lindaaker , Mats Rydberg + +[abstract] +.Abstract +-- +This is a high-level summary of the aim and description of the CIP. +-- toc::[] -== Semantics of Deleted Elements + +== Motivation Cypher allows read statements to occur after update statements. This includes reading statements after statements that delete elements. -Since the driving table of the preceding query is retained into the succeeding reading statements, this means that entries in the driving table that previously contained elements might now contain elements that have been deleted. +Since the driving table of the preceding query (parts) is retained into the succeeding reading statements, this means that entries in the driving table that previously contained elements might now contain elements that have been deleted. + +//add more + +== Background + + + + +== Proposal The semantics of accessing such elements is the same as accessing `NULL` values. @@ -21,6 +37,28 @@ This can be thought of as replacing all occurrences of the deleted elements (any These semantics effect the `DELETE` statement itself, even if not succeeded by further read statements, since the same element can occur in multiple rows in the driving table. +=== Syntax + +//Provide the full range of syntactic additions and modifications in https://en.wikipedia.org/wiki/Extended_Backus-Naur_Form[EBNF] format and refer back to constructs defined https://github.com/opencypher/openCypher/tree/master/grammar[here]. +// +//_An example of this is shown below._ +// +//Extend expressions to support string search operators: +//[source, ebnf] +//---- +//expression = current definition of expression +// | string-search +// ; +// +//string-search = starts with | ends with | contains ; +//starts-with = expression, "STARTS", "WITH", expression ; +//ends-with = expression, "ENDS", "WITH", expression ; +//contains = expression, "CONTAINS" expression ; +//---- + +=== Semantics + + === Accessing properties of deleted Elements Accessing properties of deleted elements produces a `NULL` value, just like accessing a property from a `NULL` value would. @@ -68,3 +106,97 @@ In the part of a query following a `DETACH DELETE` statement, all elements of ty In the part of a query following a `DELETE` statement, all elements of type path may now be nullable. An implementation that tracks the types of nodes and relationships more closely, such as by which labels they have, it is allowed to not treat elements as nullable in the part of the query following `DELETE` iff it can be proven that those elements are unaffected by the `DELETE`. + + +//Provide a description of the expected semantics of the new feature(s). +//Use subheadings to structure the content. +// +//_Examples are shown below in sections 3.3.1–3.3.3:_ +// +//==== STARTS WITH +// +//Using `lhs STARTS WITH rhs` requires both `lhs` and `rhs` to be strings. +//This new expression evaluates to true if `lhs` textually starts with `rhs`. +//Otherwise, it is false. +// +//==== ENDS WITH +// +//Using `lhs ENDS WITH rhs` requires both `lhs` and `rhs` to be strings. +//This new expression evaluates to true if `lhs` textually ends with `rhs`. +//Otherwise, it is false. +// +//==== CONTAINS +// +//Using `lhs CONTAINS rhs` requires both `lhs` and `rhs` to be strings. +//This new expression evaluates to true if `lhs` textually contains `rhs`. +//Otherwise, it is false. +// +//If any argument to `STARTS WITH`, `ENDS WITH`, or `CONTAINS` is `NULL`, then the result of evaluating the whole predicate is `NULL`. +// +//It is a type error to use `STARTS WITH`, `ENDS WITH`, or `CONTAINS` with a value that is not a string. + +=== Examples + +//For each aspect of the proposed feature(s), provide at least one Cypher example query to show how the feature is envisaged to work, along with explanatory text. +// +//_An example of this is shown below._ +// +//Find all persons whose name starts with "And": +//[source, cypher] +//---- +//MATCH (a:Person) +//WHERE a.name STARTS WITH “And” +//RETURN a +//---- +// +//Find all persons whose name starts with the parameter prefix: +//[source, cypher] +//---- +//MATCH (a:Person) +//WHERE a.name STARTS WITH {prefix} +//RETURN a +//---- +// +//Find all persons whose name ends with "fan": +//[source, cypher] +//---- +//MATCH (a:Person) +//WHERE a.name ENDS WITH "fan" +//RETURN a +//---- +// +//Find all books whose isbn in string form contains "007": +//[source, cypher] +//---- +//MATCH (b:Book) +//WHERE toString(b.isbn) CONTAINS "007" +//RETURN a +//---- + +=== Interaction with existing features + +//Provide details on any interactions that need to be considered. + +=== Alternatives + +//List any alternatives here; e.g. new keywords, a smaller feature set etc. + +== What others do + +//If applicable, include a feature comparison table, along with any useful links. +// +//To provide a well-rounded comparison, please ensure the inclusion of at least one SQL-based implementation -- such as DB2 or Postgres -- as well as SPARQL. +//If you require any assistance or pointers to the latter, please contact petra.selmer@neotechnology.com. + +== Benefits to this proposal + +//List the benefits here. + +== Caveats to this proposal + +//List any caveats here. +//These may include omissions, reasons for non-conformance with other features and so on. + +== Appendix + +//Put any supplementary information here. From 4a29313e773fdfa947f9ad6ad6705f25b53c6d4f Mon Sep 17 00:00:00 2001 From: Mats Rydberg Date: Tue, 14 Jun 2022 18:00:05 +0200 Subject: [PATCH 06/14] Fill in Motivation - skip Background - prefer clause over statement - refer to CIR --- .../CIP2018-10-19-Delete-Semantics.adoc | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/cip/1.accepted/CIP2018-10-19-Delete-Semantics.adoc b/cip/1.accepted/CIP2018-10-19-Delete-Semantics.adoc index 7292f2b52e..92166295c1 100644 --- a/cip/1.accepted/CIP2018-10-19-Delete-Semantics.adoc +++ b/cip/1.accepted/CIP2018-10-19-Delete-Semantics.adoc @@ -17,15 +17,14 @@ toc::[] == Motivation -Cypher allows read statements to occur after update statements. -This includes reading statements after statements that delete elements. -Since the driving table of the preceding query (parts) is retained into the succeeding reading statements, this means that entries in the driving table that previously contained elements might now contain elements that have been deleted. - -//add more - -== Background - - +Cypher allows reading clauses to occur after updating clauses. +This includes reading clauses after clauses that delete elements. +Since the driving table of the preceding query (parts) is retained into the succeeding reading query (parts), this means that entries in the driving table that previously contained elements might now contain elements that have been deleted. + +The semantics of such deleted elements are not obvious. +In fact, implementations have dealt with these in inconsistent ways, sometimes allowing access to the element id, or its properties, or allowing `MATCH` clauses to find deleted elements, and sometimes none of those things. +The need for consistent semantics for such deleted elements is expressed in part by `CIR-2017-263`. +This CIP specifies consistent and clear semantics for such deleted elements. == Proposal From 73089bae4050541d185ab2df0f82697062ff03f2 Mon Sep 17 00:00:00 2001 From: Mats Rydberg Date: Tue, 14 Jun 2022 18:17:58 +0200 Subject: [PATCH 07/14] Fill in Proposal and Syntax - relate to OPTIONAL MATCH --- .../CIP2018-10-19-Delete-Semantics.adoc | 36 +++++++++---------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/cip/1.accepted/CIP2018-10-19-Delete-Semantics.adoc b/cip/1.accepted/CIP2018-10-19-Delete-Semantics.adoc index 92166295c1..170b0b1386 100644 --- a/cip/1.accepted/CIP2018-10-19-Delete-Semantics.adoc +++ b/cip/1.accepted/CIP2018-10-19-Delete-Semantics.adoc @@ -29,31 +29,29 @@ This CIP specifies consistent and clear semantics for such deleted elements. == Proposal -The semantics of accessing such elements is the same as accessing `NULL` values. - +This CIP specifies that the semantics of accessing deleted elements is the same as accessing `NULL` values. This can be thought of as replacing all occurrences of the deleted elements (anywhere) in the driving table (including in nested values) with `NULL`, or as treating the deleted elements as _effectively_ `NULL`. -These semantics effect the `DELETE` statement itself, even if not succeeded by further read statements, since the same element can occur in multiple rows in the driving table. +`CIP-2015-10-27` defines that visibility between clauses follow a linear model. +That is, the effects of a clause are visible to the clause itself and all subsequent clauses, but never to a preceding clause. +That applies also to deleted elements. +These semantics effect the `DELETE` clause itself, even if not succeeded by further reading clauses, since the same element can occur in multiple rows in the driving table. + +These semantics are consistent with the `OPTIONAL MATCH` clause, through the behaviour of that clause when no match is found. +In that case, the pattern variables will be projected with a `NULL` value and subsequent operations using these variables are well-defined. +This CIP builds on these well-established semantics. === Syntax -//Provide the full range of syntactic additions and modifications in https://en.wikipedia.org/wiki/Extended_Backus-Naur_Form[EBNF] format and refer back to constructs defined https://github.com/opencypher/openCypher/tree/master/grammar[here]. -// -//_An example of this is shown below._ -// -//Extend expressions to support string search operators: -//[source, ebnf] -//---- -//expression = current definition of expression -// | string-search -// ; -// -//string-search = starts with | ends with | contains ; -//starts-with = expression, "STARTS", "WITH", expression ; -//ends-with = expression, "ENDS", "WITH", expression ; -//contains = expression, "CONTAINS" expression ; -//---- +There is no syntactic element to this CIP. +For reference, we include the syntax of the clauses that are able to cause a deleting effect. + +[source, ebnf] +---- + = ["DETACH"], "DELETE", ; +---- + === Semantics From 22424148f72e81af4cf8822b035efbad89ce4dc7 Mon Sep 17 00:00:00 2001 From: Mats Rydberg Date: Tue, 14 Jun 2022 18:39:50 +0200 Subject: [PATCH 08/14] Fill in Semantics - nest under Semantics section - explain effect on pattern matching using predicate example - remove commented-out junk --- .../CIP2018-10-19-Delete-Semantics.adoc | 74 ++++++++++--------- 1 file changed, 38 insertions(+), 36 deletions(-) diff --git a/cip/1.accepted/CIP2018-10-19-Delete-Semantics.adoc b/cip/1.accepted/CIP2018-10-19-Delete-Semantics.adoc index 170b0b1386..9f7b24c597 100644 --- a/cip/1.accepted/CIP2018-10-19-Delete-Semantics.adoc +++ b/cip/1.accepted/CIP2018-10-19-Delete-Semantics.adoc @@ -55,23 +55,46 @@ For reference, we include the syntax of the clauses that are able to cause a del === Semantics +The semantics of a deleted element are exactly the same as if the element variable was mapped to a `NULL` value. +In this section, we will describe detailed semantics for the access of particularly interesting aspects of elements. -=== Accessing properties of deleted Elements + +==== Properties Accessing properties of deleted elements produces a `NULL` value, just like accessing a property from a `NULL` value would. +This includes both a direct property access operator (`.`) and the `properties()` function. + + +==== Node labels + +A node label expression using the colon operator (`:`) on a deleted node evaluates to `NULL`. +The `labels()` function on a deleted node evaluates to `NULL`. + + +==== Relationship type + +A relationship type expression using the colon operator (`:`) on a deleted relationship evaluates to `NULL`. +The `type()` function on a deleted relationship evaluates to `NULL`. -=== Pattern matching on deleted Elements -Pattern matching on deleted elements produces a single row containing only `NULL` bindings, in the same way as `OPTIONAL MATCH` would. +==== Pattern matching using deleted elements -=== Deleting deleted Elements +When a pattern used for matching in the graph contains an already-bound variable that refers to a deleted element, this results in the same predicate as otherwise, but with semantics that are identical to the case when a `NULL` value would be held by that variable. -Deleting a deleted element (or any `NULL` value) is a no-op. +For example, consider the pattern `(a)-[r]->()` where the binding table contains bindings for `a` and `r`. +There is an implicit predicate for the pattern matching allowing only elements `n` and `m` in the `a` and `r` positions for which `a = n AND r = m` is `TRUE`. +If `a` and `b` refer to deleted elements, this predicate will not be true for any elements in the database, as the predicate is supposed to evaluate to the same value as `a = NULL AND r = NULL` which is `NULL` and not `TRUE`. -=== Equality of deleted Elements + +==== Deleting deleted Elements + +Deleting a deleted element (like any `NULL` value) is a no-op. + + +==== Equality of deleted Elements The normal semantics is that two `NULL` values are never considered equal. -This extends to deleted elements, since they are equivalent to `NULL` for _all_ intents and purposes. +This extends to deleted elements, since they are equivalent to `NULL` for all intents and purposes. [source, cypher] .This query returns `same1: *true*; same2: *false*` for all rows @@ -83,7 +106,7 @@ DELETE n RETURN same1, n = m AS same2 ---- -=== Deleted elements in paths +==== Deleted elements in paths If an element is deleted that is part of a path value, such a path can no longer exist, therefore the path value is to be treated as _effectively_ `NULL` (in the same way that the deleted element that is part of it would). @@ -95,7 +118,13 @@ DELETE r RETURN p AS a, nodes(p) AS b, relationships(p) AS c ---- -=== Effects of DELETE on the nullability of types + +==== Deleted elements in nested structures + +If an element exists within a list or map or another nested structure, the semantics still apply. + + +==== Effects of DELETE on the nullability of types In the part of a query following a `DELETE` statement that deletes elements of type node, all elements of type node may now be nullable. In the part of a query following a `DELETE` statement that deletes elements of type relationship, all elements of type relationship may now be nullable. @@ -105,33 +134,6 @@ In the part of a query following a `DELETE` statement, all elements of type path An implementation that tracks the types of nodes and relationships more closely, such as by which labels they have, it is allowed to not treat elements as nullable in the part of the query following `DELETE` iff it can be proven that those elements are unaffected by the `DELETE`. -//Provide a description of the expected semantics of the new feature(s). -//Use subheadings to structure the content. -// -//_Examples are shown below in sections 3.3.1–3.3.3:_ -// -//==== STARTS WITH -// -//Using `lhs STARTS WITH rhs` requires both `lhs` and `rhs` to be strings. -//This new expression evaluates to true if `lhs` textually starts with `rhs`. -//Otherwise, it is false. -// -//==== ENDS WITH -// -//Using `lhs ENDS WITH rhs` requires both `lhs` and `rhs` to be strings. -//This new expression evaluates to true if `lhs` textually ends with `rhs`. -//Otherwise, it is false. -// -//==== CONTAINS -// -//Using `lhs CONTAINS rhs` requires both `lhs` and `rhs` to be strings. -//This new expression evaluates to true if `lhs` textually contains `rhs`. -//Otherwise, it is false. -// -//If any argument to `STARTS WITH`, `ENDS WITH`, or `CONTAINS` is `NULL`, then the result of evaluating the whole predicate is `NULL`. -// -//It is a type error to use `STARTS WITH`, `ENDS WITH`, or `CONTAINS` with a value that is not a string. - === Examples //For each aspect of the proposed feature(s), provide at least one Cypher example query to show how the feature is envisaged to work, along with explanatory text. From d074400482bf726a717a2d5b94ed425c73905a01 Mon Sep 17 00:00:00 2001 From: Mats Rydberg Date: Tue, 14 Jun 2022 18:40:07 +0200 Subject: [PATCH 09/14] Omit part on nullability --- cip/1.accepted/CIP2018-10-19-Delete-Semantics.adoc | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/cip/1.accepted/CIP2018-10-19-Delete-Semantics.adoc b/cip/1.accepted/CIP2018-10-19-Delete-Semantics.adoc index 9f7b24c597..2d8bb81b82 100644 --- a/cip/1.accepted/CIP2018-10-19-Delete-Semantics.adoc +++ b/cip/1.accepted/CIP2018-10-19-Delete-Semantics.adoc @@ -124,16 +124,6 @@ RETURN p AS a, nodes(p) AS b, relationships(p) AS c If an element exists within a list or map or another nested structure, the semantics still apply. -==== Effects of DELETE on the nullability of types - -In the part of a query following a `DELETE` statement that deletes elements of type node, all elements of type node may now be nullable. -In the part of a query following a `DELETE` statement that deletes elements of type relationship, all elements of type relationship may now be nullable. -In the part of a query following a `DETACH DELETE` statement, all elements of type node and of type relationship may now be nullable. -In the part of a query following a `DELETE` statement, all elements of type path may now be nullable. - -An implementation that tracks the types of nodes and relationships more closely, such as by which labels they have, it is allowed to not treat elements as nullable in the part of the query following `DELETE` iff it can be proven that those elements are unaffected by the `DELETE`. - - === Examples //For each aspect of the proposed feature(s), provide at least one Cypher example query to show how the feature is envisaged to work, along with explanatory text. From 4975f5567f5e3fa81b91213d27f2cb5a5707166d Mon Sep 17 00:00:00 2001 From: Mats Rydberg Date: Tue, 14 Jun 2022 18:47:14 +0200 Subject: [PATCH 10/14] Fill in bottom sections - omit What others do --- .../CIP2018-10-19-Delete-Semantics.adoc | 25 ++++++++----------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/cip/1.accepted/CIP2018-10-19-Delete-Semantics.adoc b/cip/1.accepted/CIP2018-10-19-Delete-Semantics.adoc index 2d8bb81b82..3b48171bc2 100644 --- a/cip/1.accepted/CIP2018-10-19-Delete-Semantics.adoc +++ b/cip/1.accepted/CIP2018-10-19-Delete-Semantics.adoc @@ -164,28 +164,23 @@ If an element exists within a list or map or another nested structure, the seman === Interaction with existing features -//Provide details on any interactions that need to be considered. +The semantics of this proposal interact with any and all functionality in Cypher that operates over elements. +This is a substantial part of the language, which motivates the consistent semantics described in this CIP. -=== Alternatives +One particular relation that can be repeated is that to the `OPTIONAL MATCH` clause. +It is the intention that an element matched using a non-matching `OPTIONAL MATCH` will behave identical to a deleted element. -//List any alternatives here; e.g. new keywords, a smaller feature set etc. -== What others do +=== Alternatives -//If applicable, include a feature comparison table, along with any useful links. -// -//To provide a well-rounded comparison, please ensure the inclusion of at least one SQL-based implementation -- such as DB2 or Postgres -- as well as SPARQL. -//If you require any assistance or pointers to the latter, please contact petra.selmer@neotechnology.com. +An alternative model is the Tombstone semantics described briefly in `CIR-2017-263`, which allows reading (some) parts of deleted elements. -== Benefits to this proposal -//List the benefits here. +== Benefits to this proposal -== Caveats to this proposal +A consistent specification for how deleted elements work within Cypher. -//List any caveats here. -//These may include omissions, reasons for non-conformance with other features and so on. -== Appendix +== Caveats to this proposal -//Put any supplementary information here. +Query authors have to keep in mind to project properties or other data from elements before they are deleted in order to return data from elements deleted in the same query. From ce3e073f89f8f8a286868143409157afc217dd60 Mon Sep 17 00:00:00 2001 From: Mats Rydberg Date: Tue, 14 Jun 2022 18:54:29 +0200 Subject: [PATCH 11/14] Add semantics part for returning elements --- cip/1.accepted/CIP2018-10-19-Delete-Semantics.adoc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/cip/1.accepted/CIP2018-10-19-Delete-Semantics.adoc b/cip/1.accepted/CIP2018-10-19-Delete-Semantics.adoc index 3b48171bc2..21ca531635 100644 --- a/cip/1.accepted/CIP2018-10-19-Delete-Semantics.adoc +++ b/cip/1.accepted/CIP2018-10-19-Delete-Semantics.adoc @@ -124,6 +124,11 @@ RETURN p AS a, nodes(p) AS b, relationships(p) AS c If an element exists within a list or map or another nested structure, the semantics still apply. +==== Returning deleted elements + +A deleted element is replaced with a `NULL` value when returned at the end of a query. + + === Examples //For each aspect of the proposed feature(s), provide at least one Cypher example query to show how the feature is envisaged to work, along with explanatory text. From 7c31ad5aaf7a773eb8a1435201244f55fa37c81c Mon Sep 17 00:00:00 2001 From: Mats Rydberg Date: Tue, 14 Jun 2022 18:54:36 +0200 Subject: [PATCH 12/14] Add examples --- .../CIP2018-10-19-Delete-Semantics.adoc | 76 ++++++++++--------- 1 file changed, 41 insertions(+), 35 deletions(-) diff --git a/cip/1.accepted/CIP2018-10-19-Delete-Semantics.adoc b/cip/1.accepted/CIP2018-10-19-Delete-Semantics.adoc index 21ca531635..60f7c55591 100644 --- a/cip/1.accepted/CIP2018-10-19-Delete-Semantics.adoc +++ b/cip/1.accepted/CIP2018-10-19-Delete-Semantics.adoc @@ -131,41 +131,47 @@ A deleted element is replaced with a `NULL` value when returned at the end of a === Examples -//For each aspect of the proposed feature(s), provide at least one Cypher example query to show how the feature is envisaged to work, along with explanatory text. -// -//_An example of this is shown below._ -// -//Find all persons whose name starts with "And": -//[source, cypher] -//---- -//MATCH (a:Person) -//WHERE a.name STARTS WITH “And” -//RETURN a -//---- -// -//Find all persons whose name starts with the parameter prefix: -//[source, cypher] -//---- -//MATCH (a:Person) -//WHERE a.name STARTS WITH {prefix} -//RETURN a -//---- -// -//Find all persons whose name ends with "fan": -//[source, cypher] -//---- -//MATCH (a:Person) -//WHERE a.name ENDS WITH "fan" -//RETURN a -//---- -// -//Find all books whose isbn in string form contains "007": -//[source, cypher] -//---- -//MATCH (b:Book) -//WHERE toString(b.isbn) CONTAINS "007" -//RETURN a -//---- +.Returning a deleted node, a label expression using it, its labels, and a previously projected property; compared to a non-deleted node: +[source,cypher] +---- +CREATE (n:L {x: 1, y: 2}), (m:L {x: 3, y: 4}) +WITH *, n.x AS projectedWhenAlive +DELETE n +RETURN + n, // null + projectedWhenAlive, // 1 + n.x, // null + n.y, // null + properties(n), // null + n:L, // null + labels(n), // null + m, // the node as described above + m.x, // 3 + labels(m) // ['L'] +---- + + +.Deleting a node which is accessed across different rows: +[source,cypher] +---- +CREATE (x:X {x: 1}) +WITH [x, x] AS list +UNWIND list AS xComesTwiceHere +WITH xComesTwiceHere, x.x AS readBeforeDelete +DELETE xComesTwiceHere +RETURN readBeforeDelete +---- + +.Result: +[opts="header",cols=m] +|=== +|readBeforeDelete +|1 +|1 +|=== + +Note that the second row returns `1` and not `null`. + === Interaction with existing features From 2928d88ce082966ac16264d2a5a693c9194befbb Mon Sep 17 00:00:00 2001 From: Mats Rydberg Date: Fri, 17 Jun 2022 11:45:53 +0200 Subject: [PATCH 13/14] Add TCK scenarios for returning of a deleted node --- tck/features/clauses/delete/Delete4.feature | 91 +++++++++++++++++++++ 1 file changed, 91 insertions(+) diff --git a/tck/features/clauses/delete/Delete4.feature b/tck/features/clauses/delete/Delete4.feature index c194133554..271771b022 100644 --- a/tck/features/clauses/delete/Delete4.feature +++ b/tck/features/clauses/delete/Delete4.feature @@ -84,3 +84,94 @@ Feature: Delete4 - Delete clause interoperation with other clauses """ Then the result should be empty And no side effects + + Scenario: [4] Returning a deleted node + Given an empty graph + And having executed: + """ + CREATE () + """ + When executing query: + """ + MATCH (n) + DELETE n + RETURN n + """ + Then the result should be, in any order: + | n | + | null | + And the side effects should be: + | -nodes | 1 | + + Scenario: [5] Returning a property of a deleted node + Given an empty graph + And having executed: + """ + CREATE ({x: 1}) + """ + When executing query: + """ + MATCH (n) + DELETE n + RETURN n.x AS x + """ + Then the result should be, in any order: + | x | + | null | + And the side effects should be: + | -nodes | 1 | + + Scenario: [6] Returning all properties of a deleted node + Given an empty graph + And having executed: + """ + CREATE ({x: 1}) + """ + When executing query: + """ + MATCH (n) + DELETE n + RETURN properties(n) AS properties + """ + Then the result should be, in any order: + | properties | + | null | + And the side effects should be: + | -nodes | 1 | + + Scenario: [7] Returning the labels of a deleted node + Given an empty graph + And having executed: + """ + CREATE (:A:B) + """ + When executing query: + """ + MATCH (n) + DELETE n + RETURN labels(n) AS l + """ + Then the result should be, in any order: + | l | + | null | + And the side effects should be: + | -nodes | 1 | + + Scenario: [8] Returning data projected from a node prior to deletion + Given an empty graph + And having executed: + """ + CREATE (:A:B {x: 1}) + """ + When executing query: + """ + MATCH (n) + WITH n, labels(n) AS labels, properties(n) AS props, n.x AS property + DELETE n + RETURN n, labels, props, property + """ + Then the result should be, in any order: + | n | labels | props | property | + | (:A:B {x: 1}) | ['A', 'B'] | {x: 1} | 1 | + And the side effects should be: + | -nodes | 1 | From 321046e6c1b8d5a1c6bcd9dec772836bb6471007 Mon Sep 17 00:00:00 2001 From: Mats Rydberg Date: Fri, 17 Jun 2022 15:22:02 +0200 Subject: [PATCH 14/14] Extend the alternatives section --- cip/1.accepted/CIP2018-10-19-Delete-Semantics.adoc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/cip/1.accepted/CIP2018-10-19-Delete-Semantics.adoc b/cip/1.accepted/CIP2018-10-19-Delete-Semantics.adoc index 60f7c55591..0fa12ac168 100644 --- a/cip/1.accepted/CIP2018-10-19-Delete-Semantics.adoc +++ b/cip/1.accepted/CIP2018-10-19-Delete-Semantics.adoc @@ -184,7 +184,11 @@ It is the intention that an element matched using a non-matching `OPTIONAL MATCH === Alternatives -An alternative model is the Tombstone semantics described briefly in `CIR-2017-263`, which allows reading (some) parts of deleted elements. +Several alternative models have been discussed: + +* Tombstone semantics, described briefly in `CIR-2017-263`, which allows reading parts of deleted elements. +* Variable-out-of-scope, meaning any operation using a deleted element is an error, as the variable is considered out of scope and removed from the graph following the deletion. +* A mix of the above, where some parts are allowed to be read, and others cause errors. == Benefits to this proposal