Queries and mutations

The example stores the people in a database and queries their names. It collects query pages, updates Ada's age, and reads the changed age.

Example

The example compares these results:

  • a committed mutation
  • a repeated mutation
  • a query that matches no entity

Give Ada her birthday and read her age

birthdayText holds this document:

dust68B
query {find  [?e]
       where [[?e name Ada]]}
patch {?e {age 37}}

queryText holds this document:

dust56B
find  [?age]
where [[?e name Ada]
       [?e age ?age]]
go685B
birthday, err := stardust.Parse(birthdayText, stardust.DUST)
if err != nil {
	return err
}
defer birthday.Close()

mutation, err := db.Mutation(birthday)
if err != nil {
	return err
}
defer mutation.Close()

if _, err := mutation.Run(nil, stardust.RunOptions{}, nil); err != nil {
	return err
}

definition, err := stardust.Parse(queryText, stardust.DUST)
if err != nil {
	return err
}
defer definition.Close()

query, err := db.Query(definition)
if err != nil {
	return err
}
defer query.Close()

rows, err := query.Run(nil, stardust.RunOptions{}, nil)
if err != nil {
	return err
}
defer rows.Close()

result, err := rows.AllPages()
if err != nil {
	return err
}
defer result.Close()
Result / 10B
[{age 37}]

Query pages

Each query page is an owned document.

  • You can keep a page after you release the rows handle, query, or database that produced it.
  • Release each page when you finish with its values. The document ownership rule applies.

Operations

OperationReturnsSummary
Database.QueryqueryOpen an owned query from a path or an inline definition.
Database.MutationmutationOpen an owned mutation from a path or an inline definition.
Query.RunrowsRun the query and return an owned row cursor.
Query.ClosenoneRelease the query handle.
Rows.NextdocumentRead the next page as an owned document.
Rows.Pagespagesrows.pages() iterates the non-empty pages of the cursor.
Rows.AllPagesdocumentrows.all_pages() reads every remaining page into one owned array document.
Rows.ClosenoneRelease the rows handle.
Query.Subscribesubscriptionquery.subscribe(parameters, options) opens an owned live subscription.
Subscription.NexteventWait for the next live event.
Subscription.Alleventssubscription.events() delivers events in order until the subscription is cancelled, closes or fails.
Subscription.Cancelnonesubscription.cancel() ends the subscription.
Subscription.ClosenoneRelease the subscription handle.
Mutation.RuncommitRun the mutation and return commit information.
Mutation.ClosenoneRelease the mutation handle.
Database.MergePatchcommitdatabase.merge_patch(patch) applies an entity-keyed patch document in one transaction and returns commit information.

Database.Query

Open an owned query from a path or an inline definition.

Database.Query(definition) opens an owned query from an inline native definition document.

  • The call copies the definition.
  • Database.QueryPath(path) opens an owned query from a stored definition path.
  • Each run selects the stored definition using its run options, including as_of when supplied.

Query documents.

go62B
func (d *Database) Query(definition *Document) (*Query, error)
go57B
func (d *Database) QueryPath(path string) (*Query, error)
  • Concurrency: Other calls can overlap this call, except the release of a handle that this call uses.
  • Ownership: The caller owns the returned handle and releases it.

Parameters

ParameterTypeOwnershipDefaultMeaning
definition*DocumentBorrowed for the callRequiredThe inline native query definition copied into the query handle.
pathstringValueRequiredThe stored query definition path selected at run time.

Errors

StatusWhen
StatusNotFoundno definition is stored at the path
StatusInvalidDefinitionthe definition is invalid
StatusClosedthe database is closed
StatusOutOfMemorynative memory is exhausted

Examples

Open an inline query and read its first page

queryText holds this document:

dust58B
find    [?name]
where   [[?e name ?name]]
orderBy [?name]
go385B
definition, err := stardust.Parse(queryText, stardust.DUST)
if err != nil {
	return err
}
defer definition.Close()

query, err := db.Query(definition)
if err != nil {
	return err
}
defer query.Close()

rows, err := query.Run(nil, stardust.RunOptions{}, nil)
if err != nil {
	return err
}
defer rows.Close()

result, err := rows.Next()
if err != nil {
	return err
}
defer result.Close()
Result / 33B
[{name Ada} {name Bob} {name Cy}]

Refuse an invalid query definition

queryText holds this document:

dust10B
find [?x]
go194B
definition, err := stardust.Parse(queryText, stardust.DUST)
if err != nil {
	return err
}
defer definition.Close()

query, result := db.Query(definition)
if query != nil {
	defer query.Close()
}
Result / 136B
{code    unbound_variable
 message Unbound_Variable
 path    null
 field   null
 entity  null
 offset  null
 status  invalid_definition}

Report a missing stored query

go88B
query, result := db.QueryPath("people/missing")
if query != nil {
	defer query.Close()
}
Result / 140B
{code    not_found
 message no definition at this path
 path    people/missing
 field   null
 entity  null
 offset  null
 status  not_found}

C exports: stardust_db_query_open, stardust_db_query_error

