A declared derived relation chooses pull or push maintenance #152
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
K2 — A declared derived relation chooses pull or push maintenance
Status: draft, ready to file on PerishLab/keel. Blocks nothing. Deliberately
separate from K1: K1 is one concrete unblocking ask, and its three previous
drafts all went wrong by widening. This is the wide one, and it should stay in
its own room.
Where the engine stands today
The read side is complete and the write side is empty.
docs/model/edge.mdgives one traversal shape: bond bags are the liveclosure of the current root bag, computed at read time, forward bonds
only, depth 1 per tree, no engine-invented reverse edges. Past the engine
cap
C0the query errors; silent partial closures are forbidden. Deepgraphs are told to use another top-level query rather than nested links.
docs/run/trigger.mdcloses the other door on purpose: triggers arepost-commit, observe-only, thin, and consumers never participate in the write
path — the stated immunity to the SQL-trigger and ORM-callback disease.
So a caller that needs anything beyond depth 1 has exactly two options today,
and both are bad in the same way: issue N top-level queries per request, or
hand-maintain a shadow table and be responsible for its correctness forever.
The engine owns the traversal it does support; it owns nothing of the one it
doesn't.
The ask
Let a declared derived relation state how it is maintained:
semantics that already exist;
inputs, read afterwards as an ordinary relation.
Both sides engine-owned. The declaration is the caller's choice; the
correctness is not.
The classic form of this trade-off is fanout-on-read versus fanout-on-write,
and the well-known answer in practice is that neither wins outright — which is
the argument for making it a declared property rather than an engine-wide
verdict.
Two instances from one product, landing on opposite ends
Nested organisation closure. Sits on the authorization read path. A stale
answer is a security defect, not a slow page: a revoked membership that remains
effective for a delivery lag is a real grant. Wants push, inside the write
transaction. (This is K1, and it can land without this issue.)
A one-way follow relation. A broadcast timeline. Tolerates lag by nature,
and its hot query is the one the engine refuses to generate: forward bonds give
"who I follow" for free and never give "who follows me". This is where fanout
strategy actually earns its keep, and where a hybrid is normal.
Two relations in one product, opposite ends of the same trade-off, is the
reason to make it declarable.
Open, not proposed
many-to-many closure, or whether the general case needs a projection language
that would be too much engine.
should refuse a declaration whose fanout it cannot bound — the
C0instinctapplied to the write side.