spacetimedb_sql_parser/parser/
errors.rs

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