You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/architecture.md
+14-2Lines changed: 14 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -142,17 +142,29 @@ Each kind has independent leader election. A sequencer leader failure does not a
142
142
143
143
Write transactions that touch multiple vShards go through the **Calvin sequencer** rather than two-phase commit. The sequencer Raft group produces a globally-ordered log of transaction batches (epochs, default 20 ms). Within each epoch, the scheduler derives a deterministic lock order and the executor runs all writes concurrently without cross-shard coordination.
144
144
145
+
**Interactive transactions are atomic across shards.** A `BEGIN ... COMMIT` block whose statements span multiple vShards (or nodes) flushes at COMMIT as one Calvin transaction bound by a durable **Vote/Verdict barrier**: each participant replicates a commit/abort vote through the sequencer log; when the tally completes, a replicated verdict commits or drops every participant's staged writes together. Expected-participant counts are seeded from the replicated epoch batch, so the barrier survives sequencer failover. Read-only participants count too — a transaction that wrote shard X but read shard Y validates and votes on both.
146
+
147
+
**Serializable OCC.** Reads recorded during the transaction (point reads, predicate scans, index equality/range probes, both sides of gathered cross-node JOINs) are validated at COMMIT against per-key, per-collection, and per-index-value write LSNs. A stale read aborts the transaction with SQLSTATE `40001` (retryable) instead of committing silently.
148
+
149
+
**Durability.** A committed transaction's writes are persisted as a single atomically-replayable `TransactionRedo` WAL record appended before the commit is acknowledged. WAL-only recovery replays it in LSN order, rebuilding even in-memory secondary indexes (vector HNSW, FTS postings) that base storage cannot reconstruct alone.
150
+
145
151
For value-dependent predicates (e.g., `WHERE balance > 0`), the executor uses **OLLP** (Optimistic Lock Location Prediction): optimistically proceed, then re-validate and retry on mismatch. A circuit breaker opens when the retry ratio exceeds 50% for a predicate class.
146
152
147
153
```sql
148
154
-- Require atomic cross-shard writes (default)
149
155
SET cross_shard_txn ='strict';
150
156
151
-
-- Opt out of atomicity for bulk loads (each shard commits independently)
157
+
-- Opt out of atomicity for bulk loads: writes are grouped per vShard and each
158
+
-- group commits as an independent single-vShard transaction; a failure does NOT
159
+
-- roll back vShards that already committed
152
160
SET cross_shard_txn ='best_effort_non_atomic';
153
161
```
154
162
155
-
Single-shard writes bypass the sequencer entirely and go directly through the relevant data-group Raft.
163
+
(Bare `best_effort` is deliberately rejected; invalid values return SQLSTATE `22023`.)
164
+
165
+
**Single-node deployments run Calvin by default** (`[server] single_node_calvin = true`): a standalone node synthesizes a one-node sequencer group so transactions spanning multiple cores (vShards) commit atomically instead of being rejected. Set it `false` to force the legacy fast path. Uncontended single-shard point writes bypass the sequencer entirely and go directly through the relevant data-group Raft; contended or predicate/bulk writes route through the deterministic scheduler.
166
+
167
+
**Overlay hygiene.** Per-transaction staging overlays are kept alive by every staged write/read; overlays orphaned by vanished clients are reaped after a 6-hour lease. The `nodedb_active_txn_overlays` Prometheus gauge tracks live overlays. Data-Plane resource rejection surfaces as SQLSTATE `53200` (backpressure — retry when pressure subsides).
Copy file name to clipboardExpand all lines: docs/bitemporal.md
+2Lines changed: 2 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -164,6 +164,8 @@ ORDER BY _ts_system ASC;
164
164
165
165
`AS OF SYSTEM TIME NULL` returns every system-time version of each matching row, ordered ascending. Each version row carries the user columns plus three synthetic temporal columns: `_ts_system`, `_ts_valid_from`, and `_ts_valid_until`. Unbounded valid-time ends surface as the raw `i64::MIN` / `i64::MAX` sentinels (matching the Columnar and Timeseries engines). It is supported on the Document (strict and schemaless), Columnar, and Timeseries engines. It is not supported on the Graph or Array engines, nor when reading through a database clone — those return a typed error rather than collapsing to a single version.
166
166
167
+
`AS OF` reads run at parity with non-temporal reads: `WHERE` predicates (including on strict Binary-Tuple collections), `ORDER BY`, computed columns, and window functions all apply to temporal queries.
168
+
167
169
**Reserved columns never leak.** Bitemporal collections store their temporal envelope in reserved columns (`__system_from_ms`, `__valid_from_ms`, `__valid_until_ms`). These are hidden from user projections: `SELECT *` on a bitemporal collection returns exactly the declared user columns. Temporal data is only exposed through the synthetic `_ts_*` columns of audit queries.
Copy file name to clipboardExpand all lines: docs/databases.md
+2Lines changed: 2 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -337,6 +337,8 @@ ALTER DATABASE analytics SET IDLE_TIMEOUT 0; -- disabled
337
337
338
338
Sessions idle longer than the configured time are automatically closed with `SESSION_IDLE_TIMEOUT`. Tracks are monitored per-database; timeout is checked at request boundaries.
339
339
340
+
Separately, a process-global pgwire listener watchdog force-closes idle connections after `auth.idle_timeout_secs` (default 3600s; `auth.session_absolute_timeout_secs` caps total session age, default disabled). The watchdog never kills a connection mid-statement — the idle window starts when a statement completes — and its teardown reclaims any idle-in-transaction staging overlay. The per-database `SET IDLE_TIMEOUT` and the global watchdog are independent mechanisms; the stricter one wins.
Copy file name to clipboardExpand all lines: docs/documents.md
+37Lines changed: 37 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -137,6 +137,43 @@ FROM orders
137
137
GROUP BY status;
138
138
```
139
139
140
+
## CRDT Document Collections
141
+
142
+
Declare a document collection CRDT-backed at creation time and plain SQL DML converges via last-writer-wins instead of overwriting:
143
+
144
+
```sql
145
+
CREATE COLLECTION crdt_notes (
146
+
id TEXTPRIMARY KEY,
147
+
title TEXT,
148
+
body TEXT
149
+
) WITH (crdt=true);
150
+
151
+
-- Full-replace write (untouched keys pruned)
152
+
INSERT INTO crdt_notes (id, title, body) VALUES ('a', 'v1', 'text');
153
+
UPSERT INTO crdt_notes (id, title) VALUES ('a', 't2');
154
+
155
+
-- PK-targeted UPDATE is a per-field LWW merge: only the provided
156
+
-- fields are written; untouched fields survive concurrent writers
157
+
UPDATE crdt_notes SET title ='t3'WHERE id ='a';
158
+
159
+
-- PK-targeted DELETE writes a tombstone
160
+
DELETEFROM crdt_notes WHERE id ='a';
161
+
162
+
-- RETURNING works on CRDT UPDATE/DELETE
163
+
UPDATE crdt_notes SET title ='t4'WHERE id ='a' RETURNING id, title;
164
+
DELETEFROM crdt_notes WHERE id ='a' RETURNING id;
165
+
```
166
+
167
+
`crdt=true` is only valid on document collections. DML on a CRDT collection routes through the CRDT engine — there is no silent fallthrough to the plain document path (that would bypass convergence). Statement shapes that cannot be expressed as a CRDT operation are rejected with a typed error rather than downgraded:
168
+
169
+
- Predicate (non-primary-key) `UPDATE` / `DELETE`
170
+
-`UPDATE` with a non-literal right-hand side (`SET count = count + 1`)
171
+
-`INSERT ... ON CONFLICT DO UPDATE`
172
+
173
+
The `crdt` flag is part of the collection descriptor: it replicates across the cluster and travels in sync `CollectionSchema` announcements, so Lite/WASM peers see the same convergence semantics.
174
+
175
+
**Movable lists (SDK).** The client SDK exposes CRDT movable-list operations on documents: `list_insert(collection, doc_id, list_path, index, fields)`, `list_delete(...)`, and `list_move(collection, doc_id, list_path, from_index, to_index)` — dispatched as native opcodes and merged conflict-free across devices.
Copy file name to clipboardExpand all lines: docs/offline-sync-patterns.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -117,7 +117,7 @@ Columnar, Vector, FTS, and Spatial collections now participate in **inbound sync
117
117
118
118
**Schema announce.** A sync peer announces each collection's schema (`CollectionSchema` message) before sending any shape or delta data. Collections unknown to the receiver are materialized into its catalog and propagate cluster-wide via Raft — create-only, so an existing collection is never clobbered. A Lite client can therefore bootstrap collections on Origin simply by announcing their schema.
119
119
120
-
**Constraint validation and rejects.** UNIQUE, FK, required-field, and CHECK constraints are validated when deltas apply on Origin. Because CRDT deltas are commutative and already merged on import, enforcement is a post-hoc pass: a violating row is quarantined and the client receives a `DeltaReject` carrying a typed `CompensationHint` (e.g., `UniqueViolation { field, conflicting_value }`, `RetryWithDifferentValue`, `ManualIntervention`) telling it precisely what to fix. A rejected delta does not wedge the stream — later deltas continue to apply.
120
+
**Constraint validation and rejects.** UNIQUE, FK, required-field, and CHECK constraints are validated when deltas apply on Origin. Because CRDT deltas are commutative and already merged on import, enforcement is a post-hoc pass: a violating row is quarantined and the client receives a `DeltaReject` carrying a typed `CompensationHint` (e.g., `UniqueViolation { field, conflicting_value }`, `RetryWithDifferentValue`, `ManualIntervention`) telling it precisely what to fix. A rejected delta does not wedge the stream — later deltas continue to apply. A delta must also carry exactly **one document** — cross-engine identity binds one surrogate per delta — so a delta writing rows outside its frame target is rejected with `RejectedConstraint { constraint: "crdt_single_document_delta" }`.
121
121
122
122
**Durability.** Acknowledged sync writes are quorum-durable: the delta commits through the data group's Raft log before the ack, so it survives leader failover. Producers carry `(producer_id, epoch, seq)` provenance; replays are acknowledged as duplicates rather than double-applied.
Copy file name to clipboardExpand all lines: docs/query-language.md
+29-3Lines changed: 29 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -49,6 +49,8 @@ SELECT * FROM users WHERE role IN ('admin', 'editor');
49
49
SELECT*FROM users WHERE deleted_at IS NULL;
50
50
```
51
51
52
+
Timestamp-valued strings compare by instant, not bytes: a stored ISO-8601 value (`'2026-07-02T13:00:00.000000Z'`) matches a SQL-style literal (`'2026-07-02 13:00:00'`) in `=` and range predicates when both sides parse as datetimes. Non-datetime strings keep lexicographic comparison.
53
+
52
54
### Aggregates
53
55
54
56
```sql
@@ -722,6 +724,21 @@ WHERE category = 'machine-learning'
722
724
);
723
725
```
724
726
727
+
### Sparse Vector Search
728
+
729
+
```sql
730
+
-- Dimensionless sparse-vector column; values are '{dimension: weight}' literals
731
+
CREATETABLEsparse_docs (id TEXTPRIMARY KEY, terms SPARSEVECTOR);
ORDER BY sparse_score(terms, '{3: 1.0, 7: 0.5}') DESC
737
+
LIMIT3;
738
+
```
739
+
740
+
The inverted index is maintained automatically on document writes (insert, update, delete). Documents sharing no dimension with the query are never scanned. `sparse_score` is a standalone surface — it is not fused into `rrf_score` hybrid ranking.
741
+
725
742
### Full-Text Search
726
743
727
744
```sql
@@ -856,13 +873,18 @@ SELECT * FROM events WHERE doc_array_contains(payload, '$.tags', 'important');
856
873
### CRDT
857
874
858
875
```sql
859
-
-- Read CRDT state
860
-
SELECT crdt_state('collab_docs', 'doc123');
876
+
-- Declare a document collection CRDT-backed: plain DML converges via LWW
877
+
CREATE COLLECTION notes (id TEXTPRIMARY KEY, title TEXT, body TEXT) WITH (crdt=true);
878
+
UPDATE notes SET title ='t2'WHERE id ='a'; -- per-field LWW merge
879
+
DELETEFROM notes WHERE id ='a' RETURNING id; -- tombstone
`WITH (crdt=true)` is document-collection-only. Non-PK-targeted UPDATE/DELETE, non-literal SET values, and `ON CONFLICT DO UPDATE` are rejected on CRDT collections (no representable CRDT operation). See [Documents — CRDT Document Collections](documents.md#crdt-document-collections).
887
+
866
888
### Array (NDArray)
867
889
868
890
```sql
@@ -967,6 +989,10 @@ COMMIT;
967
989
968
990
Isolation level: **Snapshot Isolation (SI)**. Reads see a consistent snapshot from `BEGIN` time. Write conflicts detected at `COMMIT` and surfaced as SQLSTATE `40001` (`could not serialize access due to concurrent update`).
969
991
992
+
### Cross-Shard Transactions
993
+
994
+
An interactive `BEGIN ... COMMIT` block whose statements span multiple vShards or nodes commits **atomically** by default — the whole block flushes through the Calvin sequencer's durable vote/verdict barrier at COMMIT. Reads taken during the transaction (point reads, predicate scans, index probes, both sides of distributed JOINs) are OCC-validated at COMMIT; a stale read aborts with `40001` (retry the transaction). `SET cross_shard_txn = 'best_effort_non_atomic'` opts bulk loads out of cross-shard atomicity. Single-node deployments run the same path by default (`single_node_calvin = true`), so transactions spanning cores commit atomically too. See [Architecture — Cross-Shard Transactions](architecture.md#cross-shard-transactions).
995
+
970
996
### Read-Your-Own-Writes
971
997
972
998
Statements inside `BEGIN ... COMMIT` are staged in a per-transaction overlay on the Data Plane. Reads within the same transaction observe staged writes **across every engine**: KV, document (schemaless and strict), columnar, timeseries, graph (single-hop, multi-hop, shortest path), vector search, spatial predicates, full-text search, and hybrid search fusion. Constraint violations (e.g., primary-key uniqueness) surface immediately at statement time, not at COMMIT.
Copy file name to clipboardExpand all lines: docs/real-time.md
+7Lines changed: 7 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -71,6 +71,13 @@ SHOW TRIGGERS;
71
71
|`SYNC`| Same transaction (ACID) | Trigger time added | Yes |
72
72
|`DEFERRED`| Same transaction, batched | At COMMIT time | Yes |
73
73
74
+
**Graph mutations emit events.** Graph edge and node-label writes publish `WriteEvent`s like any other mutation, so triggers, change streams, and streaming MVs can react to graph changes:
75
+
76
+
-**Edges** — published on the edge's collection with a stable `row_id` composed from the `(src, label, dst)` triple. Insert/put carries the edge properties in `new_value`; delete carries no payload.
77
+
-**Node labels** — published tenant-wide on the dedicated stream `__graph_node_labels__`. `SET` labels → `Insert` with the added labels in `new_value` (`{ "labels": [...] }`); `REMOVE` → `Delete` with the removed labels in `old_value`. `row_id` is the node id.
78
+
79
+
Implicit edges (a document insert carrying `_from`/`_to`) are not double-published — the underlying document write already emits its event. WAL replay reconstructs graph events byte-identically and dedups on LSN.
80
+
74
81
**UPSERT and `ON CONFLICT` firing semantics.** The `WriteOp` tag emitted to the Event Plane is derived from storage prior-bytes, not from the surface SQL verb. An `UPSERT` or `INSERT ... ON CONFLICT (pk) DO UPDATE` that finds an existing row fires `AFTER UPDATE`; the same statement against a non-existent key fires `AFTER INSERT`. `ON CONFLICT DO NOTHING` on a conflict emits no event at all.
Copy file name to clipboardExpand all lines: docs/vectors.md
+18Lines changed: 18 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -78,6 +78,24 @@ LIMIT 10;
78
78
79
79
Set `target_recall` and let the planner do the rest unless you need a hard latency ceiling.
80
80
81
+
## Sparse Vectors
82
+
83
+
For learned sparse representations (SPLADE, uniCOIL, BM25-style term weights), declare a dimensionless `SPARSEVECTOR` column. An inverted index over the non-zero dimensions is maintained automatically on every document write.
84
+
85
+
```sql
86
+
CREATETABLEsparse_docs (id TEXTPRIMARY KEY, terms SPARSEVECTOR);
87
+
88
+
-- Values are '{dimension: weight}' string literals
ORDER BY sparse_score(terms, '{3: 1.0, 7: 0.5}') DESC
94
+
LIMIT3;
95
+
```
96
+
97
+
`SPARSEVECTOR` carries no fixed dimensionality — only non-zero `(dimension, weight)` pairs are stored and indexed. Documents sharing no dimension with the query are excluded by the inverted index rather than scored at zero. `sparse_score` ranks by descending dot product; it is a standalone surface, separate from the dense `vector_distance` path and the RRF hybrid fusion.
98
+
81
99
## Vector-Primary Collections
82
100
83
101
By default, vectors are an _index_ attached to a column on a normal collection — the document store is the source of truth. For pure-vector workloads (RAG corpora, recommendation memory, embedding stores) flip a collection into vector-primary mode where the vector index is the primary access path and the document store is a metadata sidecar:
0 commit comments