1use std::fmt;
21
22#[derive(Debug)]
28pub enum AkarError {
29 Storage(StorageError),
31 Transaction(TransactionError),
33 Catalog(CatalogError),
35 Binder(BinderError),
37 Planner(PlannerError),
39 Processor(ProcessorError),
41 Parser(String),
43 Io(std::io::Error),
45 Internal(String),
47}
48
49impl fmt::Display for AkarError {
50 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
51 match self {
52 Self::Storage(e) => write!(f, "storage: {e}"),
53 Self::Transaction(e) => write!(f, "transaction: {e}"),
54 Self::Catalog(e) => write!(f, "catalog: {e}"),
55 Self::Binder(e) => write!(f, "binder: {e}"),
56 Self::Planner(e) => write!(f, "planner: {e}"),
57 Self::Processor(e) => write!(f, "processor: {e}"),
58 Self::Parser(s) => write!(f, "parser: {s}"),
59 Self::Io(e) => write!(f, "io: {e}"),
60 Self::Internal(s) => write!(f, "internal: {s}"),
61 }
62 }
63}
64
65impl std::error::Error for AkarError {
66 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
67 match self {
68 Self::Storage(e) => Some(e),
69 Self::Transaction(e) => Some(e),
70 Self::Catalog(e) => Some(e),
71 Self::Binder(e) => Some(e),
72 Self::Planner(e) => Some(e),
73 Self::Processor(e) => Some(e),
74 Self::Io(e) => Some(e),
75 _ => None,
76 }
77 }
78}
79
80impl From<std::io::Error> for AkarError {
81 fn from(e: std::io::Error) -> Self {
82 Self::Io(e)
83 }
84}
85
86impl From<StorageError> for AkarError {
87 fn from(e: StorageError) -> Self {
88 Self::Storage(e)
89 }
90}
91
92impl From<TransactionError> for AkarError {
93 fn from(e: TransactionError) -> Self {
94 Self::Transaction(e)
95 }
96}
97
98impl From<CatalogError> for AkarError {
99 fn from(e: CatalogError) -> Self {
100 Self::Catalog(e)
101 }
102}
103
104impl From<BinderError> for AkarError {
105 fn from(e: BinderError) -> Self {
106 Self::Binder(e)
107 }
108}
109
110impl From<PlannerError> for AkarError {
111 fn from(e: PlannerError) -> Self {
112 Self::Planner(e)
113 }
114}
115
116impl From<ProcessorError> for AkarError {
117 fn from(e: ProcessorError) -> Self {
118 Self::Processor(e)
119 }
120}
121
122pub type Result<T> = std::result::Result<T, AkarError>;
124
125#[derive(Debug)]
131pub enum StorageError {
132 Wal(String),
134 BufferManager(String),
136 TableNotFound(String),
138 ColumnNotFound(String),
140 TypeMismatch { expected: String, actual: String },
142 Page(String),
144 ShadowFile(String),
146 Undo(String),
148 LocalStorage(String),
150 Spiller(String),
152 Index(String),
154 Reader(String),
156}
157
158impl fmt::Display for StorageError {
159 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
160 match self {
161 Self::Wal(s) => write!(f, "WAL: {s}"),
162 Self::BufferManager(s) => write!(f, "buffer manager: {s}"),
163 Self::TableNotFound(s) => write!(f, "table not found: {s}"),
164 Self::ColumnNotFound(s) => write!(f, "column not found: {s}"),
165 Self::TypeMismatch { expected, actual } => {
166 write!(f, "type mismatch: expected {expected}, got {actual}")
167 }
168 Self::Page(s) => write!(f, "page: {s}"),
169 Self::ShadowFile(s) => write!(f, "shadow file: {s}"),
170 Self::Undo(s) => write!(f, "undo: {s}"),
171 Self::LocalStorage(s) => write!(f, "local storage: {s}"),
172 Self::Spiller(s) => write!(f, "spiller: {s}"),
173 Self::Index(s) => write!(f, "index: {s}"),
174 Self::Reader(s) => write!(f, "reader: {s}"),
175 }
176 }
177}
178
179impl std::error::Error for StorageError {}
180
181impl From<StorageError> for String {
183 fn from(e: StorageError) -> String {
184 format!("storage: {e}")
185 }
186}
187
188#[derive(Debug)]
194pub enum TransactionError {
195 TableLocked { table_id: u64, owner_txn: u64 },
197 WriteConflict {
199 table_id: u64,
200 row_id: u64,
201 conflicting_txn: u64,
202 },
203 ConcurrentWriteDisabled,
205 ShuttingDown,
207 NoActiveTransaction,
209 LockPoisoned(String),
211}
212
213impl fmt::Display for TransactionError {
214 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
215 match self {
216 Self::TableLocked { table_id, owner_txn } => {
217 write!(f, "table {table_id} already locked by txn#{owner_txn}")
218 }
219 Self::WriteConflict {
220 table_id,
221 row_id,
222 conflicting_txn,
223 } => {
224 write!(
225 f,
226 "write conflict on table {table_id} row {row_id}: txn#{conflicting_txn} also modified this row"
227 )
228 }
229 Self::ConcurrentWriteDisabled => write!(f, "concurrent write not allowed"),
230 Self::ShuttingDown => write!(f, "transaction manager is shutting down"),
231 Self::NoActiveTransaction => write!(f, "no active write transaction"),
232 Self::LockPoisoned(s) => write!(f, "lock poisoned: {s}"),
233 }
234 }
235}
236
237impl std::error::Error for TransactionError {}
238
239impl From<TransactionError> for String {
241 fn from(e: TransactionError) -> String {
242 format!("transaction: {e}")
243 }
244}
245
246#[derive(Debug)]
252pub enum CatalogError {
253 AlreadyExists(String),
255 NotFound(String),
257 ColumnAlreadyExists { table: String, column: String },
259 ColumnNotFound { table: String, column: String },
261 InvalidOperation(String),
263}
264
265impl fmt::Display for CatalogError {
266 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
267 match self {
268 Self::AlreadyExists(s) => write!(f, "already exists: {s}"),
269 Self::NotFound(s) => write!(f, "not found: {s}"),
270 Self::ColumnAlreadyExists { table, column } => {
271 write!(f, "column '{column}' already exists on table '{table}'")
272 }
273 Self::ColumnNotFound { table, column } => {
274 write!(f, "column '{column}' not found on table '{table}'")
275 }
276 Self::InvalidOperation(s) => write!(f, "invalid operation: {s}"),
277 }
278 }
279}
280
281impl std::error::Error for CatalogError {}
282
283impl From<CatalogError> for String {
285 fn from(e: CatalogError) -> String {
286 format!("catalog: {e}")
287 }
288}
289
290#[derive(Debug)]
296pub enum BinderError {
297 TableNotFound(String),
299 ColumnNotFound { table: String, column: String },
301 VariableNotInScope(String),
303 UnknownType(String),
305 Validation(String),
307 Io(String),
309}
310
311impl fmt::Display for BinderError {
312 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
313 match self {
314 Self::TableNotFound(s) => write!(f, "table not found: {s}"),
315 Self::ColumnNotFound { table, column } => {
316 write!(f, "column '{column}' not found in table '{table}'")
317 }
318 Self::VariableNotInScope(s) => write!(f, "variable not in scope: {s}"),
319 Self::UnknownType(s) => write!(f, "unknown type: {s}"),
320 Self::Validation(s) => write!(f, "{s}"),
321 Self::Io(s) => write!(f, "I/O error: {s}"),
322 }
323 }
324}
325
326impl std::error::Error for BinderError {}
327
328impl From<BinderError> for String {
330 fn from(e: BinderError) -> String {
331 format!("binder: {e}")
332 }
333}
334
335impl From<String> for BinderError {
337 fn from(s: String) -> Self {
338 BinderError::Validation(s)
339 }
340}
341
342impl From<&str> for BinderError {
344 fn from(s: &str) -> Self {
345 BinderError::Validation(s.to_string())
346 }
347}
348
349impl From<CatalogError> for BinderError {
351 fn from(e: CatalogError) -> Self {
352 match e {
353 CatalogError::AlreadyExists(s) => BinderError::Validation(format!("already exists: {s}")),
354 CatalogError::NotFound(s) => BinderError::TableNotFound(s),
355 CatalogError::ColumnAlreadyExists { table, column } => {
356 BinderError::Validation(format!("column '{column}' already exists on table '{table}'"))
357 }
358 CatalogError::ColumnNotFound { table, column } => BinderError::ColumnNotFound { table, column },
359 CatalogError::InvalidOperation(s) => BinderError::Validation(s),
360 }
361 }
362}
363
364#[derive(Debug)]
370pub enum PlannerError {
371 Planning(String),
373}
374
375impl fmt::Display for PlannerError {
376 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
377 match self {
378 Self::Planning(s) => write!(f, "{s}"),
379 }
380 }
381}
382
383impl std::error::Error for PlannerError {}
384
385impl From<PlannerError> for String {
387 fn from(e: PlannerError) -> String {
388 format!("planner: {e}")
389 }
390}
391
392impl From<String> for PlannerError {
394 fn from(s: String) -> Self {
395 PlannerError::Planning(s)
396 }
397}
398
399impl From<&str> for PlannerError {
401 fn from(s: &str) -> Self {
402 PlannerError::Planning(s.to_string())
403 }
404}
405
406#[derive(Debug)]
412pub enum ProcessorError {
413 Expression(String),
415 Execution(String),
417 Io(String),
419}
420
421impl fmt::Display for ProcessorError {
422 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
423 match self {
424 Self::Expression(s) => write!(f, "expression: {s}"),
425 Self::Execution(s) => write!(f, "{s}"),
426 Self::Io(s) => write!(f, "I/O error: {s}"),
427 }
428 }
429}
430
431impl std::error::Error for ProcessorError {}
432
433impl From<ProcessorError> for String {
435 fn from(e: ProcessorError) -> String {
436 format!("processor: {e}")
437 }
438}
439
440impl From<String> for ProcessorError {
442 fn from(s: String) -> Self {
443 ProcessorError::Execution(s)
444 }
445}
446
447impl From<&str> for ProcessorError {
449 fn from(s: &str) -> Self {
450 ProcessorError::Execution(s.to_string())
451 }
452}
453
454impl From<StorageError> for ProcessorError {
456 fn from(e: StorageError) -> Self {
457 ProcessorError::Execution(format!("storage: {e}"))
458 }
459}
460
461pub fn lock_or_poisoned<T>(mutex: &std::sync::Mutex<T>) -> crate::error::Result<std::sync::MutexGuard<'_, T>> {
467 mutex
468 .lock()
469 .map_err(|e| AkarError::Transaction(TransactionError::LockPoisoned(e.to_string())))
470}