Skip to main content

Language Mapping

Every frontend lowers its syntax into the same operators. If you know a language, this page shows you which operators your queries actually run on, and if you're extending DortDB, it shows the patterns to follow.

SQL​

SQL constructLowered to
UNION / INTERSECT / EXCEPTUnion / Intersection / Difference (with Distinct when needed)
SELECT listProjection
WHERE, HAVINGSelection
FROM, joinsTupleSource, CartesianProduct, Join
GROUP BYGroupBy
ORDER BYOrderBy
LATERAL joins, correlated subqueriesProjectionConcat (or operators nested in a Calculation)
col > ALL(...), ANY(...)Quantifier, later rebuilt into a Calculation

A standard block lowers in the obvious way:

SELECT attrs
FROM table
WHERE cond
GROUP BY attrs
HAVING cond
ORDER BY attrs

becomes a Projection over Selection (HAVING) over GroupBy over Selection (WHERE) over the source, finished with an OrderBy.

Two things to watch:

  • ORDER BY can reference columns that aren't in the SELECT list. When that happens, the original Projection is widened to carry them and a second Projection is added after the OrderBy to drop them again.
  • Correlated subqueries have two lowerings. They can become a ProjectionConcat, or operators nested directly inside the relevant Calculations. The optimizer converts the latter into the former when it can.

XQuery​

XML value constructors lower to FnCalls (later rebuilt into Calculations), and aggregate functions lower to GroupBy. FLWOR expressions map clause by clause:

FLWOR clauseLowered to
forMapFromItem (plus CartesianProduct for multiple sources, ProjectionIndex for at $pos)
letProjection
countProjectionIndex
whereSelection
group byGroupBy
order byOrderBy
returnProjectionConcat (the returned value may be a sequence that gets flattened into the output)

Path expressions lower to the XQuery TreeJoin operator, usually with Selections for predicates. TreeJoin supplies the focus each step needs: $fs:dot, $fs:position, and $fs:last.

Cypher​

Cypher constructLowered to
Node / edge iterationdefaultGraph.nodes / defaultGraph.edges ItemSources
MATCHItemSources, Projections, Selections, ProjectionConcats
Variable-length pathsa recursion operator (BidirectionalRecursion for best performance)
WITH, RETURNProjection (with Limit, Distinct, or OrderBy as needed)
Aggregates in WITH / RETURNGroupBy
UNWINDItemFnSource

The default graph name can be set globally when registering the language, or per query via a proprietary FROM clause.

A naive MATCH built only from ProjectionConcats, Selections, and ItemSources would be far too slow and would ignore the graph's structure entirely. So the optimizer rewrites connected node/edge patterns first into joins, then into index scans backed by a ConnectionIndex.

Variable-length path example
MATCH ()-[path *4]->()
RETURN path

This selects every node, then finds each node's incoming and outgoing edges with index scans. The BidirectionalRecursion operator expands and stitches those edges into four-segment paths from both ends, and a final Selection drops paths that reuse an edge (an artifact of joining the forward and backward halves).