Skip to content

Commit f33cbba

Browse files
Merge branch 'dev' into 5.x-deprecate-existingDataSeedInstance
2 parents 51b482c + c4de60d commit f33cbba

File tree

7 files changed

+162
-82
lines changed

7 files changed

+162
-82
lines changed

antora.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,5 @@ nav:
77
asciidoc:
88
attributes:
99
neo4j-version: '5'
10-
neo4j-version-minor: '5.24'
11-
neo4j-version-exact: '5.24.0'
10+
neo4j-version-minor: '5.25'
11+
neo4j-version-exact: '5.25.0'

modules/ROOT/images/call_subquery_graph.svg

Lines changed: 5 additions & 5 deletions
Loading

modules/ROOT/pages/deprecations-additions-removals-compatibility.adoc

Lines changed: 86 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ OPTIONAL CALL db.labels() YIELD label
8484
RETURN label
8585
----
8686

87-
| Introduced `OPTIONAL CALL` for optionally executing a xref:clauses/call.adoc#optiona-call[procedure] or xref:subqueries/call-subquery.adoc#optional-call[subquery] `CALL`.
87+
| Introduced `OPTIONAL CALL` for optionally executing a xref:clauses/call.adoc#optional-call[procedure] or xref:subqueries/call-subquery.adoc#optional-call[subquery] `CALL`.
8888
Similar to xref:clauses/optional-match.adoc[`OPTIONAL MATCH`], any empty rows produced by the `OPTIONAL CALL` will return `null` and not affect the remainder of the procedure or subquery evaluation.
8989

9090
a|
@@ -134,6 +134,18 @@ REMOVE n[$prop]
134134
----
135135
| Added the ability to dynamically reference properties in xref:clauses/set.adoc#set-dynamically-a-property[SET] and xref:clauses/remove.adoc#remove-remove-a-property-dynamically[REMOVE] clauses.
136136

137+
a|
138+
label:functionality[]
139+
label:new[]
140+
[source, cypher, role=noheader]
141+
----
142+
DROP [COMPOSITE] DATABASE ... [RESTRICT \| CASCADE ALIAS[ES]]
143+
----
144+
145+
| Added the ability to drop database aliases while deleting a database.
146+
This will affect local database aliases targeting the database and constituent database aliases belonging to the composite database.
147+
For more information, see link:{neo4j-docs-base-uri}/operations-manual/{page-version}/database-administration/standard-databases/delete-databases/#delete-databases-with-aliases[Delete a database with local database aliases targeting it] and link:{neo4j-docs-base-uri}/operations-manual/{page-version}/database-administration/composite-databases/delete-composite-databases/#composite-databases-delete-with-aliases[Delete a composite database with constituent database aliases].
148+
137149
a|
138150
label:functionality[]
139151
label:new[]
@@ -146,6 +158,62 @@ RETURN a.name, a.year
146158

147159
| Extension of the xref:clauses/load-csv.adoc#azure-cloud-storage[LOAD CSV] clause to allow loading CSV files from Azure Cloud Storage URIs.
148160

