From 3a3f1981e3216d92e3ac091c267e09f30304c724 Mon Sep 17 00:00:00 2001 From: Mats Rydberg Date: Wed, 8 Mar 2017 09:57:58 +0100 Subject: [PATCH] Add example for how only constant expressions are allowed - Rename file to correct name for the CIP - Improve language --- ...doc => CIP2017-03-01-LIMIT-subclause.adoc} | 35 ++++++++++++++----- 1 file changed, 27 insertions(+), 8 deletions(-) rename cip/1.accepted/{CIP2017-03-01-SKIP-and-LIMIT.adoc => CIP2017-03-01-LIMIT-subclause.adoc} (62%) diff --git a/cip/1.accepted/CIP2017-03-01-SKIP-and-LIMIT.adoc b/cip/1.accepted/CIP2017-03-01-LIMIT-subclause.adoc similarity index 62% rename from cip/1.accepted/CIP2017-03-01-SKIP-and-LIMIT.adoc rename to cip/1.accepted/CIP2017-03-01-LIMIT-subclause.adoc index 647e802ab6..286269276e 100644 --- a/cip/1.accepted/CIP2017-03-01-SKIP-and-LIMIT.adoc +++ b/cip/1.accepted/CIP2017-03-01-LIMIT-subclause.adoc @@ -10,7 +10,7 @@ toc::[] == Background -This CIP is a proposal in answer to link:https://github.com/opencypher/openCypher/issues/194[CIR-2017-194]. +This CIP is a proposal in response to link:https://github.com/opencypher/openCypher/issues/194[CIR-2017-194]. == Proposal @@ -33,20 +33,39 @@ limit = "LIMIT", expr ; === Semantics -The `LIMIT` subclause prevents records passing through its parent clause after the specified amount of rows, as determined by the limit expression, has been processed. +The `LIMIT` subclause prevents records passing through its parent clause after the specified amount of rows, as determined by the expression used as the argument to `LIMIT`, has been processed. For these semantics to be well defined, the limit expression must be constant over the query lifetime, such as parameters or literals. +In other words, arbitrary expressions or variables are not valid, as the values of these may change across records, and it would not be clear which value should be used by the `LIMIT`. + +.Parameters and literals are global constants, and may be used as arguments to `LIMIT`: +[source, cypher] +---- +MATCH (a:Label) +LIMIT $matchLimit +RETURN a.prop +LIMIT 100 +---- + +.Variables and expressions involving variables are (in general) not constant, and may not be used as arguments to `LIMIT`: +[source, cypher] +---- +MATCH (a:Label) +LIMIT a.prop // not guaranteed to be constant -- error! +RETURN a.prop +LIMIT size((a)-->()) // not guaranteed to be constant -- error! +---- ==== Updating queries -The use of `LIMIT` opens the possibility for certain performance optimisations. -Clauses that come early in the query do not have to be evaluated over the full dataset, just enough to reach the subsequent limit. +The use of `LIMIT` opens up the possibility for certain performance optimisations. +Clauses appearing earlier in the query only need to be evaluated until the limit is reached, as opposed to evaluating the entire dataset. These optimisations are however not always applicable in combination with updating clauses. Semantics between clauses is defined such that _all_ of a previous clause is processed (logically) before _any_ of a subsequent clause is processed. -This means that _all_ side effects must happen before a `LIMIT` is allowed to halt the processing of records in preceding clauses. +This means that _all_ side effects must happen before a `LIMIT` is allowed to terminate the processing of records in preceding clauses. -Consider the below query: +Consider the following query: -.Create a producer for each item, return first 100 product ids. +.Create a producer for each item, returning the first 100 product ids. [source, cypher] ---- MATCH (i:Item) @@ -59,7 +78,7 @@ This query must execute its `CREATE` clause once for every `:Item` node, even th If the user intention is to only do a partial update of the graph, the query must be rewritten: -.Create a producer for the 100 first items, return their product ids. +.Create a producer for the top 100 items, and return their product ids. [source, cypher] ---- MATCH (i:Item)