Relation declarations

Updated Jul 23, 2026

Relation declarations may combine an optional role, optional kind, optional reference marker, and one body form:

R(id: u32)
input relation User(id: u32) primary key (id)
output stream Events[Event]
multiset & Bag(item: Item)

The accepted shape is:

Role? Kind? '&'? Name Body PrimaryKey?

Role may be input or output. When no role is present, the relation is internal. internal is not a keyword.

Kind may be relation, stream, or multiset. When no kind is present, relation is assumed.

Body is either a record field list, such as (id: u32, name: string), or a bracketed element type, such as [Event].

Primary-key clauses are accepted only on input relations with record bodies. The parser preserves spec-form clauses such as:

input relation Book(row: BookRow) primary key (row) (row.author, row.title)

The current typed AST exposes the binder/list names from primary key (...). Typed access to the trailing expression is deferred to roadmap item 2.6.6.1.