Skip to main content

uqa_sql/catalog/sequence_functions/
value_error.rs

1//
2// Unified Query Algebra
3//
4// Copyright (c) 2023-2026 Cognica, Inc.
5//
6
7//! Stable diagnostics and SQLSTATEs for sequence value functions.
8use crate::SQLError;
9#[derive(Debug, thiserror::Error)]
10pub enum SequenceValueError {
11    #[error("relation \"{0}\" does not exist")]
12    Undefined(String),
13    #[error("could not open relation with OID {0}")]
14    MissingOid(i64),
15    #[error("cannot open relation \"{name}\": this operation is not supported for {kind}s")]
16    WrongKind { name: String, kind: &'static str },
17    #[error("currval of sequence \"{0}\" is not yet defined in this session")]
18    CurrvalUndefined(String),
19    #[error("lastval is not yet defined in this session")]
20    LastvalUndefined,
21    #[error("setval: value {value} is out of bounds for sequence \"{name}\" ({min}..{max})")]
22    SetvalOutOfBounds {
23        name: String,
24        value: i64,
25        min: i64,
26        max: i64,
27    },
28    #[error("nextval: reached {bound} value of sequence \"{name}\" ({value})")]
29    Exhausted {
30        name: String,
31        bound: &'static str,
32        value: i64,
33    },
34    #[error("cannot execute {0}() in a read-only transaction")]
35    ReadOnly(&'static str),
36    #[error(transparent)]
37    Security(#[from] SQLError),
38    #[error(transparent)]
39    Cancelled(#[from] uqa_core::QueryCancelled),
40    #[error("{0}")]
41    Internal(String),
42}
43
44impl SequenceValueError {
45    pub fn into_sql_error(self) -> SQLError {
46        let sqlstate = match self {
47            Self::Undefined(_) => "42P01",
48            Self::MissingOid(_) => "XX000",
49            Self::WrongKind { name, kind } => {
50                let kinds = match kind {
51                    "index" => "indexes".into(),
52                    "partitioned index" => "partitioned indexes".into(),
53                    kind => format!("{kind}s"),
54                };
55                return SQLError::Diagnostic {
56                    sqlstate: "42809".into(),
57                    message: format!("cannot open relation \"{name}\""),
58                    detail: Some(format!("This operation is not supported for {kinds}.")),
59                    hint: None,
60                };
61            }
62            Self::CurrvalUndefined(_) | Self::LastvalUndefined => "55000",
63            Self::SetvalOutOfBounds { .. } => "22003",
64            Self::Exhausted { .. } => "2200H",
65            Self::ReadOnly(_) => "25006",
66            Self::Security(error) => return error,
67            Self::Cancelled(error) => return SQLError::Cancelled(error),
68            Self::Internal(message) => return SQLError::Internal(message),
69        };
70        SQLError::Routine {
71            sqlstate: sqlstate.into(),
72            message: self.to_string(),
73        }
74    }
75}
76
77#[cfg(test)]
78mod tests;