1use 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("resource exhausted: {message}")]
77 ResourceExhausted { message: String },
78
79 #[error("file not found: {0}")]
81 FileNotFound(String),
82
83 #[error("path validation failed for '{path}': {reason}")]
85 PathValidationFailed { path: String, reason: String },
86
87 #[error("unsupported format: {0}")]
89 UnsupportedFormat(String),
90
91 #[error("schema mismatch: expected {expected} columns, got {actual} - {reason}")]
93 SchemaMismatch {
94 expected: usize,
95 actual: usize,
96 reason: String,
97 },
98
99 #[error("invalid storage type: {0}")]
101 InvalidStorageType(String),
102
103 #[error("invalid compression: {0}")]
105 InvalidCompression(String),
106
107 #[error("invalid row_group_size: {0}")]
109 InvalidRowGroupSize(String),
110
111 #[error("invalid rowid_mode: {0}")]
113 InvalidRowIdMode(String),
114
115 #[error("unknown table option: {0}")]
117 UnknownTableOption(String),
118
119 #[error("duplicate option: {0}")]
121 DuplicateOption(String),
122
123 #[error("vector error: {0}")]
125 Vector(#[from] VectorError),
126
127 #[error("bulk load error: {0}")]
129 BulkLoad(String),
130
131 #[error("columnar engine error: {0}")]
133 Columnar(String),
134
135 #[error("planner error: {0}")]
137 Planner(#[from] crate::planner::PlannerError),
138}
139
140#[derive(Debug, Error, Clone, PartialEq, Eq)]
142pub enum ConstraintViolation {
143 #[error("NOT NULL constraint violated on column: {column}")]
145 NotNull { column: String },
146
147 #[error("PRIMARY KEY constraint violated on columns: {columns:?}, value: {value:?}")]
149 PrimaryKey {
150 columns: Vec<String>,
151 value: Option<String>,
152 },
153
154 #[error(
156 "UNIQUE constraint violated on index: {index_name}, columns: {columns:?}, value: {value:?}"
157 )]
158 Unique {
159 index_name: String,
160 columns: Vec<String>,
161 value: Option<String>,
162 },
163}
164
165#[derive(Debug, Error, Clone, PartialEq, Eq)]
167pub enum EvaluationError {
168 #[error("division by zero")]
170 DivisionByZero,
171
172 #[error("integer overflow")]
174 Overflow,
175
176 #[error("type mismatch: expected {expected}, got {actual}")]
178 TypeMismatch { expected: String, actual: String },
179
180 #[error("cannot cast {source_type} to {target}: {reason}")]
182 CastFailed {
183 source_type: String,
184 target: String,
185 reason: String,
186 },
187
188 #[error("invalid column reference: index {index}")]
190 InvalidColumnRef { index: usize },
191
192 #[error("unsupported expression: {0}")]
194 UnsupportedExpression(String),
195
196 #[error("unsupported function: {0}")]
198 UnsupportedFunction(String),
199
200 #[error("invalid regular expression '{pattern}': {reason}")]
202 InvalidRegex { pattern: String, reason: String },
203
204 #[error("invalid argument for {function}: {reason}")]
206 InvalidArgument { function: String, reason: String },
207
208 #[error("vector error: {0}")]
210 Vector(#[from] VectorError),
211}
212
213pub type Result<T> = std::result::Result<T, ExecutorError>;
215
216#[cfg(test)]
217mod tests {
218 use super::*;
219
220 #[test]
221 fn test_executor_error_display() {
222 let err = ExecutorError::TableNotFound("users".into());
223 assert_eq!(err.to_string(), "table not found: users");
224 }
225
226 #[test]
227 fn test_constraint_violation_display() {
228 let err = ConstraintViolation::NotNull {
229 column: "name".into(),
230 };
231 assert_eq!(
232 err.to_string(),
233 "NOT NULL constraint violated on column: name"
234 );
235 }
236
237 #[test]
238 fn test_evaluation_error_display() {
239 let err = EvaluationError::DivisionByZero;
240 assert_eq!(err.to_string(), "division by zero");
241 }
242
243 #[test]
244 fn test_constraint_violation_from() {
245 let violation = ConstraintViolation::NotNull {
246 column: "age".into(),
247 };
248 let err: ExecutorError = violation.into();
249 assert!(matches!(err, ExecutorError::ConstraintViolation(_)));
250 }
251
252 #[test]
253 fn test_evaluation_error_from() {
254 let eval_err = EvaluationError::Overflow;
255 let err: ExecutorError = eval_err.into();
256 assert!(matches!(err, ExecutorError::Evaluation(_)));
257 }
258
259 #[test]
260 fn test_vector_error_conversion() {
261 let vector_err = VectorError::ZeroNormVector;
262 let eval_err: EvaluationError = vector_err.clone().into();
263 assert!(matches!(eval_err, EvaluationError::Vector(_)));
264
265 let exec_err: ExecutorError = vector_err.into();
266 assert!(matches!(exec_err, ExecutorError::Vector(_)));
267 }
268
269 #[test]
270 fn test_path_validation_failed_display() {
271 let err = ExecutorError::PathValidationFailed {
272 path: "/tmp/data.parquet".into(),
273 reason: "symbolic links not allowed".into(),
274 };
275 assert_eq!(
276 err.to_string(),
277 "path validation failed for '/tmp/data.parquet': symbolic links not allowed"
278 );
279 }
280}