161+
a|
162+
label:functionality[]
163+
label:new[]
164+
[source, cypher, role=noheader]
165+
----
166+
CREATE USER bob
167+
SET AUTH 'externalProviderName' {
168+
SET ID 'userIdForExternalProvider'
169+
}
170+
SET AUTH 'native' {
171+
SET PASSWORD 'password'
172+
SET PASSWORD CHANGE REQUIRED
173+
}
174+
----
175+
| Added the ability set which link:{neo4j-docs-base-uri}/operations-manual/{page-version}/authentication-authorization/auth-providers[auth providers] apply to a user (Enterprise Edition).
176+
177+
Administration of the native (username / password) auth via the new syntax is also now supported (Community Edition).
178+
179+
a|
180+
label:functionality[]
181+
label:new[]
182+
[source, cypher, role=noheader]
183+
----
184+
ALTER USER bob
185+
REMOVE AUTH 'native'
186+
SET AUTH 'externalProviderName' {
187+
SET ID 'userIdForExternalProvider'
188+
}
189+
----
190+
| Added the ability add and remove user link:{neo4j-docs-base-uri}/operations-manual/{page-version}/authentication-authorization/auth-providers[auth providers] via the `ALTER USER` command.
191+
192+
Setting the native (username / password) auth provider via this new syntax is also supported (Community Edition), but removing any auth provider or setting a non-native auth provider is only supported in Enterprise Edition.
193+
194+
195+
a|
196+
label:functionality[]
197+
label:new[]
198+
[source, cypher, role="noheader"]
199+
----
200+
SHOW USERS WITH AUTH
201+
----
202+
a|
203+
New support for `WITH AUTH` to allow display users' auth providers with a separate row per user per auth provider.
204+
205+
a|
206+
label:functionality[]
207+
label:new[] +
208+
[source, cypher, role="noheader"]
209+
----
210+
SET AUTH
211+
----
212+
a|
213+
New privilege that allows a user to modify user link:{neo4j-docs-base-uri}/operations-manual/{page-version}/authentication-authorization/auth-providers[auth providers].
214+
This is a sub-privilege of the `ALTER USER` privilege.
215+
Like all `GRANT`/`DENY` commands this is only available in Enterprise Edition.
216+
149217
|===
150218

151219
[[cypher-deprecations-additions-removals-5.23]]
@@ -277,6 +345,23 @@ The column is a `STRING` value specifying a replacement function/procedure if th
277345
| Feature
278346
| Details
279347

348+
a|
349+
label:functionality[]
350+
label:new[]
351+
[source, cypher, role=noheader]
352+
----
353+
GRANT READ {*} ON GRAPH * FOR (n) WHERE n.securityLevel > 3 TO regularUsers
354+
----
355+
[source, cypher, role=noheader]
356+
----
357+
GRANT TRAVERSE ON GRAPH * FOR (n:Email) WHERE n.classification IS NULL TO regularUsers
358+
----
359+
[source, cypher, role=noheader]
360+
----
361+
DENY MATCH {*} ON GRAPH * FOR (n) WHERE n.classification <> 'UNCLASSIFIED' TO regularUsers
362+
----
363+
| Introduction of link:{neo4j-docs-base-uri}/operations-manual/{page-version}/authentication-authorization/property-based-access-control[property-based access control] for read privileges. The ability to read, traverse and match nodes based on node property values is now supported in Enterprise Edition.
364+
280365
a|
281366
label:functionality[]
282367
label:new[]
@@ -288,7 +373,6 @@ RETURN a.name, a.year
288373
----
289374
| Extension of the xref:clauses/load-csv.adoc#google-cloud-storage[LOAD CSV] clause to allow loading CSV files from Google Cloud Storage URIs.
290375

291-
292376
a|
293377
label:functionality[]
294378
label:new[]

modules/ROOT/pages/subqueries/call-subquery.adoc

