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 construct | Lowered to |
|---|---|
UNION / INTERSECT / EXCEPT | Union / Intersection / Difference (with Distinct when needed) |
SELECT list | Projection |
WHERE, HAVING | Selection |
FROM, joins | TupleSource, CartesianProduct, Join |
GROUP BY | GroupBy |
ORDER BY | OrderBy |
LATERAL joins, correlated subqueries | ProjectionConcat (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 BYcan reference columns that aren't in theSELECTlist. When that happens, the originalProjectionis widened to carry them and a secondProjectionis added after theOrderByto drop them again.- Correlated subqueries have two lowerings. They can become a
ProjectionConcat, or operators nested directly inside the relevantCalculations. The optimizer picks between them.
XQuery
XML value constructors lower to FnCalls (later rebuilt into Calculations), and aggregate functions lower to GroupBy. FLWOR expressions map clause by clause:
| FLWOR clause | Lowered to |
|---|---|
for | MapFromItem (plus CartesianProduct for multiple sources, ProjectionIndex for at $pos) |
let | Projection |
count | ProjectionIndex |
where | Selection |
group by | GroupBy |
order by | OrderBy |
return | ProjectionConcat (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 construct | Lowered to |
|---|---|
| Node / edge iteration | defaultGraph.nodes / defaultGraph.edges ItemSources |
MATCH | ItemSources, Projections, Selections, ProjectionConcats |
| Variable-length paths | a recursion operator (BidirectionalRecursion for best performance) |
WITH, RETURN | Projection (with Limit, Distinct, or OrderBy as needed) |
Aggregates in WITH / RETURN | GroupBy |
UNWIND | ItemFnSource |
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.
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).