CALL#
GQL clause Added in 2.18
Runs a routine from inside a query pipeline. The routine is either a named function whose rows join onto the working table, or a subquery written inline.
Synopsis#
bold keywords · italic placeholders you supply · [ ] optional · ... repeatable. See Syntax conventions.
Description#
CALL has two forms, and which one you get is decided by the token after the
keyword:
CALLfollowed by a name is the named-routine form. It invokes a function and adds the columns named in the mandatoryYIELDlist to the working row. SeeCALL … YIELD.CALLfollowed by(or{is the inline form. It runs the subquery between the braces, optionally once per input row. SeeCALL { subquery }.
OPTIONAL may prefix either form. It keeps an input row whose routine or subquery
produced no rows, binding everything the call would have returned to null. See
OPTIONAL CALL.
What CALL invokes#
In GQL the thing CALL invokes is a procedure. AgensGraph has no procedure catalog of its
own. CALL … YIELD resolves the name against PostgreSQL’s ordinary functions, and a stock
installation registers no procedures at all.
SELECT count(*) AS procedures FROM pg_proc WHERE prokind = 'p';
procedures
------------
0
(1 row)
So “call a procedure” means “call a function” here. Any function works, and its
shape decides what YIELD can name:
Function shape |
What |
|---|---|
Scalar, e.g. |
One column named after the function |
Set-returning, e.g. |
One column named after the function, one row per element |
Composite or |
One column per output field, under the field names |
Any of these, under the function’s own name |
The whole row, when no output column has that name; a function |
A yield item is one of these and nothing else. A name the function does not return is refused, even when a variable of that name is bound earlier in the query.
PostgreSQL’s own CALL statement is a different thing: it is a top-level SQL
statement, it requires a real procedure, and it is not a Cypher clause. The two do
not overlap, and each rejects the other’s target.
Parameters#
- function
Name of a function to invoke. Schema-qualify it if
search_pathdoes not reach it. A procedure is refused:<name>() is a procedure, with the hintTo call a procedure, use CALL.- argument
A value expression, evaluated per input row. Arguments may reference variables bound earlier, which makes the call correlated. A property access produces
jsonb, so cast it when the parameter is another type.- variable_scope
Which outer variables the inline subquery may see:
(v, w)for those named,(*)for all of them,()for none. Omitting it imports nothing. SeeCALL { subquery }, which leads with that rule.- yield_list
*, or one or more of the function’s output columns, each optionally renamed withAS. Mandatory. SeeCALL … YIELD.- subquery
A read-only query ending in
RETURN. Write clauses are rejected.
Examples#
Every example runs against the example dataset.
Call a set-returning function and join its rows onto the matched film:
MATCH (m:movie {title: 'The Matrix'})
CALL jsonb_array_elements_text(m.embedding) YIELD jsonb_array_elements_text AS d
RETURN d ORDER BY d;
d
---------------
"-0.07594558"
"-0.11921061"
"0.04081754"
"0.29592122"
(4 rows)
Compute a value per row with a subquery#
The inline form answers a question per input row, keeping the body out of the main pattern:
MATCH (m:movie {genre: 'Adventure'})
CALL (m) { MATCH (p:person)-[:acted_in]->(m) RETURN count(p) AS cast_size }
RETURN m.title AS film, cast_size;
film | cast_size
-----------------+-----------
"Jurassic Park" | 1
(1 row)
Try to call a procedure#
A procedure is the one routine kind CALL … YIELD will not take:
CREATE PROCEDURE noop() LANGUAGE sql AS 'SELECT 1';
CREATE PROCEDURE
MATCH (m:movie) CALL noop() YIELD * RETURN count(*);
ERROR: noop() is a procedure
LINE 1: MATCH (m:movie) CALL noop() YIELD * RETURN count(*);
^
HINT: To call a procedure, use CALL.
And a function is the one routine kind the SQL CALL statement will not take:
CALL generate_series(1, 3);
ERROR: generate_series(integer, integer) is not a procedure
LINE 1: CALL generate_series(1, 3);
^
HINT: To call a function, use SELECT.
Notes#
The lexer decides between the two forms by looking one token ahead. That keeps
call usable as an ordinary identifier: MATCH (call:movie) RETURN count(call)
still works, and so does the SQL statement CALL myproc().
The named-routine form is a middle clause: it cannot open a query and cannot
end one. The inline form may open a query, but only without a scope clause. A
scope clause with nothing before it raises CALL has no preceding clause to import variables from.
Compatibility#
GQL conformance
Implements the GQL call procedure statement and procedure call (ISO/IEC 39075:2024 §15.1) in the query position of §14.5, call query statement.
Supported — both procedure-call forms the standard defines, the inline call of §15.2 and the named call of §15.3, each with the optional
OPTIONALprefix.Not supported — the call data-modifying procedure statement (§13.6): a called routine or subquery may not write to the graph. Also not supported is a catalog of GQL procedures — §17.5 procedure references resolve to PostgreSQL functions, and the standard’s
QUERY PROCEDUREindication has no counterpart.Deviation — the standard makes the
YIELDclause optional on a named call (§15.3). AgensGraph requires it.
Track status in the GQL conformance matrix.
openCypher#
openCypher’s CALL db.labels() style of procedure call maps onto the named form,
but the names differ: there is no db.* or dbms.* namespace here. Use the
PostgreSQL catalogs and the \dGv / \dGe meta-commands instead, or read
ag_label directly.
Drop the routines the examples created:
DROP PROCEDURE noop();
See also#
CALL … YIELDGQL — the named-routine form in detailCALL { subquery }GQL — the inline form, and its import listOPTIONAL CALLGQL — the input-preserving formSubquery value expressions GQL — a subquery in an expression rather than a clause