use crate::ast::Span;
use thiserror::Error;
#[derive(Debug, Clone, PartialEq, Eq, Error)]
pub enum PlannerError {
#[error("error[ALOPEX-C001]: table '{name}' not found at line {line}, column {column}")]
TableNotFound {
name: String,
line: u64,
column: u64,
},
#[error("error[ALOPEX-C002]: table '{name}' already exists")]
TableAlreadyExists { name: String },
#[error(
"error[ALOPEX-C003]: column '{column}' not found in table '{table}' at line {line}, column {col}"
)]
ColumnNotFound {
column: String,
table: String,
line: u64,
col: u64,
},
#[error(
"error[ALOPEX-C004]: ambiguous column '{column}' found in tables: {tables:?} at line {line}, column {col}"
)]
AmbiguousColumn {
column: String,
tables: Vec<String>,
line: u64,
col: u64,
},
#[error("error[ALOPEX-C005]: index '{name}' already exists")]
IndexAlreadyExists { name: String },
#[error("error[ALOPEX-C006]: index '{name}' not found")]
IndexNotFound { name: String },
#[error(
"error[ALOPEX-T001]: type mismatch at line {line}, column {column}: expected {expected}, found {found}"
)]
TypeMismatch {
expected: String,
found: String,
line: u64,
column: u64,
},
#[error(
"error[ALOPEX-T002]: invalid operator '{op}' for type '{type_name}' at line {line}, column {column}"
)]
InvalidOperator {
op: String,
type_name: String,
line: u64,
column: u64,
},
#[error(
"error[ALOPEX-T003]: null constraint violation for column '{column}' at line {line}, column {col}"
)]
NullConstraintViolation { column: String, line: u64, col: u64 },
#[error(
"error[ALOPEX-T004]: vector dimension mismatch at line {line}, column {column}: expected {expected}, found {found}"
)]
VectorDimensionMismatch {
expected: u32,
found: u32,
line: u64,
column: u64,
},
#[error(
"error[ALOPEX-T005]: invalid metric '{value}' at line {line}, column {column}. Valid options: cosine, l2, inner"
)]
InvalidMetric {
value: String,
line: u64,
column: u64,
},
#[error(
"error[ALOPEX-T006]: column count ({columns}) does not match value count ({values}) at line {line}, column {column}"
)]
ColumnValueCountMismatch {
columns: usize,
values: usize,
line: u64,
column: u64,
},
#[error("error[ALOPEX-T007]: invalid expression: {message}")]
InvalidExpression { message: String },
#[error(
"error[ALOPEX-F001]: feature '{feature}' is not supported in this version. Expected in {version}"
)]
UnsupportedFeature {
feature: String,
version: String,
line: u64,
column: u64,
},
}
impl PlannerError {
pub fn table_not_found(name: impl Into<String>, span: Span) -> Self {
Self::TableNotFound {
name: name.into(),
line: span.start.line,
column: span.start.column,
}
}
pub fn table_already_exists(name: impl Into<String>) -> Self {
Self::TableAlreadyExists { name: name.into() }
}
pub fn column_not_found(
column: impl Into<String>,
table: impl Into<String>,
span: Span,
) -> Self {
Self::ColumnNotFound {
column: column.into(),
table: table.into(),
line: span.start.line,
col: span.start.column,
}
}
pub fn ambiguous_column(column: impl Into<String>, tables: Vec<String>, span: Span) -> Self {
Self::AmbiguousColumn {
column: column.into(),
tables,
line: span.start.line,
col: span.start.column,
}
}
pub fn index_already_exists(name: impl Into<String>) -> Self {
Self::IndexAlreadyExists { name: name.into() }
}
pub fn index_not_found(name: impl Into<String>) -> Self {
Self::IndexNotFound { name: name.into() }
}
pub fn type_mismatch(
expected: impl Into<String>,
found: impl Into<String>,
span: Span,
) -> Self {
Self::TypeMismatch {
expected: expected.into(),
found: found.into(),
line: span.start.line,
column: span.start.column,
}
}
pub fn invalid_expression(message: impl Into<String>) -> Self {
Self::InvalidExpression {
message: message.into(),
}
}
pub fn invalid_operator(
op: impl Into<String>,
type_name: impl Into<String>,
span: Span,
) -> Self {
Self::InvalidOperator {
op: op.into(),
type_name: type_name.into(),
line: span.start.line,
column: span.start.column,
}
}
pub fn null_constraint_violation(column: impl Into<String>, span: Span) -> Self {
Self::NullConstraintViolation {
column: column.into(),
line: span.start.line,
col: span.start.column,
}
}
pub fn vector_dimension_mismatch(expected: u32, found: u32, span: Span) -> Self {
Self::VectorDimensionMismatch {
expected,
found,
line: span.start.line,
column: span.start.column,
}
}
pub fn invalid_metric(value: impl Into<String>, span: Span) -> Self {
Self::InvalidMetric {
value: value.into(),
line: span.start.line,
column: span.start.column,
}
}
pub fn column_value_count_mismatch(columns: usize, values: usize, span: Span) -> Self {
Self::ColumnValueCountMismatch {
columns,
values,
line: span.start.line,
column: span.start.column,
}
}
pub fn unsupported_feature(
feature: impl Into<String>,
version: impl Into<String>,
span: Span,
) -> Self {
Self::UnsupportedFeature {
feature: feature.into(),
version: version.into(),
line: span.start.line,
column: span.start.column,
}
}
}