nodedb_sql/catalog.rs
1//! `SqlCatalog` trait + descriptor-resolution error type.
2//!
3//! The SQL planner resolves collection metadata through the
4//! `SqlCatalog` trait. Both Origin (via the host-side
5//! `CredentialStore` + `SystemCatalog`) and Lite (via the embedded
6//! redb catalog) implement it. The trait lives in its own file so
7//! `types.rs` stays under the 500-line limit and so the error
8//! surface has headroom for additional variants.
9
10use thiserror::Error;
11
12use crate::types::CollectionInfo;
13
14/// Errors surfaced by `SqlCatalog` implementations.
15///
16/// Only one variant today — callers pattern-match directly and
17/// map the retryable case to `SqlError::RetryableSchemaChanged`
18/// via the `From` impl in `error.rs`. The enum shape is kept
19/// despite having a single variant so future variants can be
20/// added without a breaking change.
21#[derive(Debug, Clone, Error)]
22pub enum SqlCatalogError {
23 /// A DDL drain is in progress on the descriptor at the
24 /// version the planner wanted to acquire a lease on. Callers
25 /// should retry the whole plan after a short backoff — by
26 /// then either the drain has completed (new descriptor
27 /// version available in the cache) or the retry budget is
28 /// exhausted and a typed error surfaces to the client.
29 #[error("retryable schema change on {descriptor}")]
30 RetryableSchemaChanged {
31 /// Human-readable identifier for the descriptor, e.g.
32 /// `"collection orders"`. Used in log / trace output.
33 descriptor: String,
34 },
35}
36
37/// Trait for looking up collection metadata during planning.
38///
39/// Both Origin (via CredentialStore) and Lite (via the embedded
40/// redb catalog) implement this trait.
41///
42/// The return type is `Result<Option<CollectionInfo>, _>` with
43/// a three-way semantics:
44///
45/// - `Ok(Some(info))` — the collection exists and is usable.
46/// An Origin implementation will have acquired a descriptor
47/// lease at the current version before returning; subsequent
48/// planning against the same collection within the lease
49/// window is drain-safe.
50/// - `Ok(None)` — the collection does not exist. Callers should
51/// surface this as `SqlError::UnknownTable`.
52/// - `Err(SqlCatalogError::RetryableSchemaChanged { .. })` —
53/// the collection exists but a DDL drain is in progress.
54/// Callers propagate this up so the pgwire layer can retry
55/// the whole statement.
56pub trait SqlCatalog {
57 fn get_collection(&self, name: &str) -> Result<Option<CollectionInfo>, SqlCatalogError>;
58}