Skip to main content

spacetimedb_sql_parser/parser/
errors.rs

1use std::fmt::Display;
2
3use sqlparser::{
4    ast::{BinaryOperator, Expr, Function, Query, Select, SelectItem, SetExpr, TableFactor, TableWithJoins, Value},
5    parser::ParserError,
6};
7use thiserror::Error;
8
9// FIXME: reduce type size
10#[expect(clippy::large_enum_variant)]
11#[derive(Error, Debug)]
12pub enum SubscriptionUnsupported {
13    #[error("Unsupported SELECT: {0}")]
14    Select(Select),
15    #[error("Unsupported: {0}")]
16    Feature(String),
17    #[error("Unsupported: Non-SELECT queries")]
18    Dml,
19}
20
21impl SubscriptionUnsupported {
22    pub(crate) fn feature(expr: impl Display) -> Self {
23        Self::Feature(format!("{expr}"))
24    }
25}
26
27// FIXME: reduce type size
28#[expect(clippy::large_enum_variant)]
29#[derive(Error, Debug)]
30pub enum SqlUnsupported {
31    #[error("Unsupported literal expression: {0}")]
32    Literal(Value),
33    #[error("Unsupported LIMIT expression: {0}")]
34    Limit(Expr),
35    #[error("Unsupported expression: {0}")]
36    Expr(Expr),
37    #[error("Unsupported binary operator: {0}")]
38    BinOp(BinaryOperator),
39    #[error("Unsupported projection: {0}")]
40    Projection(SelectItem),
41    #[error("Unsupported projection expression: {0}")]
42    ProjectionExpr(Expr),
43    #[error("Unsupported aggregate function: {0}")]
44    Aggregate(Function),
45    #[error("Aggregate expressions must have column aliases")]
46    AggregateWithoutAlias,
47    #[error("Unsupported FROM expression: {0}")]
48    From(TableFactor),
49    #[error("Unsupported set operation: {0}")]
50    SetOp(Box<SetExpr>),
51    #[error("Unsupported INSERT expression: {0}")]
52    Insert(Query),
53    #[error("Unsupported INSERT value: {0}")]
54    InsertValue(Expr),
55    #[error("Unsupported table expression in DELETE: {0}")]
56    DeleteTable(TableWithJoins),
57    #[error("Unsupported column/variable assignment expression: {0}")]
58    Assignment(Expr),
59    #[error("Unsupported: {0}")]
60    Feature(String),
61    #[error("Non-inner joins are not supported")]
62    JoinType,
63    #[error("Implicit joins are not supported")]
64    ImplicitJoins,
65    #[error("Mixed wildcard projections are not supported")]
66    MixedWildcardProject,
67    #[error("Multiple SQL statements are not supported")]
68    MultiStatement,
69    #[error("Multi-table DELETE is not supported")]
70    MultiTableDelete,
71    #[error("Empty SQL query")]
72    Empty,
73    #[error("Names must be qualified when using joins")]
74    UnqualifiedNames,
75}
76
77impl SqlUnsupported {
78    pub(crate) fn feature(expr: impl Display) -> Self {
79        Self::Feature(format!("{expr}"))
80    }
81}
82
83#[derive(Error, Debug)]
84pub enum SqlRequired {
85    #[error("A FROM clause is required")]
86    From,
87    #[error("Aliases are required for JOIN")]
88    JoinAlias,
89}
90
91#[derive(Error, Debug)]
92#[error("Recursion limit exceeded, `{source_}`")]
93pub struct RecursionError {
94    pub(crate) source_: &'static str,
95}
96
97#[derive(Error, Debug)]
98pub enum SqlParseError {
99    #[error(transparent)]
100    SqlUnsupported(#[from] Box<SqlUnsupported>),
101    #[error(transparent)]
102    SubscriptionUnsupported(#[from] Box<SubscriptionUnsupported>),
103    #[error(transparent)]
104    SqlRequired(#[from] SqlRequired),
105    #[error(transparent)]
106    ParserError(#[from] ParserError),
107    #[error(transparent)]
108    Recursion(#[from] RecursionError),
109}
110
111impl From<SubscriptionUnsupported> for SqlParseError {
112    fn from(value: SubscriptionUnsupported) -> Self {
113        SqlParseError::SubscriptionUnsupported(Box::new(value))
114    }
115}
116
117impl From<SqlUnsupported> for SqlParseError {
118    fn from(value: SqlUnsupported) -> Self {
119        SqlParseError::SqlUnsupported(Box::new(value))
120    }
121}