Lines changed: 45 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,9 @@ CREATE (teamA:Team {name: 'Team A'}),
3030
(playerF:Player {name: 'Player F', age: 35}),
3131
(playerA)-[:PLAYS_FOR]->(teamA),
3232
(playerB)-[:PLAYS_FOR]->(teamA),
33-
(playerC)-[:PLAYS_FOR]->(teamA),
3433
(playerD)-[:PLAYS_FOR]->(teamB),
3534
(playerE)-[:PLAYS_FOR]->(teamC),
3635
(playerF)-[:PLAYS_FOR]->(teamC),
37-
(playerA)-[:FRIEND_OF]->(playerB),
38-
(playerA)-[:FRIEND_OF]->(playerC),
39-
(playerB)-[:FRIEND_OF]->(playerF),
40-
(playerC)-[:FRIEND_OF]->(playerD),
4136
(teamA)-[:OWES {dollars: 1500}]->(teamB),
4237
(teamA)-[:OWES {dollars: 3000}]->(teamB),
4338
(teamB)-[:OWES {dollars: 1700}]->(teamC),
@@ -92,7 +87,6 @@ CALL () {
9287
SET p.age = p.age + 1
9388
RETURN p.age AS newAge
9489
}
95-
WITH x, newAge
9690
MATCH (p:Player {name: 'Player A'})
9791
RETURN x AS iteration, newAge, p.age AS totalAge
9892
----
@@ -139,7 +133,7 @@ RETURN t AS team, players
139133
| players
140134
141135
| (:Team {name: "Team A"})
142-
| [(:Player {name: "Player C", age: 19}), (:Player {name: "Player B", age: 23}), (:Player {name: "Player A", age: 24})]
136+
| (:Player {name: "Player B", age: 23}), (:Player {name: "Player A", age: 24})]
143137
144138
| (:Team {name: "Team B"})
145139
| [(:Player {name: "Player D", age: 30})]
@@ -432,60 +426,60 @@ Similar to xref:clauses/optional-match.adoc[`OPTIONAL MATCH`] any empty rows pro
432426
.Difference between using `CALL` and `OPTIONAL CALL`
433427
====
434428
435-
This example, which finds the friends of each `Player` and xref:functions/aggregating.adoc#functions-count[counts] the number of friends per player, highlights the difference between using `CALL` and `OPTIONAL CALL`.
429+
This example, which finds the team that each `Player` plays for, highlights the difference between using `CALL` and `OPTIONAL CALL`.
436430
437431
.Regular subquery `CALL`
438432
[source, cypher]
439433
----
440434
MATCH (p:Player)
441435
CALL (p) {
442-
MATCH (p)-[:FRIEND_OF]->(friend:Player)
443-
RETURN friend
436+
MATCH (p)-[:PLAYS_FOR]->(team:Team)
437+
RETURN team
444438
}
445-
RETURN p.name AS playerName, count(friend) AS numberOfFriends
446-
ORDER BY numberOfFriends
439+
RETURN p.name AS playerName, team.name AS team
447440
----
448441
449-
.Optional subquery `CALL`
442+
.Result
450443
[role="queryresult",options="header,footer",cols="2*m"]
451444
|===
452-
| playerName | numberOfFriends
445+
| playerName | team
453446
454-
| "Player B" | 1
455-
| "Player C" | 1
456-
| "Player A" | 2
447+
| "Player A" | "Team A"
448+
| "Player B" | "Team A"
449+
| "Player D" | "Team B"
450+
| "Player E" | "Team C"
451+
| "Player F" | "Team C"
457452
458-
2+d|Rows: 3
453+
2+d|Rows: 5
459454
|===
460455
461-
Note that no results are returned for `Player D`, `Player E`, and `Player F`, since they have no outgoing `FRIEND_OF` relationships connected to them.
456+
Note that no results are returned for `Player C`, since they are not connected to any `Team` with a `PLAYS_FOR` relationship.
462457
463458
.Query using regular `OPTIONAL CALL`
464459
[source, cypher]
465460
----
466461
MATCH (p:Player)
467462
OPTIONAL CALL (p) {
468-
MATCH (p)-[:FRIEND_OF]->(friend:Player)
469-
RETURN friend
463+
MATCH (p)-[:PLAYS_FOR]->(team:Team)
464+
RETURN team
470465
}
471-
RETURN p.name AS playerName, count(friend) AS numberOfFriends
472-
ORDER BY numberOfFriends
466+
RETURN p.name AS playerName, team.name AS team
473467
----
474468
475-
Now, all `Player` nodes, regardless of whether they have any friends or not, are returned.
476-
(Those without any outgoing `FRIEND_OF` relationships are returned with the result `0` because `count()` ignores `null` values.)
469+
Now all `Player` nodes, regardless of whether they have any `PLAYS_FOR` relationships connected to a `Team`, are returned.
477470
471+
.Result
478472
.Result
479473
[role="queryresult",options="header,footer",cols="2*m"]
480474
|===
481-
| playerName | numberOfFriends
475+
| playerName | team
482476
483-
| "Player D" | 0
484-
| "Player E" | 0
485-
| "Player F" | 0
486-
| "Player B" | 1
487-
| "Player C" | 1
488-
| "Player A" | 2
477+
| "Player A" | "Team A"
478+
| "Player B" | "Team A"
479+
| "Player C" | NULL
480+
| "Player D" | "Team B"
481+
| "Player E" | "Team C"
482+
| "Player F" | "Team C"
489483
490484
2+d|Rows: 6
491485
|===
@@ -495,8 +489,8 @@ Now, all `Player` nodes, regardless of whether they have any friends or not, are
495489
[[call-execution-order]]
496490
== Execution order of CALL subqueries
497491

