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("storage error: {0}")]
57 Storage(#[from] StorageError),
58
59 #[error("column required: {column} (DEFAULT not supported in v0.1.2)")]
61 ColumnRequired { column: String },
62
63 #[error("invalid index name: {name} - {reason}")]
65 InvalidIndexName { name: String, reason: String },
66
67 #[error("invalid operation: {operation} - {reason}")]
69 InvalidOperation { operation: String, reason: String },
70
71 #[error("file not found: {0}")]
73 FileNotFound(String),
74
75 #[error("path validation failed for '{path}': {reason}")]
77 PathValidationFailed { path: String, reason: String },
78
79 #[error("unsupported format: {0}")]
81 UnsupportedFormat(String),
82
83 #[error("schema mismatch: expected {expected} columns, got {actual} - {reason}")]
85 SchemaMismatch {
86 expected: usize,
87 actual: usize,
88 reason: String,
89 },
90
91 #[error("invalid storage type: {0}")]
93 InvalidStorageType(String),
94
95 #[error("invalid compression: {0}")]
97 InvalidCompression(String),
98
99 #[error("invalid row_group_size: {0}")]
101 InvalidRowGroupSize(String),
102
103 #[error("invalid rowid_mode: {0}")]
105 InvalidRowIdMode(String),
106
107 #[error("unknown table option: {0}")]
109 UnknownTableOption(String),
110
111 #[error("duplicate option: {0}")]
113 DuplicateOption(String),
114
115 #[error("vector error: {0}")]
117 Vector(#[from] VectorError),
118
119 #[error("bulk load error: {0}")]
121 BulkLoad(String),
122
123 #[error("columnar engine error: {0}")]
125 Columnar(String),
126
127 #[error("planner error: {0}")]
129 Planner(#[from] crate::planner::PlannerError),
130}
131
132#[derive(Debug, Error, Clone, PartialEq, Eq)]
134pub enum ConstraintViolation {
135 #[error("NOT NULL constraint violated on column: {column}")]
137 NotNull { column: String },
138
139 #[error("PRIMARY KEY constraint violated on columns: {columns:?}, value: {value:?}")]
141 PrimaryKey {
142 columns: Vec<String>,
143 value: Option<String>,
144 },
145
146 #[error(
148 "UNIQUE constraint violated on index: {index_name}, columns: {columns:?}, value: {value:?}"
149 )]
150 Unique {
151 index_name: String,
152 columns: Vec<String>,
153 value: Option<String>,
154 },
155}
156
157#[derive(Debug, Error, Clone, PartialEq, Eq)]
159pub enum EvaluationError {
160 #[error("division by zero")]
162 DivisionByZero,
163
164 #[error("integer overflow")]
166 Overflow,
167
168 #[error("type mismatch: expected {expected}, got {actual}")]
170 TypeMismatch { expected: String, actual: String },
171
172 #[error("invalid column reference: index {index}")]
174 InvalidColumnRef { index: usize },
175
176 #[error("unsupported expression: {0}")]
178 UnsupportedExpression(String),
179
180 #[error("unsupported function: {0}")]
182 UnsupportedFunction(String),
183
184 #[error("vector error: {0}")]
186 Vector(#[from] VectorError),
187}
188
189pub type Result<T> = std::result::Result<T, ExecutorError>;
191
192#[cfg(test)]
193mod tests {
194 use super::*;
195
196 #[test]
197 fn test_executor_error_display() {
198 let err = ExecutorError::TableNotFound("users".into());
199 assert_eq!(err.to_string(), "table not found: users");
200 }
201
202 #[test]
203 fn test_constraint_violation_display() {
204 let err = ConstraintViolation::NotNull {
205 column: "name".into(),
206 };
207 assert_eq!(
208 err.to_string(),
209 "NOT NULL constraint violated on column: name"
210 );
211 }
212
213 #[test]
214 fn test_evaluation_error_display() {
215 let err = EvaluationError::DivisionByZero;
216 assert_eq!(err.to_string(), "division by zero");
217 }
218
219 #[test]
220 fn test_constraint_violation_from() {
221 let violation = ConstraintViolation::NotNull {
222 column: "age".into(),
223 };
224 let err: ExecutorError = violation.into();
225 assert!(matches!(err, ExecutorError::ConstraintViolation(_)));
226 }
227
228 #[test]
229 fn test_evaluation_error_from() {
230 let eval_err = EvaluationError::Overflow;
231 let err: ExecutorError = eval_err.into();
232 assert!(matches!(err, ExecutorError::Evaluation(_)));
233 }
234
235 #[test]
236 fn test_vector_error_conversion() {
237 let vector_err = VectorError::ZeroNormVector;
238 let eval_err: EvaluationError = vector_err.clone().into();
239 assert!(matches!(eval_err, EvaluationError::Vector(_)));
240
241 let exec_err: ExecutorError = vector_err.into();
242 assert!(matches!(exec_err, ExecutorError::Vector(_)));
243 }
244
245 #[test]
246 fn test_path_validation_failed_display() {
247 let err = ExecutorError::PathValidationFailed {
248 path: "/tmp/data.parquet".into(),
249 reason: "symbolic links not allowed".into(),
250 };
251 assert_eq!(
252 err.to_string(),
253 "path validation failed for '/tmp/data.parquet': symbolic links not allowed"
254 );
255 }
256}