Skip to content

Commit f8f8d69

Browse files
Add mandatory GQL features (#991)
1 parent 9a748b9 commit f8f8d69

File tree

7 files changed

+357
-99
lines changed

7 files changed

+357
-99
lines changed

modules/ROOT/content-nav.adoc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@
125125
* Appendix
126126
** xref:styleguide.adoc[]
127127
** xref:appendix/gql-conformance/index.adoc[]
128+
*** xref:appendix/gql-conformance/supported-mandatory.adoc[]
128129
*** xref:appendix/gql-conformance/unsupported-mandatory.adoc[]
129130
*** xref:appendix/gql-conformance/supported-optional.adoc[]
130131
*** xref:appendix/gql-conformance/analogous-cypher.adoc[]

modules/ROOT/pages/appendix/gql-conformance/analogous-cypher.adoc

Lines changed: 1 addition & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ This page lists optional GQL features that have analogous but not identical Cyph
66
Optional GQL features are assigned a feature ID code.
77
These codes order the features in the table below.
88

9-
[options="header",cols="a,3a,5a"]
9+
[options="header",cols="2a,3a,5a"]
1010
|===
1111
| GQL Feature ID
1212
| Description
@@ -16,16 +16,6 @@ These codes order the features in the table below.
1616
| `ELEMENT_ID` function
1717
| GQL's `ELEMENT_ID()` function is equivalent to Cypher's xref:functions/scalar.adoc#functions-elementid[`elementId()`] function.
1818

19-
| GF01
20-
| Enhanced numeric functions
21-
| GQL supports `CEILING()` as a synonym to the `CEIL()` function.
22-
Cypher only supports xref:functions/mathematical-numeric.adoc#functions-ceil[`ceil()`].
23-
24-
| GF03
25-
| Logarithmic functions
26-
| * Cypher uses the xref:functions/mathematical-logarithmic.adoc#functions-log[`log()`] function instead of GQL's `LN()` function.
27-
* Cypher uses the xref:syntax/operators.adoc#syntax-using-the-exponentiation-operator[exponentiation operator (`^`)] instead of GQL's `POWER()` function.
28-
2919
| GF04
3020
| Enhanced path functions
3121
| GQL's `PATH_LENGTH()` function is equivalent to Cypher's xref:functions/scalar.adoc#functions-length[`length()`] function.
@@ -69,25 +59,6 @@ Unlike the `FOR` statement, `UNWIND` does not support yielding indexes and offse
6959
| 64-bit floating number
7060
| GQL’s `FLOAT64` type is equivalent to Cypher’s xref:values-and-types/property-structural-constructed.adoc#_property_type_details[`FLOAT`] type.
7161

72-
| GV39
73-
| xref:values-and-types/temporal.adoc[Temporal types: date, local datetime, and local time support]
74-
| Cypher supports GQL’s local temporal types, with the following exceptions:
75-
76-
* GQL defines a parameterless version of the xref:functions/temporal/index.adoc#functions-date[`date()`] function not in Cypher: `CURRENT_DATE`.
77-
* GQL’s `LOCAL_TIME()` function is equivalent to Cypher’s xref:functions/temporal/index.adoc#functions-localtime[`localtime()`] function.
78-
GQL also defines a parameterless version of the function not in Cypher: `LOCAL_TIME`.
79-
* GQL’s `LOCAL_DATETIME()` function is equivalent to Cypher’s xref:functions/temporal/index.adoc#functions-localdatetime[`localdatetime()`] function.
80-
GQL also defines a parameterless version of the function not in Cypher: `LOCAL_DATETIME`.
81-
82-
| GV40
83-
| xref:values-and-types/temporal.adoc[Temporal types: zoned datetime and zoned time support]
84-
| Cypher supports GQL’s zoned temporal types, with the following exceptions:
85-
86-
* GQL’s `ZONED_TIME()` function is equivalent to Cypher’s xref:functions/temporal/index.adoc#functions-time[`time()`] function.
87-
GQL also defines a parameterless version of the function not in Cypher: `CURRENT_TIME`.
88-
* GQL’s `ZONED_DATETIME()` function is equivalent to Cypher’s xref:functions/temporal/index.adoc#functions-datetime[`datetime()`] function.
89-
GQL also defines a parameterless version of the function not in Cypher: `CURRENT_TIMESTAMP`.
90-
9162
| GV45
9263
| Record types
9364
| GQL's open `RECORD` type is equivalent to the xref:values-and-types/maps.adoc[`MAP`] type in Cypher.

modules/ROOT/pages/appendix/gql-conformance/index.adoc

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
:description: Overview of Cypher's conformance to GQL.
22
= GQL conformance
33

4-
*Last updated*: 11 June 2024 +
4+
*Last updated*: 5 July 2024 +
55
*Neo4j version*: 5.21
66

77
GQL is the new link:https://www.iso.org/home.html[ISO] International Standard query language for graph databases.
@@ -19,16 +19,15 @@ WHERE a.name = 'Tom Hanks'
1919
RETURN m.title
2020
----
2121

22-
Neo4j is working towards full GQL conformance (meaning full support of its mandatory features).
23-
There are, however, currently some mandatory GQL features not implemented in Cypher.
22+
Cypher supports the majority of mandatory GQL features.
23+
For a full list, see xref:appendix/gql-conformance/supported-mandatory.adoc[].
24+
There are, however, currently a few mandatory GQL features not implemented in Cypher.
2425
These are listed in the page xref:appendix/gql-conformance/unsupported-mandatory.adoc[].
2526

2627
Neo4j is also working towards increasing its support of optional GQL features.
2728
These are listed in the page xref:appendix/gql-conformance/supported-optional.adoc[].
2829

2930
Additionally, some optional GQL features not yet implemented in Cypher already have analogous Cypher equivalents.
30-
For example, Cypher and GQL support a function to return the local time.
31-
In Cypher, this is called xref:functions/temporal/index.adoc#functions-localtime[`localtime()`]; in GQL, it is called `LOCAL_TIME()`.
3231
These features are listed in the page xref:appendix/gql-conformance/analogous-cypher.adoc[].
3332

3433
[[gql-minimum-conformance]]
@@ -43,5 +42,5 @@ Neo4j 5.14 added support for JavaSE 21 and version 15 of the Unicode Standard.
4342
For more information, see xref:syntax/parsing.adoc##_using_unicodes_in_cypher[Parsing -> Using Unicode in Cypher].
4443
* Cypher supports the following mandatory GQL property types: `BOOLEAN` (`BOOL`), `FLOAT` footnote:[The `FLOAT` type in Cypher always represents a 64-bit double-precision floating point number.], `INTEGER` (`SIGNED INTEGER`, or `INT`)footnote:[The `INTEGER` type in Cypher always represents a 64-bit `INTEGER`.], and `STRING` (`VARCHAR`).
4544
+
46-
Cypher also supports: `DATE`, `DURATION`, `LIST<INNER_TYPE NOT NULL>` (`ARRAY<INNER_TYPE NOT NULL>`, `INNER_TYPE LIST`, or `INNER_TYPE ARRAY`)footnote:[The `INNER_TYPE` cannot be a `LIST` type.], `LOCAL DATETIME` (`TIMESTAMP WITHOUT TIMEZONE`), `LOCAL TIME` (`TIME WITHOUT TIME ZONE`), `POINT`, `ZONED DATETIME` (`TIME WITH TIMEZONE`), and `ZONED TIME` (`TIMESTAMP WITH TIMEZONE`).
45+
Cypher also supports the following optional GQL property types: `DATE`, `DURATION`, `LIST<INNER_TYPE NOT NULL>` (`ARRAY<INNER_TYPE NOT NULL>`, `INNER_TYPE LIST`, or `INNER_TYPE ARRAY`)footnote:[The `INNER_TYPE` cannot be a `LIST` type.], `LOCAL DATETIME` (`TIMESTAMP WITHOUT TIMEZONE`), `LOCAL TIME` (`TIME WITHOUT TIME ZONE`), `POINT`, `ZONED DATETIME` (`TIME WITH TIMEZONE`), and `ZONED TIME` (`TIMESTAMP WITH TIMEZONE`).
4746
For more information, see xref:values-and-types/property-structural-constructed.adoc#_property_types[Values and types -> property types].
Lines changed: 231 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,231 @@
1+
:description: Information about mandatory GQL features supported by Cypher.
2+
= Supported mandatory GQL features
3+
4+
Unlike optional GQL features, mandatory GQL features are not assigned a GQL feature ID code.
5+
The below table is instead listed in order of their appearance in the link:https://www.iso.org/standard/76120.html[ISO/IEC 39075:2024(en) GQL Standard].
6+
7+
[options="header",cols="2a,3a,2a,5a"]
8+
|===
9+
| GQL Standard subclause
10+
| Description
11+
| Documentation
12+
| Comment
13+
14+
| 4.11
15+
| Graph pattern matching
16+
| xref:patterns/index.adoc[]
17+
|
18+
19+
| 4.13
20+
| GQL object types
21+
| xref:values-and-types/property-structural-constructed.adoc#structural-types[Structural types], xref:values-and-types/property-structural-constructed.adoc#type-synonyms[Types and their synonyms].
22+
| Includes: `NODE` (`ANY NODE`, `VERTEX`, `ANY VERTEX`) and `RELATIONSHIP` (`ANY RELATIONSHIP`, `EDGE`, `ANY EDGE`).
23+
24+
| 4.16
25+
| Predefined value types
26+
| xref:values-and-types/property-structural-constructed.adoc#property-types[Property types], xref:values-and-types/property-structural-constructed.adoc#type-synonyms[Types and their synonyms].
27+
| Includes: `BOOLEAN` (`BOOL`), `FLOAT`, `INTEGER` (`SIGNED INTEGER`, `INT`), and `STRING` (`VARCHAR`).
28+
29+
Cypher supports the boolean type predicate for `TRUE`, `FALSE`, and `NULL` but does not support the GQL keyword `UNKNOWN`.
30+
31+
| 13.2
32+
| <insert statement>
33+
| xref:clauses/create.adoc#insert-as-synonym-of-create[`INSERT`]
34+
|
35+
36+
| 13.3
37+
| <set statement>
38+
| xref:clauses/set.adoc[`SET`]
39+
| GQL’s `SET` has no order dependencies because all right-hand side operations are completed before any assignments occur.
40+
In Cypher’s `SET`, the order of rows can affect the outcome because changes made during execution may depend on the sequence of assignments.
41+
The only way to guarantee row order in Neo4j is to use xref:clauses/order-by.adoc[`ORDER BY`].
42+
43+
| 13.4
44+
| <remove statement>
45+
| xref:clauses/remove.adoc[`REMOVE`]
46+
|
47+
48+
| 13.5
49+
| <delete statement>
50+
| xref:clauses/delete.adoc[`DELETE`]
51+
|
52+
53+
| 14.4
54+
| <match statement>
55+
| xref:clauses/match.adoc[`MATCH`], xref:clauses/optional-match.adoc[`OPTIONAL MATCH`]
56+
|
57+
58+
| 14.9
59+
| <order by and page statement>
60+
| xref:clauses/skip.adoc[`SKIP`]
61+
| Cypher only supports `SKIP`, which is a GQL-supported synonym to `OFFSET`.
62+
63+
64+
| 14.10
65+
| <primitive result statement>
66+
| xref:clauses/finish.adoc[`FINISH`]
67+
|
68+
69+
| 14.11
70+
| <return statement>
71+
| xref:clauses/return.adoc[`RETURN`]
72+
|
73+
74+
| 15.1
75+
| <call procedure statement> and <procedure call>
76+
| xref:clauses/call.adoc[`CALL` procedures], xref:subqueries/call-subquery.adoc[`CALL` subqueries].
77+
| GQL defines an `OPTIONAL CALL` statement, enabling optional procedure and subquery calling.
78+
This is not available in Cypher.
79+
80+
| 15.2
81+
| <inline procedure call>
82+
| xref:subqueries/call-subquery.adoc[`CALL` subqueries].
83+
| GQL either imports variables implicitly, or explicitly using a variable scope clause.
84+
In Cypher, `CALL` subqueries require an explicit importing `WITH` clause.
85+
86+
| 15.3
87+
| <named procedure call>
88+
| xref:clauses/call.adoc[`CALL` procedure]
89+
|
90+
91+
| 16.2
92+
| <limit clause>
93+
| xref:clauses/limit.adoc[`LIMIT`]
94+
|
95+
96+
| 16.4
97+
| <graph pattern>
98+
| xref:patterns/reference.adoc#graph-patterns[Graph patterns]
99+
|
100+
101+
| 16.5
102+
| <insert graph pattern>
103+
| xref:clauses/create.adoc#[`CREATE`]
104+
|
105+
106+
| 16.6
107+
| <order by clause>
108+
| xref:clauses/order-by.adoc[`ORDER-BY`]
109+
|
110+
111+
| 16.7
112+
| <path pattern expression>
113+
| xref:patterns/reference.adoc#path-patterns[Path patterns]
114+
|
115+
116+
| 16.8
117+
| <label expression>
118+
| xref:patterns/reference.adoc#label-expressions[Label expressions]
119+
|
120+
121+
| 16.9
122+
| <path variable reference>
123+
| xref:patterns/reference.adoc[Patterns -> Syntax and semantics]
124+
|
125+
126+
| 16.11
127+
| <graph pattern quantifier>
128+
| xref:patterns/reference.adoc#quantifiers[Quantifiers]
129+
|
130+
131+
| 16.17
132+
| <sort specification list>
133+
| xref:clauses/order-by.adoc#order-nodes-in-descending-order[Order results in ascending or descending order]
134+
|
135+
136+
| 16.19
137+
| <offset clause>
138+
| xref:clauses/skip.adoc[`SKIP`]
139+
| Cypher only supports `SKIP` , which is a GQL-supported synonym to `OFFSET`.
140+
141+
| 19.3
142+
| <comparison predicate>
143+
| xref:syntax/operators.adoc##query-operators-comparison[Comparison operators]
144+
|
145+
146+
| 19.4
147+
| <exists predicate>
148+
| xref:functions/predicate.adoc#function-exists[`exists()`]
149+
|
150+
151+
| 19.5
152+
| <null predicate>
153+
| xref:values-and-types/type-predicate.adoc#type-predicate-null[Type predicate expressions for `NULL`]
154+
|
155+
156+
| 19.6
157+
| <value type predicate>
158+
| xref:values-and-types/type-predicate.adoc#[]
159+
|
160+
161+
| 19.7
162+
| <normalized predicate>
163+
| xref:syntax/operators.adoc#match-string-is-normalized[`IS NORMALIZED`], xref:syntax/operators.adoc#match-string-is-not-normalized[`IS NOT NORMALIZED`]
164+
|
165+
166+
| 20.2
167+
| <value expression primary>
168+
| xref:queries/expressions.adoc[]
169+
|
170+
171+
| 20.3
172+
| <value specification>
173+
|
174+
| GQL defines the `SESSION_USER` value expression, which enables accessing a user’s username within a query.
175+
In Cypher, current user details can be seen using the link:{neo4j-docs-base-uri}/operations-manual/{page-version}/authentication-authorization/manage-users/#access-control-current-users[`SHOW CURRENT USER` command].
176+
177+
| 20.7
178+
| <case expression>
179+
| xref:queries/case.adoc[`CASE`], xref:functions/scalar.adoc#functions-nullIf[`nullIf()`], xref:functions/scalar.adoc#functions-coalesce[`coalesce()`]
180+
|
181+
182+
| 20.9
183+
| <aggregate function>
184+
| xref:functions/aggregating.adoc#functions-avg[`avg()`], xref:functions/aggregating.adoc#functions-count[`count()`], xref:functions/aggregating.adoc#functions-max[`max`], xref:functions/aggregating.adoc#functions-mind[`min()`], xref:functions/aggregating.adoc#functions-sum[`sum()`]
185+
| Cypher and GQL handle `NULL` values differently for the `sum()` function when queries return 0 rows.
186+
For example, `RETURN sum(<expr>)` on an empty table returns `NULL` in GQL, but in Cypher it returns `0`.
187+
188+
| 20.11
189+
| <property reference>
190+
| xref:queries/concepts.adoc[Core concepts]
191+
|
192+
193+
| 20.21
194+
| <numeric value expression>
195+
| xref:syntax/operators.adoc#query-operators-mathematical[Mathematical operators]
196+
|
197+
198+
| 20.22
199+
| <numeric value function>
200+
| xref:functions/scalar.adoc#functions-char_length[`char_length()`], xref:functions/scalar.adoc#functions-character_length[`character_length()`]
201+
|
202+
203+
| 20.23
204+
| <string value expression>
205+
| xref:syntax/operators.adoc#syntax-concatenating-two-strings-doublebar[`STRING` concatenation operator (`\|\|`)]
206+
|
207+
208+
| 20.24
209+
| <character string function>
210+
| xref:functions/string.adoc#functions-left[`left()`], xref:functions/string.adoc#functions-lower[`lower()`], xref:functions/string.adoc#functions-normalize[`normalize()`], xref:functions/string.adoc#functions-right[`right()`], xref:functions/string.adoc#functions-trim[`trim()`], xref:functions/string.adoc#functions-upper[`upper()`]
211+
| In GQL, `TRIM()` removes only space characters.
212+
In Cypher, `trim()` removes any whitespace character.
213+
214+
| 21.1
215+
| Names and variables
216+
| xref:syntax/index.adoc[]
217+
| Cypher supports GQL’s lexical elements, with the following caveats:
218+
219+
* GQL allows for extended parameter identifiers.
220+
For example: `RETURN $0hello` is allowed in GQL but not Cypher.
221+
* GQL allows identifiers that are not variables to be delimited with both backticks and quotes.
222+
Cypher only allows backticks.
223+
For example: `MATCH (n) RETURN n."a prop"` is allowed in GQL but not Cypher.
224+
225+
| 22.15
226+
| Grouping operations
227+
| xref:functions/aggregating.adoc##counting_with_and_without_duplicates[Counting with and without duplicates]
228+
|
229+
230+
|===
231+

0 commit comments

Comments
 (0)