1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
// SPDX-License-Identifier: BUSL-1.1
//! redb `TableDefinition` constants for every system-catalog table.
//!
//! Constants are `pub(super)` so sibling catalog modules can use them
//! directly; `types.rs` re-exports the set for code that imports via
//! `super::types::*`.
use TableDefinition;
// ── Auth / tenancy ────────────────────────────────────────────────────
/// Table: username (string) -> MessagePack-serialized user record.
pub const USERS: = new;
/// Table: key_id (string) -> MessagePack-serialized API key record.
pub const API_KEYS: = new;
/// Table: tenant_id (string) -> MessagePack-serialized tenant record.
pub const TENANTS: = new;
/// Table: seq (u64 as big-endian bytes) -> MessagePack-serialized audit entry.
pub const AUDIT_LOG: =
new;
/// Table: role_name -> MessagePack-serialized custom role record.
pub const ROLES: = new;
/// Table: "target:role_or_user" -> MessagePack-serialized permission grant.
pub const PERMISSIONS: =
new;
/// Table: "{object_type}:{tenant_id}:{object_name}" -> owner username.
pub const OWNERS: = new;
// ── Collections ───────────────────────────────────────────────────────
/// Table (legacy, pre-database-boundary): `"{tenant_id}:{name}"` -> msgpack
/// collection metadata. Used only by the idempotent migration path that reads
/// legacy rows and rewrites them under `COLLECTIONS` with the database_id key.
pub const COLLECTIONS_LEGACY: =
new;
/// Table: `(database_id: u64, "{tenant_id}:{name}")` -> MessagePack collection metadata.
///
/// The compound key prepends `database_id` (as raw `u64`) so every collection
/// is namespaced within its database. The inner key preserves the legacy
/// `"{tenant_id}:{name}"` encoding for catalog-resolver compatibility.
pub const COLLECTIONS: =
new;
/// Table: `(tenant_id, collection_name)` -> `purge_lsn` (u64 LE).
///
/// Holds the canonical collection-tombstone set used by WAL replay to
/// shadow writes that precede a hard-delete. Persisted here (rather
/// than only on the WAL) so startup replay is O(1) instead of requiring
/// a full segment scan to rebuild the set. Entries are GC'd by
/// `delete_wal_tombstones_before_lsn` when all segments referencing
/// them have been truncated past retention.
pub const WAL_TOMBSTONES: =
new;
/// Table: `(tenant_id, collection_name)` -> MessagePack-serialized
/// `StoredL2CleanupEntry`.
///
/// Populated when a collection hard-delete finishes on this node but
/// L2 (S3) object delete has not completed yet. Drained by the L2
/// cleanup worker as `DELETE` calls succeed. Surfaced via the
/// `_system.l2_cleanup_queue` virtual view so operators can see the
/// object-store delete backlog even after the `StoredCollection` row
/// has been purged.
pub const L2_CLEANUP_QUEUE: =
new;
// ── DDL objects ───────────────────────────────────────────────────────
/// Table: "{tenant_id}:{name}" -> MessagePack-serialized materialized view metadata.
pub const MATERIALIZED_VIEWS: =
new;
/// Table: "{tenant_id}:{name}" -> MessagePack-serialized continuous aggregate metadata.
pub const CONTINUOUS_AGGREGATES: =
new;
/// Table: "{tenant_id}:{name}" -> MessagePack-serialized user function definition.
pub const FUNCTIONS: =
new;
/// Table: "{tenant_id}:{name}" -> MessagePack-serialized trigger definition.
pub const TRIGGERS: = new;
/// Table: "{tenant_id}:{name}" -> MessagePack-serialized `ArrayCatalogEntry`.
/// One row per ND array registered via DDL.
pub const ARRAYS: = new;
// ── Surrogate PK map ──────────────────────────────────────────────────
/// Table (legacy): `(collection, encoded_pk_bytes)` -> `Surrogate` (u32 LE).
/// Used only by the idempotent migration that prefixes rows with database_id.
pub const SURROGATE_PK_LEGACY: =
new;
/// Table: `(database_id: u64, collection, encoded_pk_bytes)` -> `Surrogate` (u32 LE).
///
/// Forward direction of the PK ↔ Surrogate map with database scoping prepended.
/// Every successful `assign_surrogate(database_id, collection, pk)` writes both
/// the forward and reverse rows atomically in one redb txn.
pub const SURROGATE_PK: =
new;
/// Table (legacy): `(collection, surrogate)` -> encoded pk bytes.
/// Used only by the idempotent migration that prefixes rows with database_id.
pub const SURROGATE_PK_REV_LEGACY: =
new;
/// Table: `(database_id: u64, collection, surrogate)` -> encoded pk bytes.
///
/// Reverse direction of `_system.surrogate_pk_v2`. Scoped per database_id.
pub const SURROGATE_PK_REV: =
new;
// ── Event Plane ───────────────────────────────────────────────────────
/// Table: "{tenant_id}:{stream_name}" -> MessagePack-serialized ChangeStreamDef.
pub const CHANGE_STREAMS: =
new;
/// Table: "{tenant_id}:{stream_name}:{group_name}" -> MessagePack-serialized ConsumerGroupDef.
pub const CONSUMER_GROUPS: =
new;
/// Table: "{tenant_id}:{schedule_name}" -> MessagePack-serialized ScheduleDef.
pub const SCHEDULES: =
new;
/// Table: "{tenant_id}:{policy_name}" -> MessagePack-serialized RetentionPolicyDef.
pub const RETENTION_POLICIES: =
new;
/// Table: "{tenant_id}:{alert_name}" -> MessagePack-serialized AlertDef.
pub const ALERT_RULES: =
new;
/// Table: "{tenant_id}:{topic_name}" -> MessagePack-serialized TopicDef.
pub const TOPICS_EP: =
new;
/// Table: "{tenant_id}:{mv_name}" -> MessagePack-serialized StreamingMvDef.
pub const STREAMING_MVS: =
new;
// ── Procedures, deps, sequences, stats ────────────────────────────────
/// Table: "{tenant_id}:{name}" -> MessagePack-serialized stored procedure definition.
pub const PROCEDURES: =
new;
/// Table: "{source_type}:{tenant_id}:{source_name}" -> MessagePack-serialized dependency list.
pub const DEPENDENCIES: =
new;
/// Table: "{tenant_id}:{name}" -> MessagePack-serialized sequence definition.
pub const SEQUENCES: =
new;
/// Table: "{tenant_id}:{name}" -> MessagePack-serialized sequence runtime state.
pub const SEQUENCE_STATE: =
new;
/// Table: "{tenant_id}:{collection}:{column}" -> MessagePack-serialized column statistics.
pub const COLUMN_STATS: =
new;
/// Table: metadata key -> value bytes (counters, config).
pub const METADATA: = new;
// ── Database catalog ──────────────────────────────────────────────────
/// Table: `database_id (u64)` -> MessagePack-serialized `DatabaseDescriptor`.
/// One row per database; `DatabaseId(0)` = "default" always exists.
pub const DATABASES: = new;
/// Table: `name (string)` -> `database_id (u64)`.
/// Unique reverse lookup: name → DatabaseId. Updated atomically with
/// `DATABASES` on CREATE/RENAME/DROP.
pub const DATABASES_BY_NAME: =
new;
/// Table: singleton `"global"` -> highest allocated database id (`u64`).
/// Persisted by `DatabaseRegistry::flush`; seeded at startup.
pub const DATABASE_HWM: =
new;
// ── Synonyms / custom types / WASM ────────────────────────────────────
/// Table: "{tenant_id}:{group_name}" -> MessagePack-serialized `SynonymGroupDef`.
pub const SYNONYM_GROUPS: =
new;
/// Table: "{tenant_id}:{type_name}" -> MessagePack-serialized `StoredCustomType`.
pub const CUSTOM_TYPES: =
new;
/// Table: "wasm_module:{sha256_hex}" -> raw WASM binary bytes.
pub const WASM_MODULES: =
new;
// ── Auth state (lockout, blacklist, JIT users, orgs, scopes) ──────────
/// Table: username -> MessagePack-serialized `StoredLockoutRecord`.
///
/// Persistent mirror of the in-memory `LoginAttemptTracker`. Written on every
/// failure and success; rebuilt into cache on `CredentialStore::open`.
pub const LOCKOUT_STATE: =
new;
/// Table: blacklist key (user_id or IP) -> MessagePack-serialized blacklist entry.
pub const BLACKLIST: =
new;
/// Table: auth_user_id -> MessagePack-serialized auth user record (JIT-provisioned).
pub const AUTH_USERS: =
new;
/// Table: org_id -> MessagePack-serialized org record.
pub const ORGS: = new;
// ── OIDC providers ───────────────────────────────────────────────────
/// Table: provider_name (string) -> MessagePack-serialized `StoredOidcProvider`.
pub const OIDC_PROVIDERS: =
new;
/// Table: "{org_id}:{user_id}" -> MessagePack-serialized org membership.
pub const ORG_MEMBERS: =
new;
/// Table: scope_name -> MessagePack-serialized scope definition.
pub const SCOPES: = new;
/// Table: `"{database_id}:{user_id}:{privilege}"` -> empty value.
///
/// Stores explicit per-database grants created by `GRANT … ON DATABASE …`.
/// The key encodes all three dimensions so range scans by `database_id`
/// or `user_id` prefix work without secondary tables.
pub const DATABASE_GRANTS: =
new;
/// Table: "{scope_name}:{grantee_type}:{grantee_id}" -> MessagePack-serialized scope grant.
pub const SCOPE_GRANTS: =
new;
// ── Database and tenant quotas ────────────────────────────────────────
/// Table: `database_id (u64)` -> MessagePack-serialized `QuotaRecord`.
///
/// Stores the explicit resource budget for each database. Absence means the
/// database has no configured ceiling; enforcement falls back to global limits.
pub const DATABASE_QUOTAS: =
new;
/// Table: `(database_id: u64, tenant_id: u64)` -> MessagePack-serialized `QuotaRecord`.
///
/// Stores the resource budget for a specific tenant within a specific database.
/// The sum of all tenant quotas within a database must not exceed that database's
/// quota; this invariant is checked at write time.
pub const TENANT_QUOTAS: =
new;
// ── Clone CoW tables ─────────────────────────────────────────────────
/// Table: `(target_collection_key: &str, source_surrogate: u32)` → `target_surrogate: u32`.
///
/// Records copy-up events: when a row that originally existed only in the source
/// is written to in the target clone (UPDATE or DELETE on a source-only row),
/// the source surrogate is mapped to the fresh target surrogate allocated at
/// copy-up time. The `target_collection_key` is the
/// `"{database_id}:{tenant_id}:{collection_name}"` compound form.
pub const CLONE_COPYUPS: =
new;
/// Table: `(target_collection_key: &str, source_surrogate: u32)` → `()`.
///
/// Records tombstone events: when a row that existed only in the source is
/// deleted from the clone, the source surrogate is recorded here. The read
/// planner checks this table before falling back to source storage so that
/// deleted rows are invisible even though they still exist in the source.
pub const CLONE_TOMBSTONES: =
new;
/// Table: `(target_collection_key: &str, kv_key: &str)` → `()`.
///
/// Records KV-engine tombstone events: when a KV row that exists only in the
/// source is deleted from the clone, the raw KV key string is recorded here.
/// The read path filters source KV scan results against this set so that
/// deleted rows remain invisible from clone queries.
pub const CLONE_KV_TOMBSTONES: =
new;
/// Table: `source_database_id (u64)` → MessagePack-serialized `Vec<u64>` (child DatabaseIds).
///
/// Tracks the lineage tree: for each database that is the source of one or more
/// clones, this table stores the list of child database ids. Used at DROP
/// DATABASE time to detect orphan dependency violations and by the depth-check
/// at CLONE DATABASE time (walk upward through parent_clone links counting
/// hops).
pub const CLONE_LINEAGE: =
new;
// ── Mirror catalog ────────────────────────────────────────────────────
/// Table: `(mirror_database_id: u64, source_collection_name: &str)` →
/// `local_collection_name: &str` (MessagePack bytes).
///
/// Maps source-side collection names to this mirror's local collection names.
/// In typical deployments the names match; the map exists so a future
/// `RENAME COLLECTION ON MIRROR` can decouple them without breaking replication.
/// Updated atomically when a DDL entry from the source is applied.
pub const MIRROR_COLLECTION_MAP: =
new;
/// Table: `database_id (u64)` → MessagePack-serialized `MirrorLagRecord`.
///
/// Stores the last-applied LSN and apply-timestamp for each mirror database.
/// Read by the metrics collector to produce the `mirror_lag_ms` gauge and by
/// the `SHOW DATABASE MIRROR STATUS` handler.
pub const MIRROR_LAG: =
new;
// ── Vector model + checkpoints ────────────────────────────────────────
/// Table: "{tenant_id}:{collection}:{column}" -> MessagePack-serialized VectorModelEntry.
pub const VECTOR_MODEL_METADATA: =
new;
/// Table: "{tenant_id}:{collection}:{doc_id}:{checkpoint_name}" -> MessagePack CheckpointRecord.
pub const CHECKPOINTS: =
new;