Back to Blog

ISO GQL in ArcadeDB: What Works Today

A database at the center of an ISO/IEC 39075 GQL badge, connecting a graph of people and documents to GQL statements: a MATCH pattern, SESSION SET, and START TRANSACTION with COMMIT or ROLLBACK

GQL is the first new ISO database query language since SQL. The standard, ISO/IEC 39075, was published in April 2024, and graph databases have been moving toward it since. We have just published a GQL coverage statement for ArcadeDB that lists, feature by feature, what is supported, what is partial, and what is missing.

This post is the short version: how GQL fits into ArcadeDB, what you can use today, and where the gaps are.

How GQL runs in ArcadeDB

ArcadeDB has no separate GQL engine. GQL syntax runs inside the same native engine that implements OpenCypher 25, the latest Cypher grammar. That has two practical consequences:

  • Nothing to switch on. You send GQL to the same Cypher endpoint you already use, over HTTP, the Bolt protocol or the Java API.
  • GQL and Cypher mix freely. A GQL clause and a Cypher clause can sit in the same query, so you can adopt GQL one clause at a time.

What works today

Graph pattern matching with GQL quantifiers

Node and edge patterns, label expressions, OPTIONAL MATCH and GQL quantified edges all work:

MATCH (start:Station {name: 'A'})-[:NEXT]->{1,2}(stop:Station)
RETURN stop.name

->{1,2} is the GQL way to say “one or two hops”, the counterpart of Cypher’s *1..2.

Path modes: TRAIL, WALK and ACYCLIC

GQL path modes control whether a variable-length match may revisit edges or nodes. TRAIL (no repeated edges) is the default; ACYCLIC forbids repeated nodes; WALK allows both and needs an upper bound:

MATCH ACYCLIC (a:Person {name: 'Alice'})-[:KNOWS*1..5]->(b)
RETURN b.name

This query is also an example of mixing: a GQL path mode in front of a Cypher variable-length relationship.

FILTER, FOR and FINISH

GQL’s linear composition statements are supported:

MATCH (n:Person)
FILTER (n.age > 30)
RETURN n.name AS name
FOR name IN ['Alice', 'Bob', 'Carol']
CREATE (:Person {name: name})

FINISH ends a query without returning rows, which is handy for writes:

INSERT (n:Person {name: 'Bob'}) FINISH

INSERT and the rest of data modification

GQL INSERT takes a pattern, edges included:

MATCH (a:Person {name: 'Alice'}), (b:Person {name: 'Bob'})
INSERT (a)-[r:KNOWS]->(b)
RETURN r

SET (labels included), REMOVE, DELETE, DETACH DELETE and NODETACH DELETE are all supported. Deleting a node that still has edges is refused unless you detach it.

Transactions and session parameters

GQL transaction statements run as plain statements:

START TRANSACTION
COMMIT

ROLLBACK works too, and so does choosing an isolation level with START TRANSACTION ISOLATION READ_COMMITTED (an ArcadeDB extension). Session parameters work over server sessions, HTTP or Bolt:

SESSION SET $base = 10

SESSION RESET and SESSION CLOSE are supported as well. These are not available in embedded mode yet.

What does not work yet

We would rather you find the gaps here than in production. Not supported in ArcadeDB 26.10.x:

  • Search prefixes ANY and SHORTEST. The parser accepts them but does not apply them yet, so a query using them will not return shortest paths. Use shortestPath() and allShortestPaths().
  • SIMPLE path mode and REPEATABLE ELEMENTS.
  • LET, NEXT, EXCEPT, INTERSECT, OTHERWISE and USE graph. Use WITH where you would use LET.
  • CAST. Use the toInteger(), toFloat(), toString() family instead.
  • Unsigned integers, DECIMAL, BYTES and RECORD types. Use maps instead of records.
  • CREATE GRAPH, GQL graph types and GQLSTATUS codes. One ArcadeDB database is one graph, the schema is ArcadeDB’s native schema, and errors over Bolt use Neo4j-style Neo.ClientError.* codes.

A few features are partial, such as quantified path patterns (fixed-length groups work, variable-length relationships inside a group do not) and IS TYPED. The coverage statement has the details, and the open items are tracked in issue #9940.

Why a coverage statement and not a conformance score

There is no public conformance test suite for ISO GQL yet. Without one, a database can only describe what it implements, so “GQL compliant” is not a claim anyone can check today. We publish the feature list instead.

The engine underneath does have a test score: the Cypher engine runs the openCypher Technology Compatibility Kit on every build and passes 97.8% of its 3,897 scenarios, with zero failures and the rest skipped.

ArcadeDB vs Neo4j on GQL

Neo4j also runs GQL inside its Cypher engine, and its GQL conformance appendix says Cypher supports most of the mandatory GQL features. One difference worth knowing if you are planning a move: Neo4j lists the GQL session and transaction statements (SESSION SET, START TRANSACTION, COMMIT, ROLLBACK) among the mandatory features not yet in Cypher and handles them through its driver API. In ArcadeDB they are query statements.

For everything else about moving from Neo4j, including the Bolt protocol, the importer and how your existing Cypher runs unchanged, see the Neo4j to ArcadeDB migration guide.

Try it

Start ArcadeDB with Docker and open the Studio at http://localhost:2480:

docker run --rm -p 2480:2480 -e JAVA_OPTS="-Darcadedb.server.rootPassword=playwithdata" arcadedata/arcadedb:26.10.1

Pick Cypher as the language and any query in this post will run as written. If a GQL feature you need is on the missing list, tell us on GitHub: that list is what decides what we build next.