Database.Mutation

Open an owned mutation from a path or an inline definition.

Database.Mutation(definition) opens an owned mutation from an inline native definition document.

  • The call copies the definition.
  • Database.MutationPath(path) opens an owned mutation from a stored definition path.
  • Each run selects the stored definition using its run options, including as_of when supplied.

Mutation documents.

go68B
func (d *Database) Mutation(definition *Document) (*Mutation, error)
go63B
func (d *Database) MutationPath(path string) (*Mutation, error)
  • Concurrency: Other calls can overlap this call, except the release of a handle that this call uses.
  • Ownership: The caller owns the returned handle and releases it.

Parameters

ParameterTypeOwnershipDefaultMeaning
definition*DocumentBorrowed for the callRequiredThe inline native mutation definition copied into the mutation handle.
pathstringValueRequiredThe stored mutation definition path selected at run time.

Errors

StatusWhen
StatusNotFoundno definition is stored at the path
StatusInvalidDefinitionthe definition is invalid
StatusClosedthe database is closed
StatusOutOfMemorynative memory is exhausted

Examples

database/mutation

birthdayText holds this document:

dust68B
query {find  [?e]
       where [[?e name Ada]]}
patch {?e {age 37}}
go292B
source, err := stardust.Parse(birthdayText, stardust.DUST)
if err != nil {
	return err
}
defer source.Close()

mutation, err := db.Mutation(source)
if err != nil {
	return err
}
defer mutation.Close()

result, err := mutation.Run(nil, stardust.RunOptions{}, nil)
if err != nil {
	return err
}
Result / 105B
{status       committed
 transaction  5
 facts        1
 committed_at 17915443414964059
 ids          {}}

C exports: stardust_db_mutation_open, stardust_db_mutation_error

Query.Run

Run the query and return an owned row cursor.

