Note
The eval::* functions run a query supplied as a string inside the caller's open transaction and session context. They are intended for workloads where the query text is only known at runtime — for example, analytical queries stored in a table, where you want to blend ISO GQL and SurrealQL in one transaction, or to learn SurrealQL or rewrite existing queries from another graph database.
| Function | Description |
|---|---|
eval::gql() | Evaluate a nested ISO GQL query and return its result |
eval::surql() | Evaluate a nested SurrealQL statement and return its value |
For how eval::* fits with encoding, parsing, and other representation transforms, see Representations and codecs.
eval::gql
Evaluates an ISO GQL query string. One GQL query may lower to several internal statements. Unlike eval::surql, it is not limited to a single SurrealQL statement.
eval::gql requires the gql experimental capability (same as POST /gql) and runs on the streaming query engine. Queries that include GQL mutations (INSERT, SET, REMOVE, DELETE) participate in the caller's write transaction — see GQL mutations.
Enable both capabilities on the server, for example:
GQL syntax is Cypher-like: parenthesised node patterns (variable:label), arrow edge patterns -[variable:type]->, a mandatory MATCH clause, and RETURN for projection. See Notable syntax differences from openCypher before pasting Neo4j queries verbatim.
Sample graph
The following queries create a number of person and city records, followed by INSERT RELATION to join them together. The following eval::gql queries assume this seed data when indicating output.
| GQL pattern | Meaning in SurrealDB |
|---|---|
(n:person) | Rows in table person bound to variable n |
-[k:knows]-> | Directed edges in relation table knows (in / out record IDs) |
n.name | Field name on the bound record |
$min | Parameter — pass via the optional bindings object |
Match nodes by label
MATCH finds graph patterns; RETURN projects columns (like SELECT).
Filter on node properties
WHERE filters rows after the pattern matches. Missing properties (person C has no age) are treated as unknown and excluded from comparisons.
Traverse a typed edge
Chain node and edge patterns to walk the graph. Label both endpoints as :person to ignore the person → city edge.
Optional match
OPTIONAL MATCH keeps every anchor row from the preceding MATCH even when the optional pattern misses — similar to a left outer join.
Only person A has a knows edge to the city node; everyone else still appears with city: NONE.
Aggregate with GROUP BY
Count outgoing person → person knows edges per person.
Multi-hop paths
In ISO GQL on SurrealDB, variable-length hops are a postfix quantifier on the edge, not Cypher's *1..3 inside the brackets:
One hop reaches B; two hops loop back to A via B or reach C via B.
Parameters
GQL parameters can be passed as the second argument to this function.
Bindings are isolated from the caller's scope (same as eval::surql); only keys you pass in the object are visible inside the GQL query.
Note
For more patterns — path search (ALL SHORTEST), comma-separated joins, and side-by-side SurrealQL — see Sample GQL and SurrealQL queries.
eval::surql
Evaluates a single SurrealQL statement and returns its value. To run several statements, wrap them in a block { ... } — the block's final value is returned.
Nested writes run in the caller's transaction:
The evaluated query runs in an isolated scope: parameters visible at the call site are not inherited — only keys you pass in the bindings object are bound.
Notes on using eval:: functions
Rejected inputs
The following are rejected inside eval::*:
Transaction and session control —
BEGIN,CANCEL,COMMIT,USE,LIVE,KILL,OPTION,SHOW, and access statements.Bare multi-statement SurrealQL in
eval::surql— use{ ... }instead of semicolon-separated top-level statements.Protected binding names — caller bindings cannot overwrite reserved parameters such as
$session.Excessive nesting — recursive
evalcalls share the engine's computation depth limit.
Security
Every eval::* call is checked against the current execution auth (guest, record, or system). Auth limiting in DEFINE FUNCTION bodies never raises the subject — a record-scoped caller that invokes an owner-defined function which calls eval is still evaluated as record.
All of the following must pass:
| Gate | Purpose |
|---|---|
allow-funcs / deny-funcs | The eval function family must be permitted |
deny-arbitrary-query (and related allow rules) | eval counts as an arbitrary query — denied subjects cannot use eval to bypass /sql or API lockdown |
allow-eval-query / deny-eval-query | Dedicated opt-in for eval::surql and eval::gql |
eval cannot grant a subject more query power than arbitrary-query policy allows — including when called from inside a DEFINE FUNCTION or DEFINE API handler. You do not need --allow-arbitrary-query for eval on a default server; you do need --allow-eval-query.
For eval::gql, the gql experimental capability must also be enabled.
Enabling on the server
eval::* is enforced by the database engine that executes your query, not by the client you type into.
Remote server (surreal start + surreal sql)
When the REPL connects over ws://, http://, or similar, pass capability flags on surreal start only. The same flags on surreal sql do not enable or disable eval at runtime.
Environment variable equivalent on the server process:
If you use --deny-arbitrary-query (for example to steer record users toward DEFINE API only), add matching --allow-arbitrary-query entries for any subject that should call eval.
Embedded engine (surreal sql only)
When you open the REPL against embedded storage (memory, rocksdb://…, …) without a separate surreal start process, configure capabilities on surreal sql instead:
See Capabilities and remote connections for the full remote versus embedded model.
See SURREAL_CAPS_ALLOW_EVAL_QUERY and SURREAL_CAPS_DENY_EVAL_QUERY in the environment variable reference.
See also
Representations and codecs — when to use
eval::*versus encode, parse, or analyse functionsGQL overview — ISO GQL on the wire and via
eval::gqlCapabilities — full capability model