Chapter 18Procedures
This chapter treats procedures as callable abstractions and formalizes named procedure descriptors, inline GQL procedure bodies, resolution, and calls. Functions are value-expression operators covered by the expression semantics; they are not primary catalog objects in the core catalog modeled here.
18.1 Procedure Signatures and Body Typing
Named procedure descriptors. For the lookup-oriented model used in this chapter, we use the following compact, lookup-augmented representation of a named procedure catalog entry. It adds the catalog object name to the standard descriptor components and retains the components needed below:
where is its catalog object name, is the ordered list of mandatory parameters, is the trailing list of optional parameters with default values, is the procedure result type, and records the permitted kind of side effects. Parameter names are unique. Optional parameters form only a suffix; supplying one requires supplying every optional parameter before it.
The core signature of the declaration is
If is a binding-table type, its record type supplies the names and types available to a YIELD clause. Write for the material binding-table type whose record has the named fields . In a CALL-statement, the declared type of the procedure call is required to be either a material binding-table type or the empty type. The effect abstraction used later is obtained from : a query procedure has no side effects, a data procedure may have data-modifying effects only, and a catalog procedure may have catalog-modifying effects, possibly together with data- modifying effects.
In the catalog, procedure names are unique and procedure overloading is not modeled: the Procs component maps each qualified procedure identifier to at most one declaration,
Consequently, a qualified procedure name uniquely determines its core signature whenever it is present in the catalog.
Procedure bodies and their scope. In this edition, a named procedure is an external procedure; the standard does not specify a GQL statement that defines its implementation. Accordingly, contains no GQL body. An inline procedure is instead a nested procedure specification with a GQL procedure body. Its statements determine whether it is catalog-modifying, data-modifying, or a query procedure, and its declared result type is computed from that body. Body typing uses the incoming working record/table types and the statement-block rules; it is not an undeclared attached to a named catalog descriptor.
18.2 Calls and Scoping
Static environment. Typing judgments use a resolution environment , where is the active context (catalog, working schema, working graph site) and is a finite map of parameters and binding variables used when typing argument expressions. A catalog procedure reference is resolved by its own grammar and is not shadowed by a binding variable of the same spelling.
Resolution order. For a named procedure call, the procedure reference identifies its explicit catalog parent or uses the implicit parent ./ (the current working schema), then identifies a named procedure in that parent. Absolute and relative catalog paths follow Chapter 17. Alternatively, a procedure reference may be supplied by a substituted reference parameter; its substitution is resolved as the corresponding catalog procedure parent and name. This is reference resolution, not an ordered search through local variables and catalog names.
Syntactic form of procedure calls. At statement level, a procedure call may be optional and may invoke either an inline or a named procedure. The named form is:
call-proc-stmt ::= [ "OPTIONAL" ] "CALL" procedure-call
procedure-call ::= inline-procedure-call | named-procedure-call
named-procedure-call ::= procedure-reference "(" [ arg-list ] ")"
[ "YIELD" yield-list ]
arg-list ::= expr { "," expr }
yield-list ::= yield-item { "," yield-item }
yield-item ::= field-name [ "AS" binding-variable ]
expr ::= ... /* value expression */
Here procedure-reference identifies a cataloged procedure, arg-list supplies actual arguments as value expressions in call-position order, and yield-list specifies which output columns of the procedure are made visible to the enclosing statement, with AS providing an explicit alias for the corresponding column name when required by the context. The named form requires optional Feature GP04, Named procedure calls. A graph argument additionally requires GP15, and a binding-table argument additionally requires GP14.
Example: a named library procedure. Let be a procedure object name and let be its globally resolved reference in the current working schema. In the descriptor abstraction used here, an illustrative external data procedure may be represented by
If it is registered through an implementation-defined mechanism, the derived catalog projection satisfies
The relative name in the following call resolves to :
CALL recomputeFees(DATE '2025-12-31')
YIELD updatedCount AS cnt
The procedure name and implementation are illustrative; the library DDL in Section 4.2 does not declare this external procedure.
Example: procedure-call resolution environment. In the static-resolution abstraction used here, one possible environment for a call typed inside the library context is
The local map records types used to type argument expressions; the reference recomputeFees is resolved through .
Procedure call in statements. A CALL-statement that invokes a named procedure and yields selected columns has the form . Let be the applicable static type context and let be the incoming binding-name-to-type environment; is its extension by yielded columns. For a descriptor with mandatory and optional parameters, define and . For a binding-table result , let . Finally, is empty for a query procedure and is the applicable abstract data- or catalog-modifying effect for the other procedure kinds. The yielding form below therefore assumes a material binding-table result. If the procedure result type is the empty type, YIELD is not permitted and the call statement uses the material unit record type for its output contribution. For a permitted number of actual arguments, write when the statically derived type of each supplied argument passes the GQL store-assignment check against the corresponding mandatory or optional parameter type; omitted optional arguments use their descriptor defaults. A schematic typing rule is:
Here is the procedure-specific instance of the catalog resolution function from Chapter 17. A YIELD clause is permitted only for a binding-table procedure result, selects existing result columns, and produces the aliases shown in . The incoming and yielded record types must be field-name-disjoint. The effect is determined by the descriptor’s procedure kind, and is empty exactly for a query procedure.
Operationally, the procedure is called once for each incoming working-table record in a child execution context containing its argument record. If its execution result is a binding table, each result record is combined with that incoming record. If its result is omitted (the empty-type case), the call statement uses a unit binding table containing one unit record, so the incoming record is preserved once. For OPTIONAL CALL, an empty binding-table result instead contributes one record whose yielded fields are null; a non-optional empty binding-table result contributes no record.