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
**Control Plane** — Runs on Tokio. Handles connections (pgwire, HTTP, WebSocket), parses SQL via DataFusion, builds logical query plans, and dispatches work to the Data Plane. All types here are `Send + Sync`.
25
+
**Control Plane** — Runs on Tokio. Handles connections (pgwire, HTTP, WebSocket), parses SQL via nodedb-sql (sqlparser-rs based), builds logical query plans, and dispatches work to the Data Plane. All types here are `Send + Sync`.
26
26
27
27
**Data Plane** — One thread per CPU core, each an isolated shard. Reads from NVMe via io_uring, runs SIMD vector math, executes physical query plans. No locks, no atomics, no cross-core sharing. Types are `!Send` by design. Emits `WriteEvent` records (covering inserts, updates, and deletes via `WriteOp`) to the Event Plane via per-core bounded ring buffers after each WAL commit.
28
28
@@ -44,13 +44,13 @@ NodeDB splits work across three planes connected by lock-free ring buffers. This
44
44
45
45
There are two ways a query reaches the Data Plane. Both produce the same `PhysicalPlan` and execute identically from that point on.
46
46
47
-
**SQL path (user-facing)** — All user-visible interfaces use SQL. `psql`, the `ndb` CLI, and the HTTP `/v1/query` endpoint all accept SQL text. The Control Plane runs it through DataFusion (parse → logical plan → optimize → `PhysicalPlan`):
47
+
**SQL path (user-facing)** — All user-visible interfaces use SQL. `psql`, the `ndb` CLI, and the HTTP `/v1/query` endpoint all accept SQL text. The Control Plane runs it through nodedb-sql (parse → logical plan → optimize → `PhysicalPlan`):
48
48
49
49
```
50
50
psql / ndb CLI / HTTP /v1/query
51
51
│
52
52
▼
53
-
DataFusion parser
53
+
nodedb-sql parser
54
54
│
55
55
▼
56
56
Logical plan + optimizer
@@ -59,7 +59,7 @@ psql / ndb CLI / HTTP /v1/query
59
59
PhysicalPlan ──► SPSC Bridge ──► Data Plane
60
60
```
61
61
62
-
**Native opcode path (SDK optimization)** — The Rust SDK (`nodedb-client`), FFI bindings (`nodedb-lite-ffi`), and WASM bindings (`nodedb-lite-wasm`) dispatch typed opcode messages over the NDB protocol instead of SQL text. The Control Plane converts them directly to a `PhysicalPlan` via `build_plan()`, skipping SQL parsing and serialization:
62
+
**Native opcode path (SDK optimization)** — The Rust SDK (`nodedb-client`), FFI bindings (`nodedb-lite-ffi`), and WASM bindings (`nodedb-lite-wasm`) dispatch typed opcode messages over the NDB protocol instead of SQL text. The Control Plane converts them directly to a `PhysicalPlan` via engine-specific handlers, skipping SQL parsing and serialization:
-- Query what we knew at April 1st (before correction)
97
100
SELECT location, temperature FROM sensor_readings
98
101
WHERE ts BETWEEN '2026-04-01'AND'2026-04-02'
99
-
AS OF VALID TIME1711953600000; -- April 1st
102
+
AS OF VALID TIME'2026-04-01T00:00:00Z';
100
103
101
104
-- Query what we know now (after correction)
102
105
SELECT location, temperature FROM sensor_readings
@@ -127,7 +130,7 @@ SELECT lon, lat, temp_c FROM ARRAY_SLICE(
127
130
{lon: [-10, 10), lat: [0, 20)},
128
131
['temp_c']
129
132
)
130
-
AS OF SYSTEM TIME(extract(epoch from now()) *1000-86400000);
133
+
AS OF SYSTEM TIME'2026-06-06T00:00:00Z';
131
134
```
132
135
133
136
### Lineage and Compliance
@@ -153,12 +156,14 @@ UPDATE transactions SET status = 'CONFIRMED' WHERE id = 'txn-1';
153
156
UPDATE transactions SET status ='SETTLED'WHERE id ='txn-1';
154
157
155
158
-- Audit: show full timeline of this transaction
156
-
SELECT status, system_timeFROM transactions
159
+
SELECT status, _ts_systemFROM transactions
157
160
WHERE id ='txn-1'
158
-
AS OF SYSTEM TIMENULL--special: returns all versions in systemtime order
159
-
ORDER BYsystem_timeASC;
161
+
AS OF SYSTEM TIMENULL-- returns every system-time version, ascending
162
+
ORDER BY_ts_systemASC;
160
163
```
161
164
165
+
`AS OF SYSTEM TIME NULL` returns every system-time version of each matching row, ordered ascending, with the `_ts_system` column projected into the result. 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
+
162
167
## Index Engines and Temporal Composition
163
168
164
169
Vector, FTS, KV, and Spatial do not carry temporal columns. This is not an oversight — it is the correct architectural decomposition. These four are **index engines**: they point at records that live in data-bearing engines. Indexes don't have time; the records they point to do.
@@ -185,7 +190,7 @@ CREATE VECTOR INDEX idx_product_vec ON product_embeddings METRIC cosine DIM 384;
185
190
SELECTp.product_id, p.description,
186
191
vector_distance(p.embedding, $query_vec) AS score
187
192
FROM product_embeddings p
188
-
AS OF SYSTEM TIME(extract(epoch from now()) *1000-2592000000)
193
+
AS OF SYSTEM TIME'2026-05-08T00:00:00Z'
189
194
WHEREp.idIN (
190
195
SEARCH product_embeddings USING VECTOR(embedding, $query_vec, 20)
191
196
)
@@ -212,7 +217,7 @@ CREATE SEARCH INDEX ON articles FIELDS title, body ANALYZER 'english';
212
217
-- 3. Bitemporal FTS: search the index state as it existed yesterday
213
218
SELECT id, title
214
219
FROM articles
215
-
AS OF SYSTEM TIME(extract(epoch from now()) *1000-86400000)
220
+
AS OF SYSTEM TIME'2026-06-06T00:00:00Z'
216
221
WHERE text_match(body, 'distributed consensus raft')
217
222
ORDER BY bm25_score(body, 'distributed consensus raft') DESC
218
223
LIMIT20;
@@ -275,7 +280,7 @@ SELECT value FROM config_entries WHERE key = 'feature_x_enabled';
275
280
276
281
-- Audit: what was the value 7 days ago?
277
282
SELECT value FROM config_entries
278
-
AS OF SYSTEM TIME(extract(epoch from now()) *1000-604800000)
0 commit comments