proof_of_sql/sql/parse/
error.rsuse crate::base::{
database::{ColumnOperationError, ColumnType},
math::decimal::DecimalError,
};
use alloc::{
boxed::Box,
format,
string::{String, ToString},
};
use core::result::Result;
use proof_of_sql_parser::{
intermediate_decimal::IntermediateDecimalError, posql_time::PoSQLTimestampError, Identifier,
ResourceId,
};
use snafu::Snafu;
#[derive(Snafu, Debug, PartialEq, Eq)]
pub enum ConversionError {
#[snafu(display("Column '{identifier}' was not found in table '{resource_id}'"))]
MissingColumn {
identifier: Box<Identifier>,
resource_id: Box<ResourceId>,
},
#[snafu(display("Column '{identifier}' was not found"))]
MissingColumnWithoutTable {
identifier: Box<Identifier>,
},
#[snafu(display("Expected '{expected}' but found '{actual}'"))]
InvalidDataType {
expected: ColumnType,
actual: ColumnType,
},
#[snafu(display("Left side has '{left_type}' type but right side has '{right_type}' type"))]
DataTypeMismatch {
left_type: String,
right_type: String,
},
#[snafu(display("Columns have different lengths: {len_a} != {len_b}"))]
DifferentColumnLength {
len_a: usize,
len_b: usize,
},
#[snafu(display("Multiple result columns with the same alias '{alias}' have been found."))]
DuplicateResultAlias {
alias: String,
},
#[snafu(display(
"A WHERE clause must has boolean type. It is currently of type '{datatype}'."
))]
NonbooleanWhereClause {
datatype: ColumnType,
},
#[snafu(display(
"Invalid order by: alias '{alias}' does not appear in the result expressions."
))]
InvalidOrderBy {
alias: String,
},
#[snafu(display(
"Invalid group by: column '{column}' must appear in the group by expression."
))]
InvalidGroupByColumnRef {
column: String,
},
#[snafu(display("Invalid expression: {expression}"))]
InvalidExpression {
expression: String,
},
#[snafu(display("Encountered parsing error: {error}"))]
ParseError {
error: String,
},
#[snafu(transparent)]
DecimalConversionError {
source: DecimalError,
},
#[snafu(context(false), display("Timestamp conversion error: {source}"))]
TimestampConversionError {
source: PoSQLTimestampError,
},
#[snafu(transparent)]
ColumnOperationError {
source: ColumnOperationError,
},
#[snafu(transparent)]
PostprocessingError {
source: crate::sql::postprocessing::PostprocessingError,
},
#[snafu(display("Query not provable because: {error}"))]
Unprovable {
error: String,
},
}
impl From<String> for ConversionError {
fn from(value: String) -> Self {
ConversionError::ParseError { error: value }
}
}
impl From<ConversionError> for String {
fn from(error: ConversionError) -> Self {
error.to_string()
}
}
impl From<IntermediateDecimalError> for ConversionError {
fn from(err: IntermediateDecimalError) -> ConversionError {
ConversionError::DecimalConversionError {
source: DecimalError::IntermediateDecimalConversionError { source: err },
}
}
}
impl ConversionError {
pub fn non_numeric_expr_in_agg<S: Into<String>>(dtype: S, func: S) -> Self {
ConversionError::InvalidExpression {
expression: format!(
"cannot use expression of type '{}' with numeric aggregation function '{}'",
dtype.into().to_lowercase(),
func.into().to_lowercase()
),
}
}
}
pub type ConversionResult<T> = Result<T, ConversionError>;