handle.run(parameters, options) runs a query or mutation.

  • Parameters apply a JSON merge patch (RFC 7396) to the declared defaults.
  • Omitted parameters keep their defaults.
  • Absent parameters have the same effect as an empty object.
  • Objects merge recursively.
  • Other values replace the defaults, including tagged values such as {#utc …}.

A name matches with or without its leading ?.

  • A null parameter has no value, so the run fails with missing_parameter.

Query runs return owned rows.

  • Mutation runs return commit information.
  • Options include as_of, max_cost and query page_size.
  • The as_of option selects a historical stored definition.

Query documents.

go99B
func (q *Query) Run(parameters *Document, options RunOptions, explain *QueryExplain) (*Rows, error)
  • Concurrency: Other calls can overlap this call, except the release of a handle that this call uses.
  • Ownership: The caller owns the returned handle and releases it.

Parameters

ParameterTypeOwnershipDefaultMeaning
parameters*DocumentBorrowed for the callAbsent means no supplied parametersNamed values bound for this execution.
optionsRunOptionsValueRequired options record. See field defaultsThe operation's options record. See its field defaults.
explain*QueryExplainCaller-owned outputAbsent skips explain outputOptional explain output. This record contains explain output for query run. The compile, plan, execute, group and order fields divide the wall time of run into stages.

Errors

StatusWhen
StatusNotFoundthe stored query definition was deleted
StatusInvalidDefinitionthe loaded query definition is invalid
StatusInvalidArgumentthe parameters or run options are invalid
StatusEvaluationFailedthe query fails or exceeds max_cost
StatusClosedthe query is closed
StatusOutOfMemorynative memory is exhausted

Examples

Open an inline query and read its first page

queryText holds this document:

dust58B
find    [?name]
where   [[?e name ?name]]
orderBy [?name]
go385B
definition, err := stardust.Parse(queryText, stardust.DUST)
if err != nil {
	return err
}
defer definition.Close()

query, err := db.Query(definition)
if err != nil {
	return err
}
defer query.Close()

rows, err := query.Run(nil, stardust.RunOptions{}, nil)
if err != nil {
	return err
}
defer rows.Close()

result, err := rows.Next()
if err != nil {
	return err
}
defer result.Close()
Result / 33B
[{name Ada} {name Bob} {name Cy}]

Capture the host duration boundary

boundaryText holds this document:

dust20B
9223372036854775807

queryText holds this document:

dust58B
find    [?name]
where   [[?e name ?name]]
orderBy [?name]
go631B
definition, err := stardust.Parse(queryText, stardust.DUST)
if err != nil {
	return err
}
defer definition.Close()

query, err := db.Query(definition)
if err != nil {
	return err
}
defer query.Close()

boundary, err := stardust.Parse(boundaryText, stardust.DUST)
if err != nil {
	return err
}
defer boundary.Close()

boundaryRoot, err := boundary.Root()
if err != nil {
	return err
}
nanoseconds, err := boundary.I64(boundaryRoot)
if err != nil {
	return err
}

result := stardust.RunOptions{PageSize: 2, MaxCost: time.Duration(nanoseconds)}
rows, err := query.Run(nil, result, nil)
if err != nil {
	return err
}
defer rows.Close()
Result / 55B
{page_size 2
 max_cost  92233720368547758
 as_of     0}

Truncate a positive sub-tick duration

boundaryText holds this document:

dust3B
99

queryText holds this document:

dust58B
find    [?name]
where   [[?e name ?name]]
orderBy [?name]
go631B
definition, err := stardust.Parse(queryText, stardust.DUST)
if err != nil {
	return err
}
defer definition.Close()

query, err := db.Query(definition)
if err != nil {
	return err
}
defer query.Close()

boundary, err := stardust.Parse(boundaryText, stardust.DUST)
if err != nil {
	return err
}
defer boundary.Close()

boundaryRoot, err := boundary.Root()
if err != nil {
	return err
}
nanoseconds, err := boundary.I64(boundaryRoot)
if err != nil {
	return err
}

result := stardust.RunOptions{PageSize: 2, MaxCost: time.Duration(nanoseconds)}
rows, err := query.Run(nil, result, nil)
if err != nil {
	return err
}
defer rows.Close()
Result / 39B
{page_size 2
 max_cost  0
 as_of     0}

Explain query execution

queryText holds this document:

dust58B
find    [?name]
where   [[?e name ?name]]
orderBy [?name]
go343B
definition, err := stardust.Parse(queryText, stardust.DUST)
if err != nil {
	return err
}
defer definition.Close()

query, err := db.Query(definition)
if err != nil {
	return err
}
defer query.Close()

var result stardust.QueryExplain
rows, err := query.Run(nil, stardust.RunOptions{}, &result)
if err != nil {
	return err
}
defer rows.Close()
Result / 618B
{load_definition  {cpu         361
                   wall        366
                   arena_bytes 1664}
 parameters       {cpu         3
                   wall        5
                   arena_bytes 0}
 run              {cpu         1988
                   wall        1987
                   arena_bytes 6408}
 total            {cpu         2368
                   wall        2374
                   arena_bytes 8072}
 arena_capacity   4194304
 work             308
 rows             3
 compile          37
 plan             25
 execute          224
 group            0
 order            14
 stages_completed 3}

A negative Go duration keeps its sign at the ABI boundary

go56B
result := stardust.RunOptions{MaxCost: -time.Nanosecond}
Result / 40B
{page_size 0
 max_cost  -1
 as_of     0}

Run with typed query options

queryText holds this document:

dust58B
find    [?name]
where   [[?e name ?name]]
orderBy [?name]
go356B
definition, err := stardust.Parse(queryText, stardust.DUST)
if err != nil {
	return err
}
defer definition.Close()

query, err := db.Query(definition)
if err != nil {
	return err
}
defer query.Close()

result := stardust.RunOptions{PageSize: 2, MaxCost: time.Second}
rows, err := query.Run(nil, result, nil)
if err != nil {
	return err
}
defer rows.Close()
Result / 46B
{page_size 2
 max_cost  10000000
 as_of     0}

C exports: stardust_db_query_run, stardust_db_rows_error

Query.Close

Release the query handle.

close(handle) releases the handle.

  • Do not use it after closure.
  • Result documents remain usable after the handle that produces them closes.
go23B
func (q *Query) Close()
  • Concurrency: This call is the last use of the receiver and ends its ownership.

Examples

Open an inline query and read its first page

queryText holds this document:

dust58B
find    [?name]
where   [[?e name ?name]]
orderBy [?name]
go400B
definition, err := stardust.Parse(queryText, stardust.DUST)
if err != nil {
	return err
}
defer definition.Close()

query, err := db.Query(definition)
if err != nil {
	return err
}
defer query.Close()

rows, err := query.Run(nil, stardust.RunOptions{}, nil)
if err != nil {
	return err
}
defer rows.Close()

result, err := rows.Next()
if err != nil {
	return err
}
defer result.Close()

query.Close()
Result / 33B
[{name Ada} {name Bob} {name Cy}]

C exports: stardust_db_query_release

Rows.Next

Read the next page as an owned document.

rows.next() returns an owned array document with the next page.

  • An empty array ends the cursor.
  • A page outlives the rows, query and database.

subscription.next(max_wait) returns the next live event with sequence, superseded, transaction and an owned result document.

  • Event 1 is the initial result.
  • The superseded field counts intermediate computed results skipped since this subscription's previous event.
  • Its first event always has 0.
  • Each delivered result is a full replacement.
  • Consumers replace their previous view with this result.

Identical subscriptions share computed results.

  • If another consumer computes two newer results before this consumer calls next, this consumer receives the latest with superseded 1.
  • One rerun can include several commits.
  • Thus, superseded counts neither commits nor changed rows.
  • The sequence field counts delivered events.
  • It advances by one even when the subscription skips results.

The max_wait argument uses the host duration type.

  • The binding gives it to one native call as 100-ns ticks.
  • Zero polls.
  • A positive wait returns when an event exists, or returns no event at the deadline.
  • A representable negative wait reports invalid_argument.
  • Bindings do not divide the wait into shorter waits.

Cancel, close and database close wake a blocked next immediately.

  • The precision of a timed deadline depends on the platform.
  • Windows rounds it to milliseconds.

After cancel or close, the subscription reports cancelled.

  • After database close, it reports closed.
  • A failed rerun is terminal.
  • Every later call reports that failure.
go40B
func (r *Rows) Next() (*Document, error)
  • Concurrency: Other calls can overlap this call, except the release of a handle that this call uses.
  • Ownership: The caller owns the returned handle and releases it.

Errors

StatusWhen
StatusEvaluationFailedthe page does not render
StatusClosedthe rows is closed
StatusOutOfMemorynative memory is exhausted

Examples

Open an inline query and read its first page

queryText holds this document:

dust58B
find    [?name]
where   [[?e name ?name]]
orderBy [?name]
go385B
definition, err := stardust.Parse(queryText, stardust.DUST)
if err != nil {
	return err
}
defer definition.Close()

query, err := db.Query(definition)
if err != nil {
	return err
}
defer query.Close()

rows, err := query.Run(nil, stardust.RunOptions{}, nil)
if err != nil {
	return err
}
defer rows.Close()

result, err := rows.Next()
if err != nil {
	return err
}
defer result.Close()
Result / 33B
[{name Ada} {name Bob} {name Cy}]

C exports: stardust_db_rows_next, stardust_result_take_document, stardust_result_error, stardust_result_release

Rows.Pages

rows.pages() iterates the non-empty pages of the cursor.

rows.pages() lazily iterates the remaining non-empty pages in order.

  • Advancing the iterator reads the next page.
  • Each page is an array document; the iterator does not build a document containing the whole result.
  • The empty page ends iteration and is not yielded.
  • Rust pages belong to the caller.
  • Go, Clojure, Python and Odin pages belong to the iteration and close when it advances; use next to keep an owned page.
  • Close the iterator after an early exit where the language requires explicit cleanup.
  • The cursor stays open until the caller closes it.
  • A failure is reported once, and then iteration ends.
go50B
func (r *Rows) Pages() iter.Seq2[*Document, error]
  • Concurrency: Other calls can overlap this call, except the release of a handle that this call uses.

Errors

StatusWhen
StatusEvaluationFaileda page does not render
StatusClosedthe rows is closed
StatusOutOfMemorynative memory is exhausted

Examples

Iterate the pages of a query run

queryText holds this document:

dust58B
find    [?name]
where   [[?e name ?name]]
orderBy [?name]
go470B
definition, err := stardust.Parse(queryText, stardust.DUST)
if err != nil {
	return err
}
defer definition.Close()

query, err := db.Query(definition)
if err != nil {
	return err
}
defer query.Close()

rows, err := query.Run(nil, stardust.RunOptions{PageSize: 1}, nil)
if err != nil {
	return err
}
defer rows.Close()

result := 0
for page, err := range rows.Pages() {
	if err != nil {
		return err
	}
	if _, err := page.Count(); err != nil {
		return err
	}
	result++
}
Result / 1B
3

C exports: stardust_db_rows_next, stardust_result_take_document, stardust_result_error, stardust_result_release, stardust_document_root, stardust_document_read_many, stardust_document_release

Rows.AllPages

rows.all_pages() reads every remaining page into one owned array document.

rows.all_pages() eagerly reads all remaining pages before returning one owned array document.

  • The document contains every remaining row in order, not an array of page documents.
  • Pages already read from the cursor are excluded.
  • This operation is not lazy: memory grows with the full remaining result.
  • Use pages to process one page at a time.
  • It copies rows through a native builder, preserving typed numbers, member order and duplicate keys, and closes each intermediate page.
  • The caller closes the returned document and the rows cursor.
  • On failure, it releases the partial result and reports the error.
go44B
func (r *Rows) AllPages() (*Document, error)
  • Concurrency: Other calls can overlap this call, except the release of a handle that this call uses.
  • Ownership: The caller owns the returned handle and releases it.

Errors

StatusWhen
StatusEvaluationFaileda page does not render
StatusClosedthe rows is closed
StatusOutOfMemorynative memory is exhausted

Examples

Read all remaining rows into one document

queryText holds this document:

dust58B
find    [?name]
where   [[?e name ?name]]
orderBy [?name]
go400B
definition, err := stardust.Parse(queryText, stardust.DUST)
if err != nil {
	return err
}
defer definition.Close()

query, err := db.Query(definition)
if err != nil {
	return err
}
defer query.Close()

rows, err := query.Run(nil, stardust.RunOptions{PageSize: 1}, nil)
if err != nil {
	return err
}
defer rows.Close()

result, err := rows.AllPages()
if err != nil {
	return err
}
defer result.Close()
Result / 33B
[{name Ada} {name Bob} {name Cy}]

C exports: stardust_db_rows_next, stardust_result_take_document, stardust_result_error, stardust_result_release, stardust_document_count, stardust_document_read_many, stardust_document_i64, stardust_document_f64, stardust_document_release, stardust_document_builder_create, stardust_document_builder_add_many, stardust_document_builder_seal, stardust_document_builder_release

Rows.Close

Release the rows handle.

close(handle) releases the handle.

  • Do not use it after closure.
  • Result documents remain usable after the handle that produces them closes.
go22B
func (r *Rows) Close()
  • Concurrency: This call is the last use of the receiver and ends its ownership.

Examples

Open an inline query and read its first page

queryText holds this document:

dust58B
find    [?name]
where   [[?e name ?name]]
orderBy [?name]
go399B
definition, err := stardust.Parse(queryText, stardust.DUST)
if err != nil {
	return err
}
defer definition.Close()

query, err := db.Query(definition)
if err != nil {
	return err
}
defer query.Close()

rows, err := query.Run(nil, stardust.RunOptions{}, nil)
if err != nil {
	return err
}
defer rows.Close()

result, err := rows.Next()
if err != nil {
	return err
}
defer result.Close()

rows.Close()
Result / 33B
[{name Ada} {name Bob} {name Cy}]

C exports: stardust_db_rows_release

Query.Subscribe

query.subscribe(parameters, options) opens an owned live subscription.

  • Parameters apply a merge patch to the declared defaults as in run.
  • The call copies the definition and parameters.
  • For a stored path, a positive options.as_of selects the historical definition.
  • Later definition edits do not affect the subscription.

Options use as_of and max_cost.

  • The call ignores page_size.

Query documents.

go90B
func (q *Query) Subscribe(parameters *Document, options RunOptions) (*Subscription, error)
  • Concurrency: Other calls can overlap this call, except the release of a handle that this call uses.
  • Ownership: The caller owns the returned handle and releases it.

Parameters

ParameterTypeOwnershipDefaultMeaning
parameters*DocumentBorrowed for the callAbsent means no supplied parametersNamed values bound for this execution.
optionsRunOptionsValueRequired options record. See field defaultsThe operation's options record. See its field defaults.

Errors

StatusWhen
StatusInvalidDefinitionthe query or its callable definitions are invalid
StatusInvalidArgumentthe parameters or subscription options are invalid
StatusClosedthe query is closed
StatusOutOfMemorynative memory is exhausted

Examples

query/subscribe

queryText holds this document:

dust58B
find    [?name]
where   [[?e name ?name]]
orderBy [?name]
go456B
definition, err := stardust.Parse(queryText, stardust.DUST)
if err != nil {
	return err
}
defer definition.Close()

query, err := db.Query(definition)
if err != nil {
	return err
}
defer query.Close()

subscription, err := query.Subscribe(nil, stardust.RunOptions{})
if err != nil {
	return err
}
defer subscription.Close()

event, err := subscription.Next(context.Background(), 0)
if err != nil {
	return err
}

result := event.Result
defer result.Close()
Result / 33B
[{name Ada} {name Bob} {name Cy}]

Read the complete initial subscription event

queryText holds this document:

dust58B
find    [?name]
where   [[?e name ?name]]
orderBy [?name]
go440B
definition, err := stardust.Parse(queryText, stardust.DUST)
if err != nil {
	return err
}
defer definition.Close()

query, err := db.Query(definition)
if err != nil {
	return err
}
defer query.Close()

subscription, err := query.Subscribe(nil, stardust.RunOptions{})
if err != nil {
	return err
}
defer subscription.Close()

result, err := subscription.Next(context.Background(), 0)
if err != nil {
	return err
}
defer result.Result.Close()
Result / 92B
{sequence    1
 superseded  0
 transaction 4
 result      [{name Ada} {name Bob} {name Cy}]}

C exports: stardust_db_query_subscribe, stardust_db_subscription_error

Subscription.Next

Wait for the next live event.

rows.next() returns an owned array document with the next page.

  • An empty array ends the cursor.
  • A page outlives the rows, query and database.

subscription.next(max_wait) returns the next live event with sequence, superseded, transaction and an owned result document.

  • Event 1 is the initial result.
  • The superseded field counts intermediate computed results skipped since this subscription's previous event.
  • Its first event always has 0.
  • Each delivered result is a full replacement.
  • Consumers replace their previous view with this result.

Identical subscriptions share computed results.

  • If another consumer computes two newer results before this consumer calls next, this consumer receives the latest with superseded 1.
  • One rerun can include several commits.
  • Thus, superseded counts neither commits nor changed rows.
  • The sequence field counts delivered events.
  • It advances by one even when the subscription skips results.

The max_wait argument uses the host duration type.

  • The binding gives it to one native call as 100-ns ticks.
  • Zero polls.
  • A positive wait returns when an event exists, or returns no event at the deadline.
  • A representable negative wait reports invalid_argument.
  • Bindings do not divide the wait into shorter waits.

Cancel, close and database close wake a blocked next immediately.

  • The precision of a timed deadline depends on the platform.
  • Windows rounds it to milliseconds.

After cancel or close, the subscription reports cancelled.

  • After database close, it reports closed.
  • A failed rerun is terminal.
  • Every later call reports that failure.
go87B
func (s *Subscription) Next(ctx context.Context, maxWait time.Duration) (*Event, error)
  • Concurrency: Other calls can overlap this call, except the release of a handle that this call uses.

Parameters

ParameterTypeOwnershipDefaultMeaning
ctxcontext.ContextValueRequiredContext controlling cancellation of the call.
maxWaittime.DurationValueRequiredThe maximum wait for the next event, as a native duration.

Errors

StatusWhen
StatusInvalidArgumentmax_wait is negative
StatusCancelledthe subscription is cancelled or closed
StatusEvaluationFaileda rerun of the query failed. Every later call reports this failure
StatusClosedthe subscription is closed
StatusOutOfMemorynative memory is exhausted

Examples

subscription/next

queryText holds this document:

dust58B
find    [?name]
where   [[?e name ?name]]
orderBy [?name]
go456B
definition, err := stardust.Parse(queryText, stardust.DUST)
if err != nil {
	return err
}
defer definition.Close()

query, err := db.Query(definition)
if err != nil {
	return err
}
defer query.Close()

subscription, err := query.Subscribe(nil, stardust.RunOptions{})
if err != nil {
	return err
}
defer subscription.Close()

event, err := subscription.Next(context.Background(), 0)
if err != nil {
	return err
}

result := event.Result
defer result.Close()
Result / 33B
[{name Ada} {name Bob} {name Cy}]

C exports: stardust_db_subscription_next, stardust_db_subscription_error, stardust_document_release

Subscription.All

subscription.events() delivers events in order until the subscription is cancelled, closes or fails.

  • It waits with no deadline between events.
  • The consumer owns and closes each result.
  • Cancellation and closure end the iteration without an error.
  • A failed rerun is reported once, and then the iteration ends.
  • Leaving the iteration early cancels the subscription; the subscription still needs close.
go72B
func (s *Subscription) All(ctx context.Context) iter.Seq2[*Event, error]
  • Concurrency: Other calls can overlap this call, except the release of a handle that this call uses.

Parameters

ParameterTypeOwnershipDefaultMeaning
ctxcontext.ContextValueRequiredContext controlling cancellation of the call.

Errors

Cancellation and closure end iteration. The iteration reports other terminal failures.

StatusWhen
StatusEvaluationFaileda rerun of the query failed
StatusOutOfMemorynative memory is exhausted

Examples

subscription/events

queryText holds this document:

dust58B
find    [?name]
where   [[?e name ?name]]
orderBy [?name]
go505B
definition, err := stardust.Parse(queryText, stardust.DUST)
if err != nil {
	return err
}
defer definition.Close()

query, err := db.Query(definition)
if err != nil {
	return err
}
defer query.Close()

subscription, err := query.Subscribe(nil, stardust.RunOptions{})
if err != nil {
	return err
}
defer subscription.Close()

var result *stardust.Document
for event, err := range subscription.All(context.Background()) {
	if err != nil {
		return err
	}
	result = event.Result
	break
}
defer result.Close()
Result / 33B
[{name Ada} {name Bob} {name Cy}]

C exports: stardust_db_subscription_next, stardust_db_subscription_error

Subscription.Cancel

subscription.cancel() ends the subscription.

  • Any thread can call it.
  • Each blocked next returns cancelled immediately, and later calls also report cancelled.
  • A second cancel has no effect.
  • The subscription still needs close, which cancels, waits for active calls and releases the handle.
go31B
func (s *Subscription) Cancel()
  • Concurrency: Other calls can overlap this call, except the release of a handle that this call uses.

Examples

subscription/cancel

queryText holds this document:

dust58B
find    [?name]
where   [[?e name ?name]]
orderBy [?name]
go478B
definition, err := stardust.Parse(queryText, stardust.DUST)
if err != nil {
	return err
}
defer definition.Close()

query, err := db.Query(definition)
if err != nil {
	return err
}
defer query.Close()

subscription, err := query.Subscribe(nil, stardust.RunOptions{})
if err != nil {
	return err
}
defer subscription.Close()

event, err := subscription.Next(context.Background(), 0)
if err != nil {
	return err
}
subscription.Cancel()

result := event.Result
defer result.Close()
Result / 33B
[{name Ada} {name Bob} {name Cy}]

C exports: stardust_db_subscription_cancel

Subscription.Close

Release the subscription handle.

close(handle) releases the handle.

  • Do not use it after closure.
  • Result documents remain usable after the handle that produces them closes.
go30B
func (s *Subscription) Close()
  • Concurrency: This call is the last use of the receiver and ends its ownership.

Examples

subscription/close

queryText holds this document:

dust58B
find    [?name]
where   [[?e name ?name]]
orderBy [?name]
go478B
definition, err := stardust.Parse(queryText, stardust.DUST)
if err != nil {
	return err
}
defer definition.Close()

query, err := db.Query(definition)
if err != nil {
	return err
}
defer query.Close()

subscription, err := query.Subscribe(nil, stardust.RunOptions{})
if err != nil {
	return err
}
defer subscription.Close()

event, err := subscription.Next(context.Background(), 0)
if err != nil {
	return err
}

result := event.Result
defer result.Close()

subscription.Close()
Result / 33B
[{name Ada} {name Bob} {name Cy}]

C exports: stardust_db_subscription_release

Mutation.Run

Run the mutation and return commit information.

handle.run(parameters, options) runs a query or mutation.

  • Parameters apply a JSON merge patch (RFC 7396) to the declared defaults.
  • Omitted parameters keep their defaults.
  • Absent parameters have the same effect as an empty object.
  • Objects merge recursively.
  • Other values replace the defaults, including tagged values such as {#utc …}.

A name matches with or without its leading ?.

  • A null parameter has no value, so the run fails with missing_parameter.

Query runs return owned rows.

  • Mutation runs return commit information.
  • Options include as_of, max_cost and query page_size.
  • The as_of option selects a historical stored definition.

Mutation documents.

go106B
func (m *Mutation) Run(parameters *Document, options RunOptions, explain *MutationExplain) (Commit, error)
  • Concurrency: Other calls can overlap this call, except the release of a handle that this call uses.

Parameters

ParameterTypeOwnershipDefaultMeaning
parameters*DocumentBorrowed for the callAbsent means no supplied parametersNamed values bound for this execution.
optionsRunOptionsValueRequired options record. See field defaultsThe operation's options record. See its field defaults.
explain*MutationExplainCaller-owned outputAbsent skips explain outputOptional explain output. This record contains explain output for mutation run.

Errors

StatusWhen
StatusInvalidDefinitionthe mutation selection or definition is invalid
StatusInvalidArgumentthe parameters or run options are invalid
StatusSchemaViolationthe write breaks a schema
StatusConflictconcurrent writes prevent the commit
StatusRejecteda mutation target or write guard refuses the write
StatusEvaluationFailedthe mutation fails
StatusClosedthe mutation is closed
StatusOutOfMemorynative memory is exhausted

Examples

mutation/run

birthdayText holds this document:

dust68B
query {find  [?e]
       where [[?e name Ada]]}
patch {?e {age 37}}
go292B
source, err := stardust.Parse(birthdayText, stardust.DUST)
if err != nil {
	return err
}
defer source.Close()

mutation, err := db.Mutation(source)
if err != nil {
	return err
}
defer mutation.Close()

result, err := mutation.Run(nil, stardust.RunOptions{}, nil)
if err != nil {
	return err
}
Result / 105B
{status       committed
 transaction  5
 facts        1
 committed_at 17915443416714906
 ids          {}}

Explain mutation execution

birthdayText holds this document:

dust68B
query {find  [?e]
       where [[?e name Ada]]}
patch {?e {age 37}}
go328B
source, err := stardust.Parse(birthdayText, stardust.DUST)
if err != nil {
	return err
}
defer source.Close()

mutation, err := db.Mutation(source)
if err != nil {
	return err
}
defer mutation.Close()

var result stardust.MutationExplain
if _, err := mutation.Run(nil, stardust.RunOptions{}, &result); err != nil {
	return err
}
Result / 495B
{load_definition  {cpu         343
                   wall        348
                   arena_bytes 2304}
 parameters       {cpu         4
                   wall        6
                   arena_bytes 0}
 run              {cpu         2019
                   wall        28517
                   arena_bytes 24640}
 total            {cpu         2395
                   wall        28900
                   arena_bytes 26944}
 arena_capacity   4194304
 stages_completed 3
 attempts         1}

C exports: stardust_db_mutation_run, stardust_db_result_commit_info, stardust_result_error, stardust_result_release

Mutation.Close

Release the mutation handle.

close(handle) releases the handle.

  • Do not use it after closure.
  • Result documents remain usable after the handle that produces them closes.
go26B
func (m *Mutation) Close()
  • Concurrency: This call is the last use of the receiver and ends its ownership.

Examples

mutation/close

birthdayText holds this document:

dust68B
query {find  [?e]
       where [[?e name Ada]]}
patch {?e {age 37}}
go309B
source, err := stardust.Parse(birthdayText, stardust.DUST)
if err != nil {
	return err
}
defer source.Close()

mutation, err := db.Mutation(source)
if err != nil {
	return err
}
defer mutation.Close()

result, err := mutation.Run(nil, stardust.RunOptions{}, nil)
if err != nil {
	return err
}
mutation.Close()
Result / 105B
{status       committed
 transaction  5
 facts        1
 committed_at 17915443416384677
 ids          {}}

C exports: stardust_db_mutation_release

Database.MergePatch

database.merge_patch(patch) applies an entity-keyed patch document in one transaction and returns commit information. Temporary names use #_name and transaction metadata uses #_tx.

Patch documents.

go85B
func (d *Database) MergePatch(patch *Document, explain *PatchExplain) (Commit, error)
  • Concurrency: Other calls can overlap this call, except the release of a handle that this call uses.

Parameters

ParameterTypeOwnershipDefaultMeaning
patch*DocumentBorrowed for the callRequiredAn entity-keyed native patch document for one transaction. Temporary names use #_name. Transaction metadata uses #_tx.
explain*PatchExplainCaller-owned outputAbsent skips explain outputOptional explain output. This record contains explain output for merge_patch.

Errors

StatusWhen
StatusInvalidCommitTimethe #_tx commit time is not later than the last commit
StatusRejectedthe database refuses the patch
StatusInvalidArgumentthe patch is not an entity-keyed object
StatusClosedthe database is closed
StatusOutOfMemorynative memory is exhausted

Examples

database/merge_patch

patchText holds this document:

dust232B
#_ada {name Ada
       role engineer
       age  36}
#_bob {name   Bob
       role   engineer
       age    41
       mentor {#link #_ada}}
#_cy  {name Cy
       role designer
       age  29}
#_tx  {author smoke
       reason seed}
