Masterbelt

masterbelt/masterbelt

Master Data Relations

Synced from main@9490864MarkdownSource

#Master Data Relations

This document defines master-to-master references. The ref<M> field also drives the per-field Join builder on the source query — see Join Operator. Richer relation contracts (cardinality, cascade behavior) will be defined in future revisions of this document.

#Reference Type

A ref<M> value identifies one row of a master M by its primary key.

Masterbelt
master A {
  record {
    primary id: int,
    primary name: string,
  }
}

master B {
  record {
    primary id: int,
    aRecord: ref<A>,
  }
}

ref is a built-in generic type with one type argument. The argument must be a master type; any other argument is reported as masterbelt.checker.ref_non_master_target.

#Field Expansion

A field whose type is ref<M> is expanded into the target master's primary-key fields. The expanded fields are introduced at the parent record's top level, named by joining the original field name and the target's primary-key field name with _.

For the example above, master B's effective record shape is:

B.id : int B.aRecord_id : int B.aRecord_name: string

The expansion is observable at every consumer of the schema:

  • CSV import: source files must provide one column per expanded field. The example expects id, aRecord_id, aRecord_name.
  • Code generation: the target language emits one field per expanded entry on the generated record type, and emits a per-field Join builder that resolves the ref's expanded primary-key columns against the target master's relation through FindBy (see Join Operator).

The original ref field name does not appear as a single nested field at any consumer in the current revision.

#Post-Filter Collections in Validation

The same post-filter record collection that source programs reach through Master.toList() also appears as the table binding (and its alias self) of a master's validation all rule, iterated with for row in table. The only source-level relation terminal is toList(); findBy and the other terminals stay codegen/runtime-level. The relation stage operators (where, orderBy, thenBy, skip, take) are reachable from source only inside a scope body, where a validation all rule may also call the master's scopes on table.

#Reserved Keywords

The identifier ref is not reserved: it is matched only when written as a generic type argument application ref<M>. Using ref as an ordinary identifier elsewhere remains allowed.

Specification