Mutations

A mutation is a query and a patch together. The query selects the entities, and the patch gives the new state of each one. Stardust commits every change in one transaction. Each example reads the same five entities as Queries.

The document

A mutation document has query and patch. The query is an ordinary query, and the patch follows the form in Patches.

dust75B
query {find  [?e]
       where [[?e dept ops]]}
patch {?e {status active}}

Each key of the patch is a target. A key that begins with ? uses an entity variable bound by the query. A key that begins with _ makes a new entity.

Preview and commit

The native mutation run commits the selection and resolved patch together. The core also has a preview path that validates the same selection, resolution and store rules without writing facts. The public ABI does not currently expose that preview.

The result blocks on this page show the core report's status and counts. The public mutation result uses lowercase status names and also gives the commit time and generated entity ids.

Result / 68B
{status      Committed
 transaction 7
 facts       1
 generated   0}

The three statuses

StatusMeaning
CommittedThe patch writes facts in a new transaction
No_ChangeThe selection matches and every field already agrees
No_MatchThe selection matches no entity

A second run of the same mutation changes nothing, so Stardust commits no new transaction.

Result / 68B
{status      No_Change
 transaction 0
 facts       0
 generated   0}

A selection that matches no entity gives the same counts. No entity is in the department legal:

dust77B
query {find  [?e]
       where [[?e dept legal]]}
patch {?e {status active}}
Result / 67B
{status      No_Match
 transaction 0
 facts       0
 generated   0}

New entities

A target that begins with _ makes an entity. The selection must give exactly one row, because one new entity needs one parent row.

dust90B
query {find  [?e]
       where [[?e dept ops]]
       limit 1}
patch {_new {status seed}}
Result / 68B
{status      Committed
 transaction 9
 facts       1
 generated   1}

The engine rejects the same patch against a selection of two rows. Two entities are in the department eng:

dust75B
query {find  [?e]
       where [[?e dept eng]]}
patch {_new {status seed}}

Error

Generate_Requires_Single

Patch values and variables

The body for each target is a merge patch. It accepts every Stardust value: numbers, text, booleans, lists, maps, links and the other typed values. A null removes the field.

dust19B
patch {?e {age 5}}

This sets age to 5 on every entity bound to ?e.

The query may bind a patch variable in where or expose it through find. Both forms refer to the same row binding. A variable used as a patch target must bind an entity. A variable used as a field value substitutes its complete bound value.

dust177B
query {find  [?status]
       where [[?e status ?status]
              [= ?status pending]
              [?owner name Ada]]}
patch {?e {status active
           owner  ?owner}}

Stardust rejects a mutation with a malformed patch or an unbound variable. It also rejects a target that does not bind an entity or writes a protected stardust/* field. An invalid typed value or a result that violates the selected schema also causes rejection.

A mutation cannot write a definition. Stardust rejects a definition target with Definition_Target. Definitions include schemas, queries and mutations. A patch that writes stardust/type also gives Definition_Target. The preview gives the same error, and no fact changes. Use the definition API to change a definition.

Run it

mutation run.