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 { table_id: u64, row_id: u64, conflicting_txn: u64 },
199 ConcurrentWriteDisabled,
201 ShuttingDown,
203 NoActiveTransaction,
205 LockPoisoned(String),
207}
208
209impl fmt::Display for TransactionError {
210 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
211 match self {
212 Self::TableLocked { table_id, owner_txn } => {
213 write!(f, "table {table_id} already locked by txn#{owner_txn}")
214 }
215 Self::WriteConflict { table_id, row_id, conflicting_txn } => {
216 write!(f, "write conflict on table {table_id} row {row_id}: txn#{conflicting_txn} also modified this row")
217 }
218 Self::ConcurrentWriteDisabled => write!(f, "concurrent write not allowed"),
219 Self::ShuttingDown => write!(f, "transaction manager is shutting down"),
220 Self::NoActiveTransaction => write!(f, "no active write transaction"),
221 Self::LockPoisoned(s) => write!(f, "lock poisoned: {s}"),
222 }
223 }
224}
225
226impl std::error::Error for TransactionError {}
227
228impl From<TransactionError> for String {
230 fn from(e: TransactionError) -> String {
231 format!("transaction: {e}")
232 }
233}
234
235#[derive(Debug)]
241pub enum CatalogError {
242 AlreadyExists(String),
244 NotFound(String),
246 ColumnAlreadyExists { table: String, column: String },
248 ColumnNotFound { table: String, column: String },
250 InvalidOperation(String),
252}
253
254impl fmt::Display for CatalogError {
255 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
256 match self {
257 Self::AlreadyExists(s) => write!(f, "already exists: {s}"),
258 Self::NotFound(s) => write!(f, "not found: {s}"),
259 Self::ColumnAlreadyExists { table, column } => {
260 write!(f, "column '{column}' already exists on table '{table}'")
261 }
262 Self::ColumnNotFound { table, column } => {
263 write!(f, "column '{column}' not found on table '{table}'")
264 }
265 Self::InvalidOperation(s) => write!(f, "invalid operation: {s}"),
266 }
267 }
268}
269
270impl std::error::Error for CatalogError {}
271
272impl From<CatalogError> for String {
274 fn from(e: CatalogError) -> String {
275 format!("catalog: {e}")
276 }
277}
278
279#[derive(Debug)]
285pub enum BinderError {
286 TableNotFound(String),
288 ColumnNotFound { table: String, column: String },
290 VariableNotInScope(String),
292 UnknownType(String),
294 Validation(String),
296 Io(String),
298}
299
300impl fmt::Display for BinderError {
301 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
302 match self {
303 Self::TableNotFound(s) => write!(f, "table not found: {s}"),
304 Self::ColumnNotFound { table, column } => {
305 write!(f, "column '{column}' not found in table '{table}'")
306 }
307 Self::VariableNotInScope(s) => write!(f, "variable not in scope: {s}"),
308 Self::UnknownType(s) => write!(f, "unknown type: {s}"),
309 Self::Validation(s) => write!(f, "{s}"),
310 Self::Io(s) => write!(f, "I/O error: {s}"),
311 }
312 }
313}
314
315impl std::error::Error for BinderError {}
316
317impl From<BinderError> for String {
319 fn from(e: BinderError) -> String {
320 format!("binder: {e}")
321 }
322}
323
324impl From<String> for BinderError {
326 fn from(s: String) -> Self {
327 BinderError::Validation(s)
328 }
329}
330
331impl From<&str> for BinderError {
333 fn from(s: &str) -> Self {
334 BinderError::Validation(s.to_string())
335 }
336}
337
338impl From<CatalogError> for BinderError {
340 fn from(e: CatalogError) -> Self {
341 match e {
342 CatalogError::AlreadyExists(s) => BinderError::Validation(format!("already exists: {s}")),
343 CatalogError::NotFound(s) => BinderError::TableNotFound(s),
344 CatalogError::ColumnAlreadyExists { table, column } => {
345 BinderError::Validation(format!("column '{column}' already exists on table '{table}'"))
346 }
347 CatalogError::ColumnNotFound { table, column } => {
348 BinderError::ColumnNotFound { table, column }
349 }
350 CatalogError::InvalidOperation(s) => BinderError::Validation(s),
351 }
352 }
353}
354
355#[derive(Debug)]
361pub enum PlannerError {
362 Planning(String),
364}
365
366impl fmt::Display for PlannerError {
367 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
368 match self {
369 Self::Planning(s) => write!(f, "{s}"),
370 }
371 }
372}
373
374impl std::error::Error for PlannerError {}
375
376impl From<PlannerError> for String {
378 fn from(e: PlannerError) -> String {
379 format!("planner: {e}")
380 }
381}
382
383impl From<String> for PlannerError {
385 fn from(s: String) -> Self {
386 PlannerError::Planning(s)
387 }
388}
389
390impl From<&str> for PlannerError {
392 fn from(s: &str) -> Self {
393 PlannerError::Planning(s.to_string())
394 }
395}
396
397#[derive(Debug)]
403pub enum ProcessorError {
404 Expression(String),
406 Execution(String),
408 Io(String),
410}
411
412impl fmt::Display for ProcessorError {
413 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
414 match self {
415 Self::Expression(s) => write!(f, "expression: {s}"),
416 Self::Execution(s) => write!(f, "{s}"),
417 Self::Io(s) => write!(f, "I/O error: {s}"),
418 }
419 }
420}
421
422impl std::error::Error for ProcessorError {}
423
424impl From<ProcessorError> for String {
426 fn from(e: ProcessorError) -> String {
427 format!("processor: {e}")
428 }
429}
430
431impl From<String> for ProcessorError {
433 fn from(s: String) -> Self {
434 ProcessorError::Execution(s)
435 }
436}
437
438impl From<&str> for ProcessorError {
440 fn from(s: &str) -> Self {
441 ProcessorError::Execution(s.to_string())
442 }
443}
444
445impl From<StorageError> for ProcessorError {
447 fn from(e: StorageError) -> Self {
448 ProcessorError::Execution(format!("storage: {e}"))
449 }
450}
451
452pub fn lock_or_poisoned<T>(mutex: &std::sync::Mutex<T>) -> crate::error::Result<std::sync::MutexGuard<'_, T>> {
458 mutex
459 .lock()
460 .map_err(|e| AkarError::Transaction(TransactionError::LockPoisoned(e.to_string())))
461}
462
463