# GQL conformance AgensGraph implements part of ISO/IEC 39075:2024, *Information technology — Database languages — GQL*. This appendix is not a full statement of conformance. It covers the main topics in as much detail as is reasonable and useful. The tables below are keyed by subclause of the standard, because that is the unit the standard itself uses to attach a conformance rule to a piece of syntax. Every row was checked against a running 2.18 server. A row says **Yes** only when the syntax the subclause defines was accepted and produced the result the subclause requires. It says **Partial** when some of the subclause's syntax is accepted and the rest raises an error, and **No** when none of it parses. Where the standard offers several spellings of the same idea, the comment says which one AgensGraph takes. Three general points hold across every row and are not repeated in each comment. GQL is not a separate mode. A GQL statement and a Cypher statement go through the same parser and may be mixed in one pipeline, so `LET` sits next to `WITH` and `INSERT` next to `CREATE`. See [Cypher, GQL and SQL](../concepts/languages.md). A graph is a PostgreSQL schema and a label is a table. So the parts of the standard that describe a catalog of directories, schemas and graph types have a PostgreSQL counterpart rather than a GQL one. The working graph comes from the `graph_path` setting instead of a `USE` clause, and privileges are PostgreSQL privileges. See [How a graph is stored](../concepts/graph-on-postgresql.md). Errors carry a five-character SQLSTATE, not a GQLSTATUS. See [Error codes](error-codes.md). ## Supported features These subclauses are wholly or partly implemented. A **Partial** comment names what is missing, so that a reader porting standard GQL knows what to look for. | Subclause | Name | Support | Comment | | --- | --- | --- | --- | | 8.1–8.4 | ``, ``, ``, `` | Yes | PostgreSQL's own transaction statements answer these. `START TRANSACTION READ ONLY`, `COMMIT` and `ROLLBACK` all work. | | 9.2 | `` | Partial | `NEXT` chains one statement onto the result of the previous one. `NEXT` cannot carry a `YIELD` clause, and the binding-variable definition block that 9.2 also allows does not exist — see 10.1–10.3 below. | | 11.1 | `` | Partial | `CURRENT_GRAPH` and `CURRENT_PROPERTY_GRAPH` are accepted, in Cypher and in SQL. They are bare keywords: `current_graph()` is a syntax error. No other form of graph expression exists. | | 12.4 | `` | Partial | `CREATE GRAPH name` and `CREATE GRAPH IF NOT EXISTS name` work. The graph type the standard requires after the name (`ANY`, `LIKE`, or a graph type reference) is not accepted, nor is `OR REPLACE`, `PROPERTY GRAPH` or `AS COPY OF`. | | 12.5 | `` | Partial | `DROP GRAPH name` and `DROP GRAPH IF EXISTS name` work, plus a non-standard `CASCADE`, which is needed because a new graph already contains `ag_vertex` and `ag_edge`. `DROP PROPERTY GRAPH` is a syntax error. | | 13.1 | `` | Yes | A statement composes read clauses and write clauses in one pipeline, and a write clause's changes are visible to a read clause after it. | | 13.2 | `` | Yes | `INSERT` takes the same pattern as Cypher `CREATE` and is a synonym for it. | | 13.3 | `` | Partial | Property assignment works, including the non-standard `+=` merge form. The label-set assignment the subclause also defines does not exist: a vertex has exactly one label. | | 13.4 | `` | Partial | `REMOVE n.prop` removes a property. `REMOVE n:Label` does not exist, for the same reason. | | 13.5 | `` | Yes | `DELETE` and `DETACH DELETE`. Deleting a vertex that still has edges is refused unless `DETACH` is given. | | 14.2 | `` | Partial | `UNION`, `UNION ALL`, `EXCEPT` and `INTERSECT` compose two query statements. `OTHERWISE` is a syntax error. | | 14.3 | `` and `` | Yes | A query is a sequence of the primitive query statements below, ending in a primitive result statement. | | 14.4 | `` | Partial | `MATCH` and `OPTIONAL MATCH` work. The braced form, `OPTIONAL { MATCH … MATCH … }`, is a syntax error. | | 14.5 | `` | Partial | Both call forms work. See 15.2 and 15.3 for what each one requires. | | 14.6 | `` | Yes | Both `FILTER expr` and `FILTER WHERE expr`. | | 14.7 | `` | Yes | Additive, row-wise, and able to lead a query. An aggregate in a `LET` expression is refused. | | 14.8 | `` | Partial | Iterating a list works, with `WITH OFFSET AS name` giving a 0-based index. `WITH ORDINALITY` is a syntax error, and `FOR` cannot iterate a binding table. | | 14.9 | `` | Yes | `ORDER BY`, `SKIP`, `OFFSET` and `LIMIT` are statements in their own right and can sit anywhere in a pipeline. Like the standard, AgensGraph does not let one *end* a query — 14.3 requires a primitive result statement last — so a query ending in `ORDER BY` raises `ERROR: Cypher query must end with RETURN, FINISH or update clause`. | | 14.10 | `` | Yes | `RETURN`, `RETURN … ORDER BY …`, and `FINISH`. | | 14.11 | `` | Partial | `RETURN`, `RETURN DISTINCT`, `RETURN ALL`, `RETURN *` and explicit aliases. `RETURN NO BINDINGS` is a syntax error. Grouping is implicit — see 16.15. | | 15.1 | `` and `` | Yes | `CALL` and `OPTIONAL CALL`, over either call form. | | 15.2 | `` | Partial | `CALL (v) { … }`, `CALL () { … }`, `CALL (*) { … }` and `CALL { WITH v … }` all import correctly. A bare `CALL { … }` deviates: Syntax Rule 3 says an absent variable scope clause is rewritten to one naming *every* field of the incoming working record, so under the standard it imports everything, as `CALL (*) { … }` does. AgensGraph imports nothing instead, and raises no error, so the query answers a different question than it appears to — always write an import list. Write clauses in the subquery body are refused, and `IN TRANSACTIONS` does not exist. | | 15.3 | `` | Partial | `CALL routine(args) YIELD item [AS alias]` and `YIELD *` work, correlated when an argument references a variable already in scope. `YIELD` is mandatory, where the subclause makes it optional, and the clause can neither lead nor end a query. The name resolves to a PostgreSQL function, not to a procedure of the catalog 17.5 describes: a stock server registers no procedures, and calling one raises `() is a procedure`. | | 16.3 | `` | Partial | A graph pattern produces a binding table. The pattern `YIELD` clause the subclause also allows is a syntax error. | | 16.4 | `` | Partial | Comma-separated path patterns work. The match modes (`DIFFERENT EDGES`, `REPEATABLE ELEMENTS`) and the `KEEP` clause are syntax errors. | | 16.5 | `` | Yes | The pattern after `INSERT` or `CREATE` may create vertices, edges, or edges between vertices already bound. | | 16.7 | `` | Partial | Concatenation works. Path multiset alternation and path pattern union — two path patterns separated by `\|` — are syntax errors. | | 16.8 | `