498-
The order in which subqueries are executed is not defined.
499-
If a query result depends on the order of execution of subqueries, an `ORDER BY` clause should precede the `CALL` clause.
492+
The order in which rows from the outer scope are passed into subqueries is not defined.
493+
If the results of the subquery depend on the order of these rows, use an `ORDER BY` clause before the `CALL` clause to guarantee a specific processing order for the rows.
500494

501495
.Ordering results before `CALL` subquery
502496
====
@@ -590,13 +584,13 @@ UNION
590584
ORDER BY p.age DESC
591585
LIMIT 1
592586
}
593-
RETURN p.name AS name, p.age AS age
587+
RETURN p.name AS playerName, p.age AS age
594588
----
595589
596590
.Result
597591
[role="queryresult",options="header,footer",cols="2*<m"]
598592
|===
599-
| name | age
593+
| playerName | age
600594
| "Player C" | 19
601595
| "Player F" | 35
602596
2+d|Rows: 2
@@ -641,39 +635,33 @@ The result of the `CALL` subquery is the combined result of evaluating the subqu
641635

642636
.`CALL` subquery changing returned rows of outer query
643637
====
644-
The following example finds the name of each `Player` and the names of their friends.
645-
No rows are returned for the `Player` nodes without any `FRIEND_OF` relationships, the number of results of the subquery thus changed the number of results of the enclosing query.
638+
The following example finds the name of each `Player` and the team they play for.
639+
No rows are returned for `Player C`, since they are not connected to a `Team` with a `PLAYS_FOR` relationship.
640+
The number of results of the subquery thus changed the number of results of the enclosing query.
646641
647642
.Find the friends of players
648643
[source, cypher]
649644
----
650645
MATCH (p:Player)
651646
CALL (p) {
652-
MATCH (p)-[:FRIEND_OF]->(p2:Player)
653-
RETURN p2.name AS friend
647+
MATCH (p)-[:PLAYS_FOR]->(team:Team)
648+
RETURN team.name AS team
654649
}
655-
RETURN p.name AS player, friend
650+
RETURN p.name AS playerName, team
656651
----
657652
658653
.Result
659-
[role="queryresult",options="header,footer",cols="2*<m"]
654+
[role="queryresult",options="header,footer",cols="2*m"]
660655
|===
661-
| player
662-
| friend
663-
664-
| "Player A"
665-
| "Player B"
666-
667-
| "Player A"
668-
| "Player C"
656+
| playerName | team
669657
670-
| "Player B"
671-
| "Player F"
672-
673-
| "Player C"
674-
| "Player D"
658+
| "Player A" | "Team A"
659+
| "Player B" | "Team A"
660+
| "Player D" | "Team B"
661+
| "Player E" | "Team C"
662+
| "Player F" | "Team C"
675663
676-
2+d|Rows: 4
664+
2+d|Rows: 5
677665
|===
678666
679667
====
@@ -771,7 +759,7 @@ Labels added: 18
771759

772760
* `CALL` subqueries optimize data handling and query efficiency, and can perform changes to the database.
773761

774-
* `CALL` subqueries enable progressive data transformation and can accumulate results across multiple row executions.
762+
* `CALL` subqueries allow for row-by-row data transformation and enable the accumulation of results across multiple rows, facilitating complex operations that depend on intermediate or aggregated data.
775763

776764
* `CALL` subqueries can only refer to variables from the enclosing query if they are explicitly imported by either a variable scope clause or an importing `WITH` clause (deprecated).
777765

0 commit comments

Comments
 (0)