Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

query

query-decl ::= attribute* 'pub'? 'query' Ident '(' param-list ')' '->' TypeExpr
               ('across' '[' standpoint (',' …)* ']')?
               '{' query-body '}'
query-body ::= ('with' Ident '=' query-body ';')*
               'select' projection
               'from' rule-body                                    // Rule-atom grammar
               ('optional' 'from' rule-body)*
               ('where' rule-body)?                                // additional atoms
               ('group' 'by' expr ('having' expr)?)?
               ('order' 'by' expr ('asc' | 'desc')?)?
               ('limit' Nat ('offset' Nat)?)?
projection ::= expr | '{' struct-init-list '}' | 'path' Ident | aggregate
role-step  ::= Ident quantifier? ('(' role-binders ')')? ('as' Ident)? mode-spec?
quantifier ::= '+' | '*' | '{' expr (',' expr)? '}'                // expr of type Nat
mode-spec  ::= 'mode' ('walk' | 'trail' | 'acyclic' | 'simple')
            |  'shortest' | 'all-shortest' | 'any' | 'k-shortest' Nat

Role-step path-traversal chains (a.role+(b), c.ParentOf{1, n}(p: Person)) are admitted as predicate-call atoms in the rule-atom grammar (Rule-atom grammar) and are not separately defined here.

The evaluated query-body is select … from … (where …)?. Every other form parse-refuses loudly with a feature-named code — never a generic OE0001, never silently ignored: the result-shaping clauses (group by … having, order by … asc|desc, limit … offset) with OE0007; the with CTE clause with OE1344; the graph-/path-traversal projections (select shortest path …, select path …, … as <name> mode …) with OE1345; optional from with OE1346; and the result-table set operators (union / union all / intersect / except) with OE1347.

pub query active_leases_for(t: Person) -> [Lease] {
    select l from l: Lease, l.tenant == t where is_active(l)
}

pub query ancestors_within(p: Person, n: Nat) -> Set<Person> {
    select a from p.ParentOf{1, n}(a: Person)
}

pub query shortest_route(a: City, b: City) -> Path<City, Road> {
    select shortest path r from a.road+(b) as r
}

pub query avg_age_by_dept() -> Map<Department, Real> {
    select { dept: avg(p.age) }
    from p: Person, p.works_in(dept: Department)
    group by dept
}

pub query rich_friends_of(p: Person) -> Set<Person> {
    with rich = select x from x: Person where x.net_worth > 1_000_000;
    select f from p.knows(f: Person) where f in rich
}

pub query agreed_across(p: Person) -> Truth4Of<Bool>
    across [LegalGround, MedicalGround]
{
    select consents(p)
}

Subquery forms. Brace-bracketed inner queries used as expressions:

subquery      ::= subquery-kind '{' rule-body '}'                   // Rule-atom grammar; no `from` keyword
subquery-kind ::= 'collect' | 'set' | 'one' | 'count' | 'exists'

The subquery body is a bare rule-atom list — there is no from keyword inside the braces (that prefix belongs to the top-level query-body only; an inner from parse-refuses with OE0001).

FormReturnsNotes
collect { … }List<T>Projection-carrying; supports order/limit.
set { … }Set<T>Projection-carrying; deduplicated.
one { … }Option<T>Projection-carrying; None if no match.
count { … }NatNo projection (counts matched tuples).
exists { … }BoolNo projection (K3 fail-closed; false on unknown).

The cardinality-fold kinds count and exists evaluate over the bare atom list above (count { p: Person }, exists { p: Person }). The projection-carrying kinds collect / set / one parse but refuse at ox check / ox build (OE1312); they never silently lower to a cardinality fold. Use a derive head plus a top-level query projection.

Set operations on result tables: union, union all, intersect, except.

Subquery aggregates (admitted as aggregate projections inside subquery bodies and as the subquery-form <aggregate> { atoms }): count, count distinct, sum, avg, min, max, collect, set_collect, string_join, percentile. The expression-level comprehension form sum(expr for x in coll where pred) (Expression grammar) admits a subset (sum, count, min, max, avg) for non-subquery contexts.

Default lattice context: K3. With across [...]: FDE.