crabka_pgparser/error.rs
1//! Parse/lex errors. Most map to SQLSTATE 42601 (`syntax_error`) and carry the
2//! byte offset where the problem was detected. A too-deep query — one whose
3//! nesting would overflow the parser/evaluator stack — instead maps to 54001
4//! (`statement_too_complex` / "stack depth limit exceeded"), matching
5//! `PostgreSQL`.
6
7/// A parse/lex error. `message` is the full, ready-to-display text (the
8/// `#[error]` format is just `"{message}"`), so the `42601` "syntax error at
9/// position N: …" framing is baked in by `new`, while a `54001` depth error
10/// (built by `too_deep`) renders its own PostgreSQL-faithful text verbatim.
11#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
12#[error("{message}")]
13pub struct ParseError {
14 pub message: String,
15 pub position: usize,
16 /// The SQLSTATE this error maps to. Defaults to `"42601"` (`syntax_error`);
17 /// `too_deep` sets it to `"54001"` (`statement_too_complex`).
18 sqlstate: &'static str,
19}
20
21impl ParseError {
22 pub fn new(message: impl Into<String>, position: usize) -> Self {
23 Self {
24 message: format!("syntax error at position {position}: {}", message.into()),
25 position,
26 sqlstate: "42601",
27 }
28 }
29
30 pub(crate) fn new_sqlstate(
31 sqlstate: &'static str,
32 message: impl Into<String>,
33 position: usize,
34 ) -> Self {
35 Self {
36 message: message.into(),
37 position,
38 sqlstate,
39 }
40 }
41
42 /// A recursion-depth-limit error: the statement nests more deeply than the
43 /// parser's `MAX_DEPTH` allows. Maps to SQLSTATE `54001`
44 /// (`statement_too_complex`) with `PostgreSQL`'s "stack depth limit exceeded"
45 /// message, so a maliciously deep query returns a clean error instead of
46 /// overflowing the stack and aborting the server process.
47 #[must_use]
48 pub fn too_deep(position: usize) -> Self {
49 Self {
50 message: "stack depth limit exceeded".to_string(),
51 position,
52 sqlstate: "54001",
53 }
54 }
55
56 #[must_use]
57 pub fn sqlstate(&self) -> &'static str {
58 self.sqlstate
59 }
60}