nodedb_sql/types/collection.rs
1// SPDX-License-Identifier: Apache-2.0
2
3//! Collection and column metadata types for query planning.
4
5use super::query::EngineType;
6use crate::types_expr::SqlDataType;
7
8/// Metadata about a collection for query planning.
9#[derive(Debug, Clone)]
10pub struct CollectionInfo {
11 pub name: String,
12 pub engine: EngineType,
13 pub columns: Vec<ColumnInfo>,
14 pub primary_key: Option<String>,
15 pub has_auto_tier: bool,
16 /// Secondary indexes available for planner rewrites. Populated by the
17 /// catalog adapter from `StoredCollection.indexes`. `Building` entries
18 /// are included so the planner can see them but MUST be skipped when
19 /// choosing an index lookup — only `Ready` indexes back query rewrites.
20 pub indexes: Vec<IndexSpec>,
21 /// When `true`, this collection stores every write as an immutable
22 /// version keyed by `system_from_ms`. Enables `FOR SYSTEM_TIME AS OF`
23 /// and `FOR VALID_TIME` queries. Only meaningful for document engines
24 /// today; other engines ignore this flag.
25 pub bitemporal: bool,
26 /// Primary engine hint from the catalog.
27 pub primary: nodedb_types::PrimaryEngine,
28 /// Vector-primary configuration. `Some` only when
29 /// `primary == PrimaryEngine::Vector`.
30 pub vector_primary: Option<nodedb_types::VectorPrimaryConfig>,
31}
32
33/// Secondary index metadata surfaced to the SQL planner.
34#[derive(Debug, Clone)]
35pub struct IndexSpec {
36 pub name: String,
37 /// Canonical field path (`$.email`, `$.user.name`, or plain column name
38 /// for strict documents — the catalog layer stores them uniformly).
39 pub field: String,
40 pub unique: bool,
41 pub case_insensitive: bool,
42 /// Build state. Only `Ready` indexes drive query rewrites.
43 pub state: IndexState,
44 /// Partial-index predicate as raw SQL text (`WHERE <expr>` body
45 /// without the keyword), or `None` for full indexes. The planner
46 /// uses this to reject rewrites whose WHERE clause doesn't entail
47 /// the predicate — matching against such a partial index would
48 /// omit rows the index didn't cover.
49 pub predicate: Option<String>,
50}
51
52/// Planner-facing index state. Mirrors the catalog variant but lives here
53/// so the SQL crate doesn't depend on `nodedb` internals.
54#[derive(Debug, Clone, Copy, PartialEq, Eq)]
55pub enum IndexState {
56 Building,
57 Ready,
58}
59
60/// Metadata about a single column.
61#[derive(Debug, Clone)]
62pub struct ColumnInfo {
63 pub name: String,
64 pub data_type: SqlDataType,
65 pub nullable: bool,
66 pub is_primary_key: bool,
67 /// Default value expression (e.g. "UUID_V7", "ULID", "NANOID(10)", "0", "'active'").
68 pub default: Option<String>,
69}