go176B
patch, err := stardust.Parse(patchText, stardust.DUST)
if err != nil {
	return err
}
defer patch.Close()

result, err := db.MergePatch(patch, nil)
if err != nil {
	return err
}
Result / 159B
{status       committed
 transaction  4
 facts        12
 committed_at 17915443414178231
 ids          {#_ada 1
               #_bob 2
               #_cy  3}}

Explain patch validation and commit

patchText holds this document:

dust232B
#_ada {name Ada
       role engineer
       age  36}
#_bob {name   Bob
       role   engineer
       age    41
       mentor {#link #_ada}}
#_cy  {name Cy
       role designer
       age  29}
#_tx  {author smoke
       reason seed}
go209B
patch, err := stardust.Parse(patchText, stardust.DUST)
if err != nil {
	return err
}
defer patch.Close()

var result stardust.PatchExplain
if _, err := db.MergePatch(patch, &result); err != nil {
	return err
}
Result / 372B
{copy_patch       {cpu         399
                   wall        434
                   arena_bytes 3080}
 commit           {cpu         248
                   wall        15494
                   arena_bytes 8200}
 total            {cpu         685
                   wall        15966
                   arena_bytes 11294}
 arena_capacity   4194304
 stages_completed 2}

Refuse a metadata-only transaction

