You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: cip/1.accepted/CIP2017-04-20-query-combinators-for-set-operations.adoc
+18-31Lines changed: 18 additions & 31 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,4 +1,4 @@
1
-
= CIP2017-04-20 - Query Combinators
1
+
= CIP2017-04-20 - Query combinators for set operations
2
2
:numbered:
3
3
:toc:
4
4
:toc-placement: macro
@@ -9,7 +9,7 @@
9
9
[abstract]
10
10
.Abstract
11
11
--
12
-
This CIP codifies the pre-existing `UNION` and `UNION ALL` clauses, and proposes additional query combinators for set operations and pipelining.
12
+
This CIP codifies the pre-existing `UNION` and `UNION ALL` clauses, and proposes additional query combinators for set operations.
13
13
--
14
14
15
15
toc::[]
@@ -23,12 +23,12 @@ Adding more query combinators to Cypher will increase language expressivity and
23
23
24
24
The vast majority of Cypher clauses are underpinned by sequential composition; i.e. the records produced by the first clause act as an input to the next clause and so on.
25
25
However, some operations require multiple streams of records as inputs.
26
-
These are called _query combinators_.
26
+
These are called _query combinators_ (CIP2016-06-22 Nested, updating, and chained subqueries).
27
27
The most notable example of query combinators are _set operations_.
28
28
29
29
== Proposal
30
30
31
-
This CIP proposes the introduction of several new multi-arm query combinators:
31
+
This CIP proposes the specification of pre-existing and the introduction of several new query combinators for set operations:
32
32
33
33
* `UNION`
34
34
* `UNION ALL`
@@ -41,24 +41,19 @@ This CIP proposes the introduction of several new multi-arm query combinators:
41
41
* `EXCLUSIVE UNION MAX`
42
42
* `OTHERWISE`
43
43
* `CROSS`
44
-
* `THEN`
45
44
46
-
Multi-arm query combinators can only be used to constuct a compound multi-arm query using the syntax `<query> [<combinator> <query>]+`.
45
+
Query combinators are used to construct a (compound) top-level query from two input queries: a left-hand side top-level query and a right-hand side argument query, i.e. always have the form
46
+
`<top-level-query> <combinator> <argument-query>`(where `<combinator>` may be any of the combinators given above).
47
+
Query combinators are left-associative; that is, their operations are grouped from the left.
47
48
48
-
The `<combinator>` can be any of the combinators given above.
49
-
Multi-arm query combinators are interpreted left-associative; that is, the operations are grouped from the left.
50
-
Thus, for the remainder of this proposal, we only consider combinator semantics regarding two arms (left and right) -- the semantics follow on straightforwardly by induction for the multi-arm cases.
49
+
For all proposed query combinators -- except for `CROSS` -- the fields returned are subject to the following standard rules:
51
50
52
-
For all proposed query combinators -- excluding `CROSS` and `THEN` -- the fields returned are subject to the following standard rules:
51
+
* Both input queries must return precisely the same set of variables
52
+
* If both input queries specify the order of returned variables explicitly, they must both return those variables in exactly the same order.
53
+
* If one of the input queries does not specify the order of returned variables explicitly (e.g. by using `RETURN *`), then the other input query must specify the order of returned variables explicitly.
54
+
This order will then be the order in which variables are returned by the query combinator.
55
+
* If both input queries do not specify the order of returned variables explicitly (e.g. by using `RETURN *`), variables are returned in the same order as map keys (i.e. sorted according to their UNICODE name).
53
56
54
-
* The `RETURN` clause of each arm is either a `RETURN *` or specifies record fields explicitly (e.g. `RETURN n.prop1, n.prop2, ...`).
55
-
* If both arms specify record fields explicitly, then they must specify precisely the same set of record fields (by name) in exactly the same order.
56
-
* If one of the arms, _arm1_, ends with `RETURN *`, and the other arm, _arm2_, specifies record fields explicitly, then _arm1_ must implicitly return exactly the same set of record fields as _arm2_; i.e. the arm with the explicitly-defined record fields will determine which record fields are returned as well as the order thereof.
57
-
* If both arms end with `RETURN *`, they must return exactly the same set of record fields.
58
-
* If both arms end with `RETURN *`, the order of record fields is unspecified and left to the implementation.
59
-
60
-
Multi-arm query combinators may determine the result signature of a top-level query.
61
-
If any arm specifies record fields explicitly, the same set of record fields in exactly the same order is returned by the entire query.
62
57
63
58
=== UNION
64
59
@@ -75,6 +70,7 @@ If any arm specifies record fields explicitly, the same set of record fields in
75
70
76
71
`INTERSECT ALL` computes the logical multiset intersection between two bags of input records (i.e. shared duplicates are retained).
77
72
73
+
78
74
=== EXCEPT
79
75
80
76
`EXCEPT` computes the logical set difference between two sets of input records (i.e. any duplicates are discarded).
@@ -87,30 +83,21 @@ If any arm specifies record fields explicitly, the same set of record fields in
87
83
88
84
`EXCLUSIVE UNION MAX` computes the exclusive logical multiset union between two bags of input records (i.e. the largest remaining excess multiplicity of each record in any argument bag is returned).
89
85
86
+
90
87
=== OTHERWISE
91
88
92
89
`OTHERWISE` computes the logical choice between two bags of input records.
93
90
It evaluates to all records from the left-hand side argument provided the bag of input records is non-empty; otherwise it evaluates to all records from the right-hand side argument.
94
91
92
+
95
93
=== CROSS
96
94
97
95
`CROSS` computes the cartesian product between two bags of input records (i.e. preserves duplicates).
98
96
99
97
In contrast to the other query combinators, the standard rules regarding returned record fields do not apply to `CROSS`.
100
-
Instead, the set of returned record fields of both arms of a `CROSS` must be non-overlapping.
101
-
The returned record fields of a `CROSS` operation consist of all the fields specified in the left arm (appearing in the order specified), followed by all the fields specified in the right arm (appearing in the order specified).
102
-
103
-
=== THEN
104
-
105
-
`THEN` computes query-level pipelining; i.e. it executes the right-hand side query for each input record from the left-hand side, and returns the flattened concatenation of all such records produced.
106
-
107
-
The main feature of `THEN` is that it allows pipelining between nested subqueries.
108
-
This is due to its syntactic status as a query combinator.
98
+
Instead, the set of variables returned from both input queries of a `CROSS` must be non-overlapping.
99
+
The returned variables of a `CROSS` operation consist of all the variables returned by the left-hand side input query (appearing in the order specified), followed by all the variables returned by the right-hand side input query (appearing in the order specified).
109
100
110
-
In contrast to the other query combinators, the standard rules regarding returned record fields do not apply to `THEN`.
111
-
Instead, the set of returned record fields of both arms of `THEN` may overlap arbitrarily.
112
-
All record fields that are returned in the left arm are made visible at the start of the right-arm query.
113
-
`THEN` returns the record fields that are specified in the right arm, in the order specified in the right arm.
0 commit comments