alopex_sql/executor/
error.rs1use crate::executor::evaluator::VectorError;
9use crate::storage::StorageError;
10use thiserror::Error;
11
12#[derive(Debug, Error)]
14pub enum ExecutorError {
15 #[error("hnsw error: {0}")]
17 Core(#[from] alopex_core::Error),
18
19 #[error("table not found: {0}")]
21 TableNotFound(String),
22
23 #[error("table already exists: {0}")]
25 TableAlreadyExists(String),
26
27 #[error("index not found: {0}")]
29 IndexNotFound(String),
30
31 #[error("index already exists: {0}")]
33 IndexAlreadyExists(String),
34
35 #[error("column not found: {0}")]
37 ColumnNotFound(String),
38
39 #[error("constraint violation: {0}")]
41 ConstraintViolation(#[from] ConstraintViolation),
42
43 #[error("evaluation error: {0}")]
45 Evaluation(#[from] EvaluationError),
46
47 #[error("unsupported operation: {0}")]
49 UnsupportedOperation(String),
50
51 #[error("transaction conflict")]
53 TransactionConflict,
54
55 #[error("read-only transaction: cannot execute {operation}")]
57 ReadOnlyTransaction { operation: String },
58
59 #[error("storage error: {0}")]
61 Storage(#[from] StorageError),
62
63 #[error("column required: {column} (DEFAULT not supported in v0.1.2)")]
65 ColumnRequired { column: String },
66
67 #[error("invalid index name: {name} - {reason}")]
69 InvalidIndexName { name: String, reason: String },
70
71 #[error("invalid operation: {operation} - {reason}")]
73 InvalidOperation { operation: String, reason: String },
74
75 #[error("file not found: {0}")]
77 FileNotFound(String),
78
79 #[error("path validation failed for '{path}': {reason}")]
81 PathValidationFailed { path: String, reason: String },
82
83 #[error("unsupported format: {0}")]
85 UnsupportedFormat(String),
86
87 #[error("schema mismatch: expected {expected} columns, got {actual} - {reason}")]
89 SchemaMismatch {
90 expected: usize,
91 actual: usize,
92 reason: String,
93 },
94
95 #[error("invalid storage type: {0}")]
97 InvalidStorageType(String),
98
99 #[error("invalid compression: {0}")]
101 InvalidCompression(String),
102
103 #[error("invalid row_group_size: {0}")]
105 InvalidRowGroupSize(String),
106
107 #[error("invalid rowid_mode: {0}")]
109 InvalidRowIdMode(String),
110
111 #[error("unknown table option: {0}")]
113 UnknownTableOption(String),
114
115 #[error("duplicate option: {0}")]
117 DuplicateOption(String),
118
119 #[error("vector error: {0}")]
121 Vector(#[from] VectorError),
122
123 #[error("bulk load error: {0}")]
125 BulkLoad(String),
126
127 #[error("columnar engine error: {0}")]
129 Columnar(String),
130
131 #[error("planner error: {0}")]
133 Planner(#[from] crate::planner::PlannerError),
134}
135
136#[derive(Debug, Error, Clone, PartialEq, Eq)]
138pub enum ConstraintViolation {
139 #[error("NOT NULL constraint violated on column: {column}")]
141 NotNull { column: String },
142
143 #[error("PRIMARY KEY constraint violated on columns: {columns:?}, value: {value:?}")]
145 PrimaryKey {
146 columns: Vec<String>,
147 value: Option<String>,
148 },
149
150 #[error(
152 "UNIQUE constraint violated on index: {index_name}, columns: {columns:?}, value: {value:?}"
153 )]
154 Unique {
155 index_name: String,
156 columns: Vec<String>,
157 value: Option<String>,
158 },
159}
160
161#[derive(Debug, Error, Clone, PartialEq, Eq)]
163pub enum EvaluationError {
164 #[error("division by zero")]
166 DivisionByZero,
167
168 #[error("integer overflow")]
170 Overflow,
171
172 #[error("type mismatch: expected {expected}, got {actual}")]
174 TypeMismatch { expected: String, actual: String },
175
176 #[error("invalid column reference: index {index}")]
178 InvalidColumnRef { index: usize },
179
180 #[error("unsupported expression: {0}")]
182 UnsupportedExpression(String),
183
184 #[error("unsupported function: {0}")]
186 UnsupportedFunction(String),
187
188 #[error("vector error: {0}")]
190 Vector(#[from] VectorError),
191}
192
193pub type Result<T> = std::result::Result<T, ExecutorError>;
195
196#[cfg(test)]
197mod tests {
198 use super::*;
199
200 #[test]
201 fn test_executor_error_display() {
202 let err = ExecutorError::TableNotFound("users".into());
203 assert_eq!(err.to_string(), "table not found: users");
204 }
205
206 #[test]
207 fn test_constraint_violation_display() {
208 let err = ConstraintViolation::NotNull {
209 column: "name".into(),
210 };
211 assert_eq!(
212 err.to_string(),
213 "NOT NULL constraint violated on column: name"
214 );
215 }
216
217 #[test]
218 fn test_evaluation_error_display() {
219 let err = EvaluationError::DivisionByZero;
220 assert_eq!(err.to_string(), "division by zero");
221 }
222
223 #[test]
224 fn test_constraint_violation_from() {
225 let violation = ConstraintViolation::NotNull {
226 column: "age".into(),
227 };
228 let err: ExecutorError = violation.into();
229 assert!(matches!(err, ExecutorError::ConstraintViolation(_)));
230 }
231
232 #[test]
233 fn test_evaluation_error_from() {
234 let eval_err = EvaluationError::Overflow;
235 let err: ExecutorError = eval_err.into();
236 assert!(matches!(err, ExecutorError::Evaluation(_)));
237 }
238
239 #[test]
240 fn test_vector_error_conversion() {
241 let vector_err = VectorError::ZeroNormVector;
242 let eval_err: EvaluationError = vector_err.clone().into();
243 assert!(matches!(eval_err, EvaluationError::Vector(_)));
244
245 let exec_err: ExecutorError = vector_err.into();
246 assert!(matches!(exec_err, ExecutorError::Vector(_)));
247 }
248
249 #[test]
250 fn test_path_validation_failed_display() {
251 let err = ExecutorError::PathValidationFailed {
252 path: "/tmp/data.parquet".into(),
253 reason: "symbolic links not allowed".into(),
254 };
255 assert_eq!(
256 err.to_string(),
257 "path validation failed for '/tmp/data.parquet': symbolic links not allowed"
258 );
259 }
260}