patchText holds this document:

dust16B
#_tx {author x}
go144B
patch, err := stardust.Parse(patchText, stardust.DUST)
if err != nil {
	return err
}
defer patch.Close()

_, result := db.MergePatch(patch, nil)
Result / 203B
{code    invalid
 message the write is invalid: check entity ids, field names, values and #_tx (a patch of only #_tx is refused)
 path    null
 field   null
 entity  null
 offset  null
 status  rejected}

Refuse a repeated commit time

futureText holds this document:

dust67B
#_d  {x 1}
#_tx {stardust/committedAt {#utc 2200-01-01T00:00:00Z}}

patchText holds this document:

dust67B
#_e  {x 2}
#_tx {stardust/committedAt {#utc 2200-01-01T00:00:00Z}}
go322B
future, err := stardust.Parse(futureText, stardust.DUST)
if err != nil {
	return err
}
defer future.Close()

if _, err := db.MergePatch(future, nil); err != nil {
	return err
}

patch, err := stardust.Parse(patchText, stardust.DUST)
if err != nil {
	return err
}
defer patch.Close()

_, result := db.MergePatch(patch, nil)
Result / 195B
{code    invalid_commit_time
 message stardust/committedAt must be strictly newer than the latest commit time
 path    null
 field   null
 entity  null
 offset  null
 status  invalid_commit_time}

