Skip to main content

kimberlite_query/
error.rs

1//! Error types for query operations.
2
3use kimberlite_store::StoreError;
4
5/// Errors that can occur during query parsing and execution.
6#[derive(thiserror::Error, Debug)]
7pub enum QueryError {
8    /// SQL syntax or parsing error.
9    #[error("parse error: {0}")]
10    ParseError(String),
11
12    /// Table not found in schema.
13    #[error("table '{0}' not found")]
14    TableNotFound(String),
15
16    /// Column not found in table.
17    #[error("column '{column}' not found in table '{table}'")]
18    ColumnNotFound { table: String, column: String },
19
20    /// Query parameter not provided.
21    #[error("parameter ${0} not provided")]
22    ParameterNotFound(usize),
23
24    /// Type mismatch between expected and actual value.
25    #[error("type mismatch: expected {expected}, got {actual}")]
26    TypeMismatch { expected: String, actual: String },
27
28    /// SQL feature not supported.
29    #[error("unsupported feature: {0}")]
30    UnsupportedFeature(String),
31
32    /// SQL input exceeds a complexity limit (depth or token budget).
33    /// Pre-parse guard that rejects pathological inputs which would
34    /// trigger super-linear behavior in the upstream SQL parser.
35    #[error("sql too complex: {kind} = {value} exceeds limit {limit}")]
36    SqlTooComplex {
37        /// Which budget was exceeded (e.g., `paren_depth`, `not_tokens`).
38        kind: &'static str,
39        /// Observed value.
40        value: usize,
41        /// Configured limit.
42        limit: usize,
43    },
44
45    /// Constraint violation (e.g., duplicate primary key, NOT NULL violation).
46    #[error("constraint violation: {0}")]
47    ConstraintViolation(String),
48
49    /// Correlated subquery row-evaluation cap exceeded.
50    ///
51    /// Emitted before the correlated-loop executor runs when the estimated
52    /// product of outer rows × inner rows per iteration exceeds the
53    /// configured cap (default `10_000_000`; see
54    /// `QueryEngine::with_correlated_cap`). Fails fast rather than
55    /// consuming memory. See `docs/reference/sql/correlated-subqueries.md`.
56    #[error(
57        "correlated subquery cardinality exceeded: estimated {estimated} row \
58         evaluations exceeds cap of {cap}"
59    )]
60    CorrelatedCardinalityExceeded { estimated: u64, cap: u64 },
61
62    /// Requested `AS OF TIMESTAMP` precedes the earliest retained event.
63    ///
64    /// Emitted when a `FOR SYSTEM_TIME AS OF '<iso>'` / `AS OF TIMESTAMP`
65    /// query asks for a wall-clock instant older than the oldest entry
66    /// in the timestamp-to-offset index (typically a freshly-opened
67    /// database, or a timestamp predating any write). Distinguished
68    /// from a general "no offset found" error so callers can surface
69    /// the retention horizon to the user.
70    ///
71    /// `requested_ns` is the caller-supplied Unix-nanosecond timestamp;
72    /// `horizon_ns` is the earliest wall-clock instant the index can
73    /// answer for (or `0` when the log is empty).
74    ///
75    /// Shipped with v0.6.0 Tier 2 #6 (AS OF TIMESTAMP time-travel).
76    #[error(
77        "AS OF TIMESTAMP {requested_ns} ns precedes the earliest retained \
78         event (retention horizon: {horizon_ns} ns)"
79    )]
80    AsOfBeforeRetentionHorizon { requested_ns: i64, horizon_ns: i64 },
81
82    /// Underlying store error.
83    #[error("store error: {0}")]
84    Store(#[from] StoreError),
85
86    /// JSON serialization/deserialization error.
87    #[error("json error: {0}")]
88    Json(#[from] serde_json::Error),
89}
90
91/// Result type for query operations.
92pub type Result<T> = std::result::Result<T, QueryError>;