The CALL statement is used to invoke an inline procedure or a named procedure.
Syntax<call statement> ::= <call inline procedure> | <call named procedure>
An inline procedure is a user-defined procedure embedded within a query, commonly used to execute subqueries or perform data modifications. It enables complex logic such as looping and enhances efficiency by managing resources more effectively, especially when working with large graphs, thereby reducing memory overhead.
Syntax<call inline procedure> ::= [ "OPTIONAL" ] "CALL" [ <variable reference list> ] <procedure specification> <variable reference list> ::= "(" <variable reference> [ { "," <variable reference> }... ] ")" <procedure specification> ::= "{" <statement block> "}"
Details
CALL. If omitted, all current variables are implicitly imported.CALL.<statement block> must end with a RETURN statement to output variables to the outer query:
OPTIONAL keyword can be used to handle this case - producing a null value instead of discarding the record.RETURN statement is not required. In such cases, the number of records in the intermediate result table remains the same after CALL.
GQLINSERT (rowlock:User {_id:'U01', name:'rowlock'}), (brainy:User {_id:'U02', name:'Brainy'}), (purplechalk:User {_id:'U03', name:'purplechalk'}), (mochaeach:User {_id:'U04', name:'mochaeach'}), (lionbower:User {_id:'U05', name:'lionbower'}), (c01:Club {_id:'C01'}), (c02:Club {_id:'C02'}), (rowlock)-[:Follows]->(brainy), (mochaeach)-[:Follows]->(brainy), (brainy)-[:Follows]->(purplechalk), (lionbower)-[:Follows]->(purplechalk), (brainy)-[:Joins]->(c01), (lionbower)-[:Joins]->(c01), (brainy)-[:Joins]->(c02), (mochaeach)-[:Joins]->(c02)
Find members of each club:
GQLMATCH (c:Club) CALL { MATCH (c)<-[:Joins]-(u:User) RETURN collect_list(u.name) AS members } RETURN c._id, members
Result:
| c._id | members |
|---|---|
| C01 | ["Brainy","lionbower"] |
| C02 | ["Brainy","mochaeach"] |
Retrieve the followers of each member in club C01, ensure that members with no followers are still included in the results:
GQLMATCH (c)<-[:Joins]-(u:User) WHERE c._id = "C01" OPTIONAL CALL (u) { MATCH (u)<-(follower:User) RETURN collect_list(follower.name) AS followers } RETURN u.name, followers
Result:
| u.name | followers |
|---|---|
| Brainy | ["rowlock","mochaeach"] |
| lionbower | [] |
The order in which the subquery executed is not determined. If a specific execution order is desired, ORDER BY should be used to sort the records before CALL to enforce that sequence.
This query counts the number of followers for each user. The execution order of the subqueries is determined by the ascending order of the users' name:
GQLMATCH (u:User) ORDER BY u.name CALL { MATCH (u)<-[:Follows]-(follower) RETURN count(follower) AS followersNo } RETURN u.name, followersNo
Result:
| u.name | followersNo |
|---|---|
| Brainy | 2 |
| lionbower | 0 |
| mochaeach | 0 |
| purplechalk | 2 |
| rowlock | 0 |
Set values for the property rates of Joins edges:
GQLFOR score IN [1,2,3,4] CALL { MATCH ()-[e:Joins WHERE e.rates IS NULL]-() LIMIT 1 SET e.rates = score RETURN e } RETURN e
Result:
JSON[ {"id": "e:7", "label": "Joins", "fromNodeId": "U02", "toNodeId": "C02", "properties": {"rates": 1}}, {"id": "e:8", "label": "Joins", "fromNodeId": "U04", "toNodeId": "C02", "properties": {"rates": 2}}, {"id": "e:5", "label": "Joins", "fromNodeId": "U02", "toNodeId": "C01", "properties": {"rates": 3}}, {"id": "e:6", "label": "Joins", "fromNodeId": "U05", "toNodeId": "C01", "properties": {"rates": 4}} ]
A named procedure refers to a predefined procedure that is registered in the system and can be invoked by its name using the CALL statement. Two kinds of named procedures are supported:
algo.degree, algo.pagerank. See Graph Algorithms.CREATE PROCEDURE. See Stored Procedures.Syntax<call named procedure> ::= [ "OPTIONAL" ] "CALL" <procedure reference> [ <yield clause> ] <yield clause> ::= "YIELD" <yield item> [ { "," <yield item> }... ] <yield item> ::= <column name> [ "AS" <binding variable> ]
Details
YIELD clause outputs the procedure's columns to the outer query.n from a preceding MATCH (n)) are not visible after a named CALL ... YIELD. To carry variables through, project them in the RETURN before the CALL, or use the inline CALL { ... } form with explicit variable import.OPTIONAL to suppress the "procedure not found" error when the named procedure does not exist. Unlike the inline OPTIONAL CALL { ... } subquery form, named OPTIONAL CALL does not insert a NULL-padded row when a resolved procedure yields zero rows — the result is an empty table.Execute the Degree Centrality algorithm:
GQLCALL algo.degree({ order: "desc" }) YIELD nodeId, degree
To learn more about available algorithms, refer to Graph Algorithms.
Given a stored procedure greet created with CREATE PROCEDURE, invoke it the same way:
GQLCALL greet('World') YIELD greeting
For details on defining, listing, and managing user-defined procedures, refer to Stored Procedures.
For named procedures, OPTIONAL CALL only suppresses the "procedure not found" error when the procedure does not exist. It does not insert a NULL-padded row when a resolved procedure yields zero rows — the result is simply an empty table. The richer outer-row preservation with NULL columns documented above applies only to the inline OPTIONAL CALL { ... } form.
GQL-- Errors if 'maybe_proc' is not defined CALL maybe_proc() YIELD result -- No error; returns an empty result with column 'result' OPTIONAL CALL maybe_proc() YIELD result