C exports: stardust_db_merge_patch, stardust_db_result_commit_info, stardust_result_error, stardust_result_release

run_options

This record supplies options for query and mutation run. Zero selects each default. Mutations use DB_Write_Options, whose fields are a subset.

FieldTypeUnitRangeMeaning
page_sizeuint32CountHost type rangeRows per page. 0 selects the default page size. Queries only.
max_costtime.DurationHost duration (100 ns ticks at the ABI)Tick rangeThread CPU duration limit. 0 selects the engine’s dynamic budget.
as_ofint64NoneHost type rangeA positive transaction runs a stored definition as of that transaction.

commit

This record contains the result of mutation run, merge_patch and patch_definition.

FieldTypeUnitRangeAbsentMeaning
statusCommitStatusNoneHost type range——
transactionint64NoneHost type range—Zero when nothing was written.
factsint64CountHost type range——
committed_attime.TimeUTC instant (100 ns ticks since the Unix epoch at the ABI)Tick rangeThe zero time.TimeRecorded commit time as a UTC instant. The call measures this value. Independent calls can differ.
idsmap[string]int64NoneHost type range—Maps each #_name of a merge patch to its entity.

event

This record contains the result of subscription next.

FieldTypeUnitMeaning
sequenceint64CountEvent number. Event 1 is the initial result.
supersededint64CountIntermediate computed results skipped by this subscription since its previous event. Zero for its first event. The delivered result replaces them in full. This value counts neither commits nor changed rows.
transactionint64NoneTransaction the result was computed at.
result*DocumentNoneThe full query result. The event owns it and the consumer closes it.