1use thiserror::Error;
2
3pub type Result<T> = std::result::Result<T, MongrelQueryError>;
4
5#[non_exhaustive]
6#[derive(Debug, Error)]
7pub enum MongrelQueryError {
8 #[error("mongreldb error: {0}")]
9 Core(#[from] mongreldb_core::MongrelError),
10 #[error("arrow error: {0}")]
11 Arrow(String),
12 #[error("datafusion error: {0}")]
13 DataFusion(String),
14 #[error("schema error: {0}")]
15 Schema(String),
16 #[error("query {query_id} cancelled: {reason:?}")]
17 QueryCancelled {
18 query_id: crate::QueryId,
19 reason: mongreldb_core::CancellationReason,
20 committed: bool,
21 committed_statements: usize,
22 last_commit_epoch: Option<u64>,
23 first_commit_statement_index: Option<usize>,
24 last_commit_statement_index: Option<usize>,
25 completed_statements: usize,
26 cancelled_statement_index: usize,
27 },
28 #[error("query {query_id} deadline exceeded")]
29 DeadlineExceeded {
30 query_id: crate::QueryId,
31 timeout_ms: Option<u64>,
32 committed: bool,
33 committed_statements: usize,
34 last_commit_epoch: Option<u64>,
35 first_commit_statement_index: Option<usize>,
36 last_commit_statement_index: Option<usize>,
37 completed_statements: usize,
38 cancelled_statement_index: usize,
39 },
40 #[error("query id {query_id} is already active or retained")]
41 QueryIdConflict { query_id: crate::QueryId },
42 #[error("SQL query registry is full")]
43 QueryRegistryFull,
44 #[error("query {query_id} result limit exceeded: {message}")]
45 ResultLimitExceeded {
46 query_id: crate::QueryId,
47 committed: bool,
48 committed_statements: usize,
49 last_commit_epoch: Option<u64>,
50 first_commit_statement_index: Option<usize>,
51 last_commit_statement_index: Option<usize>,
52 completed_statements: usize,
53 statement_index: usize,
54 message: String,
55 },
56 #[error("transaction is aborted; ROLLBACK or ROLLBACK TO SAVEPOINT is required")]
57 TransactionAborted,
58 #[error("no SQL transaction is open")]
59 NoSqlTransaction,
60 #[error("no savepoint named '{name}'")]
61 SavepointNotFound { name: String },
62 #[error(
63 "query {query_id} commit outcome: committed={committed}, committed_statements={committed_statements}, last_commit_epoch={last_commit_epoch:?}: {message}"
64 )]
65 CommitOutcome {
66 query_id: crate::QueryId,
67 committed: bool,
68 committed_statements: usize,
69 last_commit_epoch: Option<u64>,
70 first_commit_statement_index: Option<usize>,
71 last_commit_statement_index: Option<usize>,
72 completed_statements: usize,
73 statement_index: usize,
74 message: String,
75 },
76 #[error("query {query_id} durable outcome is unknown: {message}")]
77 OutcomeUnknown {
78 query_id: crate::QueryId,
79 message: String,
80 },
81 #[error("invalid query state: {0}")]
82 InvalidQueryState(String),
83}
84
85impl MongrelQueryError {
86 pub fn code(&self) -> &'static str {
88 match self {
89 Self::Core(_) | Self::Arrow(_) | Self::DataFusion(_) | Self::Schema(_) => {
90 "SQL_EXECUTION_FAILED"
91 }
92 Self::QueryCancelled {
93 committed: true, ..
94 } => "QUERY_CANCELLED_AFTER_COMMIT",
95 Self::QueryCancelled { .. } => "QUERY_CANCELLED",
96 Self::DeadlineExceeded {
97 committed: true, ..
98 } => "DEADLINE_AFTER_COMMIT",
99 Self::DeadlineExceeded { .. } => "DEADLINE_EXCEEDED",
100 Self::QueryIdConflict { .. } => "QUERY_ID_CONFLICT",
101 Self::QueryRegistryFull => "QUERY_REGISTRY_FULL",
102 Self::ResultLimitExceeded { .. } => "RESULT_LIMIT_EXCEEDED",
103 Self::TransactionAborted => "TRANSACTION_ABORTED",
104 Self::NoSqlTransaction => "NO_SQL_TRANSACTION",
105 Self::SavepointNotFound { .. } => "SAVEPOINT_NOT_FOUND",
106 Self::CommitOutcome { .. } => "COMMIT_OUTCOME",
107 Self::OutcomeUnknown { .. } => "QUERY_OUTCOME_UNKNOWN",
108 Self::InvalidQueryState(_) => "INVALID_QUERY_STATE",
109 }
110 }
111}