A few queries. A bigger picture.

Small examples make the design easier to reason about. These snippets illustrate the proposed language. They are not a runnable tutorial or a claim that an engine is available.

Start small. Ask a useful question.

This table is the foundation for the examples below. Values permit unknown unless constrained otherwise.

Define playersShiverDB SQL
create table player (
  id generated,
  name text not unknown,
  level int32 not unknown default 1,
  gold int64 not unknown default 0,
  last_seen instant
)
Find experienced playersShiverDB SQL
select id, name, level
from player
where level >= :minimum_level
order by level desc, id asc
limit 50

:minimum_level is supplied by the caller. Explicit ordering makes the intent clear; ordering by identity resolves equal levels.

Ask whether a value is missing.

Players without a last-seen valueShiverDB SQL
select id, name
from player
where last_seen is unknown
order by id asc

Do not write last_seen = unknown. Direct comparison against the literal is invalid. An unknown value is not implicitly a zero timestamp.

Make a protected update.

This database-local routine debits a known player. Both invalid input and insufficient funds raise errors instead of silently doing nothing. It assumes trusted invocation; application authorization belongs in policies or additional checks.

A single transactional operationShiverDB SQL
routine spend_gold(player_id, amount)
  if amount is unknown or amount <= 0 then
    error('amount must be positive')
  end

  local buyer = select id, gold
    from player:player_id
    for update

  if buyer is unknown then
    error('player not found')
  end

  if buyer.gold < amount then
    error('insufficient gold')
  end

  update player:player_id
  set gold = gold - amount
end

for update requests update protection without prescribing a physical lock. Persistence is the explicit update, not a change to the local buyer value. An uncaught error rolls back the routine transaction.

A normal routine cannot perform external I/O. Sending a payment or webhook outside the database needs the external-routine rules, not an assumption that a retry is harmless.

Give a relationship its own data.

Relations connect records and can carry fields. Assume players 10 and 20 already exist.

A friendship with a timestampShiverDB SQL
create relation friendship
  from player
  to player
{
  since instant,
  trust float32
}

relate player:10
  to player:20
  through friendship {
    since = now(),
    trust = 0.8
  }

select friend.id, friend.name
from player:10
through friendship
to player as friend
where friendship.trust > 0.5

This is not a separate graph consistency model. Relations participate in the same transactions, authorization, indexing, and change mechanisms as other records.

Keep a query result current.

Follow experienced playersShiverDB SQL
subscribe experienced_players as
select id, name, level
from player
where level >= :minimum_level

The subscription first yields a snapshot, then ordered committed deltas. Delta order follows commits; it does not imply a row sort order for the result. Rolled-back changes never appear.

Use changes player since :cursor when you want mutation history instead. A maintained result and a durable changefeed answer different questions.

Next: read the source specifications

From the specifications

This guide explains the design. The original documents carry the precise requirements and recommendations.