spacetimedb_expr/
errors.rs

1use super::statement::InvalidVar;
2use spacetimedb_lib::AlgebraicType;
3use spacetimedb_sats::algebraic_type::fmt::fmt_algebraic_type;
4use spacetimedb_sql_parser::ast::BinOp;
5use spacetimedb_sql_parser::parser::errors::SqlParseError;
6use thiserror::Error;
7
8#[derive(Error, Debug)]
9pub enum Unresolved {
10    #[error("`{0}` is not in scope")]
11    Var(String),
12    #[error("`{0}` is not a valid table")]
13    Table(String),
14    #[error("`{0}` does not have a field `{1}`")]
15    Field(String, String),
16    #[error("Cannot resolve type for literal expression")]
17    Literal,
18}
19
20impl Unresolved {
21    /// Cannot resolve name
22    pub fn var(name: &str) -> Self {
23        Self::Var(name.to_owned())
24    }
25
26    /// Cannot resolve table name
27    pub fn table(name: &str) -> Self {
28        Self::Table(name.to_owned())
29    }
30
31    /// Cannot resolve field name within table
32    pub fn field(table: &str, field: &str) -> Self {
33        Self::Field(table.to_owned(), field.to_owned())
34    }
35}
36
37#[derive(Error, Debug)]
38pub enum InvalidWildcard {
39    #[error("SELECT * is not supported for joins")]
40    Join,
41}
42
43#[derive(Error, Debug)]
44pub enum Unsupported {
45    #[error("Column projections are not supported in subscriptions; Subscriptions must return a table type")]
46    ReturnType,
47    #[error("Unsupported expression in projection")]
48    ProjectExpr,
49}
50
51// TODO: It might be better to return the missing/extra fields
52#[derive(Error, Debug)]
53#[error("Inserting a row with {values} values into `{table}` which has {fields} fields")]
54pub struct InsertValuesError {
55    pub table: String,
56    pub values: usize,
57    pub fields: usize,
58}
59
60// TODO: It might be better to return the missing/extra fields
61#[derive(Error, Debug)]
62#[error("The number of fields ({nfields}) in the INSERT does not match the number of columns ({ncols}) of the table `{table}`")]
63pub struct InsertFieldsError {
64    pub table: String,
65    pub ncols: usize,
66    pub nfields: usize,
67}
68
69#[derive(Debug, Error)]
70#[error("Invalid binary operator `{op}` for type `{ty}`")]
71pub struct InvalidOp {
72    op: BinOp,
73    ty: String,
74}
75
76impl InvalidOp {
77    pub fn new(op: BinOp, ty: &AlgebraicType) -> Self {
78        Self {
79            op,
80            ty: fmt_algebraic_type(ty).to_string(),
81        }
82    }
83}
84
85#[derive(Error, Debug)]
86#[error("The literal expression `{literal}` cannot be parsed as type `{ty}`")]
87pub struct InvalidLiteral {
88    literal: String,
89    ty: String,
90}
91
92impl InvalidLiteral {
93    pub fn new(literal: String, expected: &AlgebraicType) -> Self {
94        Self {
95            literal,
96            ty: fmt_algebraic_type(expected).to_string(),
97        }
98    }
99}
100
101#[derive(Debug, Error)]
102#[error("Unexpected type: (expected) {expected} != {inferred} (inferred)")]
103pub struct UnexpectedType {
104    expected: String,
105    inferred: String,
106}
107
108impl UnexpectedType {
109    pub fn new(expected: &AlgebraicType, inferred: &AlgebraicType) -> Self {
110        Self {
111            expected: fmt_algebraic_type(expected).to_string(),
112            inferred: fmt_algebraic_type(inferred).to_string(),
113        }
114    }
115}
116
117#[derive(Debug, Error)]
118#[error("Duplicate name `{0}`")]
119pub struct DuplicateName(pub String);
120
121#[derive(Debug, Error)]
122#[error("`filter!` does not support column projections; Must return table rows")]
123pub struct FilterReturnType;
124
125#[derive(Error, Debug)]
126pub enum TypingError {
127    #[error(transparent)]
128    Unsupported(#[from] Unsupported),
129    #[error(transparent)]
130    Unresolved(#[from] Unresolved),
131    #[error(transparent)]
132    InvalidVar(#[from] InvalidVar),
133    #[error(transparent)]
134    InsertValues(#[from] InsertValuesError),
135    #[error(transparent)]
136    InsertFields(#[from] InsertFieldsError),
137    #[error(transparent)]
138    ParseError(#[from] SqlParseError),
139
140    #[error(transparent)]
141    InvalidOp(#[from] InvalidOp),
142    #[error(transparent)]
143    Literal(#[from] InvalidLiteral),
144    #[error(transparent)]
145    Unexpected(#[from] UnexpectedType),
146    #[error(transparent)]
147    Wildcard(#[from] InvalidWildcard),
148    #[error(transparent)]
149    DuplicateName(#[from] DuplicateName),
150    #[error(transparent)]
151    FilterReturnType(#[from] FilterReturnType),
152}