proof_of_sql/sql/parse/
error.rs1use crate::{
2    base::{
3        database::{ColumnOperationError, ColumnType, TableRef},
4        math::decimal::{DecimalError, IntermediateDecimalError},
5    },
6    sql::AnalyzeError,
7};
8use alloc::{
9    boxed::Box,
10    format,
11    string::{String, ToString},
12};
13use core::result::Result;
14use proof_of_sql_parser::posql_time::PoSQLTimestampError;
15use snafu::Snafu;
16use sqlparser::ast::{Ident, ObjectName};
17
18#[derive(Snafu, Debug, PartialEq, Eq)]
20pub enum ConversionError {
21    #[snafu(display("Column '{identifier}' was not found in table '{table_ref}'"))]
22    MissingColumn {
24        identifier: Box<Ident>,
26        table_ref: TableRef,
28    },
29
30    #[snafu(display("Missing schema or table identifier in ObjectName"))]
31    MissingSchemaOrTable {
33        object_name: ObjectName,
35    },
36
37    #[snafu(display("Column '{identifier}' was not found"))]
38    MissingColumnWithoutTable {
40        identifier: Box<Ident>,
42    },
43
44    #[snafu(display("Expected '{expected}' but found '{actual}'"))]
45    InvalidDataType {
47        expected: ColumnType,
49        actual: ColumnType,
51    },
52
53    #[snafu(display("Left side has '{left_type}' type but right side has '{right_type}' type"))]
54    DataTypeMismatch {
56        left_type: String,
58        right_type: String,
60    },
61
62    #[snafu(display("Columns have different lengths: {len_a} != {len_b}"))]
63    DifferentColumnLength {
65        len_a: usize,
67        len_b: usize,
69    },
70
71    #[snafu(display("Multiple result columns with the same alias '{alias}' have been found."))]
72    DuplicateResultAlias {
74        alias: String,
76    },
77
78    #[snafu(display(
79        "A WHERE clause must have boolean type. It is currently of type '{datatype}'."
80    ))]
81    NonbooleanWhereClause {
83        datatype: ColumnType,
85    },
86
87    #[snafu(display(
88        "Invalid order by: alias '{alias}' does not appear in the result expressions."
89    ))]
90    InvalidOrderBy {
92        alias: String,
94    },
95
96    #[snafu(display(
97        "Invalid group by: column '{column}' must appear in the group by expression."
98    ))]
99    InvalidGroupByColumnRef {
101        column: String,
103    },
104
105    #[snafu(display("Invalid expression: {expression}"))]
106    InvalidExpression {
108        expression: String,
110    },
111
112    #[snafu(display("Encountered parsing error: {error}"))]
113    ParseError {
115        error: String,
117    },
118
119    #[snafu(transparent)]
120    DecimalConversionError {
122        source: DecimalError,
124    },
125
126    #[snafu(context(false), display("Timestamp conversion error: {source}"))]
128    TimestampConversionError {
129        source: PoSQLTimestampError,
131    },
132
133    #[snafu(transparent)]
135    ColumnOperationError {
136        source: ColumnOperationError,
138    },
139
140    #[snafu(transparent)]
142    PostprocessingError {
143        source: crate::sql::postprocessing::PostprocessingError,
145    },
146
147    #[snafu(display("Query not provable because: {error}"))]
148    Unprovable {
150        error: String,
152    },
153
154    #[snafu(display("Unsupported operator: {message}"))]
155    UnsupportedOperation {
157        message: String,
159    },
160    #[snafu(display("Failed to convert `Ident` to `Identifier`: {error}"))]
162    IdentifierConversionError {
163        error: String,
165    },
166    #[snafu(transparent)]
168    AnalyzeError {
169        source: AnalyzeError,
171    },
172}
173
174impl From<String> for ConversionError {
175    fn from(value: String) -> Self {
176        ConversionError::ParseError { error: value }
177    }
178}
179
180impl From<ConversionError> for String {
181    fn from(error: ConversionError) -> Self {
182        error.to_string()
183    }
184}
185
186impl From<IntermediateDecimalError> for ConversionError {
187    fn from(err: IntermediateDecimalError) -> ConversionError {
188        ConversionError::DecimalConversionError {
189            source: DecimalError::IntermediateDecimalConversionError { source: err },
190        }
191    }
192}
193
194impl ConversionError {
195    pub fn non_numeric_expr_in_agg<S: Into<String>>(dtype: S, func: S) -> Self {
197        ConversionError::InvalidExpression {
198            expression: format!(
199                "cannot use expression of type '{}' with numeric aggregation function '{}'",
200                dtype.into().to_lowercase(),
201                func.into().to_lowercase()
202            ),
203        }
204    }
205}
206
207pub type ConversionResult<T> = Result<T, ConversionError>;