1use crate::ast::Span;
9use thiserror::Error;
10
11#[derive(Debug, Clone, PartialEq, Eq, Error)]
13pub enum PlannerError {
14 #[error("error[ALOPEX-C001]: table '{name}' not found at line {line}, column {column}")]
17 TableNotFound {
18 name: String,
19 line: u64,
20 column: u64,
21 },
22
23 #[error("error[ALOPEX-C002]: table '{name}' already exists")]
25 TableAlreadyExists { name: String },
26
27 #[error(
29 "error[ALOPEX-C003]: column '{column}' not found in table '{table}' at line {line}, column {col}"
30 )]
31 ColumnNotFound {
32 column: String,
33 table: String,
34 line: u64,
35 col: u64,
36 },
37
38 #[error(
40 "error[ALOPEX-C004]: ambiguous column '{column}' found in tables: {tables:?} at line {line}, column {col}"
41 )]
42 AmbiguousColumn {
43 column: String,
44 tables: Vec<String>,
45 line: u64,
46 col: u64,
47 },
48
49 #[error("error[ALOPEX-C005]: index '{name}' already exists")]
51 IndexAlreadyExists { name: String },
52
53 #[error("error[ALOPEX-C006]: index '{name}' not found")]
55 IndexNotFound { name: String },
56
57 #[error(
60 "error[ALOPEX-T001]: type mismatch at line {line}, column {column}: expected {expected}, found {found}"
61 )]
62 TypeMismatch {
63 expected: String,
64 found: String,
65 line: u64,
66 column: u64,
67 },
68
69 #[error(
71 "error[ALOPEX-T002]: invalid operator '{op}' for type '{type_name}' at line {line}, column {column}"
72 )]
73 InvalidOperator {
74 op: String,
75 type_name: String,
76 line: u64,
77 column: u64,
78 },
79
80 #[error(
82 "error[ALOPEX-T003]: null constraint violation for column '{column}' at line {line}, column {col}"
83 )]
84 NullConstraintViolation { column: String, line: u64, col: u64 },
85
86 #[error(
88 "error[ALOPEX-T004]: vector dimension mismatch at line {line}, column {column}: expected {expected}, found {found}"
89 )]
90 VectorDimensionMismatch {
91 expected: u32,
92 found: u32,
93 line: u64,
94 column: u64,
95 },
96
97 #[error(
99 "error[ALOPEX-T005]: invalid metric '{value}' at line {line}, column {column}. Valid options: cosine, l2, inner"
100 )]
101 InvalidMetric {
102 value: String,
103 line: u64,
104 column: u64,
105 },
106
107 #[error(
109 "error[ALOPEX-T006]: column count ({columns}) does not match value count ({values}) at line {line}, column {column}"
110 )]
111 ColumnValueCountMismatch {
112 columns: usize,
113 values: usize,
114 line: u64,
115 column: u64,
116 },
117
118 #[error("error[ALOPEX-T007]: invalid expression: {message}")]
120 InvalidExpression { message: String },
121
122 #[error(
125 "error[ALOPEX-F001]: feature '{feature}' is not supported in this version. Expected in {version}"
126 )]
127 UnsupportedFeature {
128 feature: String,
129 version: String,
130 line: u64,
131 column: u64,
132 },
133}
134
135impl PlannerError {
136 pub fn table_not_found(name: impl Into<String>, span: Span) -> Self {
138 Self::TableNotFound {
139 name: name.into(),
140 line: span.start.line,
141 column: span.start.column,
142 }
143 }
144
145 pub fn table_already_exists(name: impl Into<String>) -> Self {
147 Self::TableAlreadyExists { name: name.into() }
148 }
149
150 pub fn column_not_found(
152 column: impl Into<String>,
153 table: impl Into<String>,
154 span: Span,
155 ) -> Self {
156 Self::ColumnNotFound {
157 column: column.into(),
158 table: table.into(),
159 line: span.start.line,
160 col: span.start.column,
161 }
162 }
163
164 pub fn ambiguous_column(column: impl Into<String>, tables: Vec<String>, span: Span) -> Self {
166 Self::AmbiguousColumn {
167 column: column.into(),
168 tables,
169 line: span.start.line,
170 col: span.start.column,
171 }
172 }
173
174 pub fn index_already_exists(name: impl Into<String>) -> Self {
176 Self::IndexAlreadyExists { name: name.into() }
177 }
178
179 pub fn index_not_found(name: impl Into<String>) -> Self {
181 Self::IndexNotFound { name: name.into() }
182 }
183
184 pub fn type_mismatch(
186 expected: impl Into<String>,
187 found: impl Into<String>,
188 span: Span,
189 ) -> Self {
190 Self::TypeMismatch {
191 expected: expected.into(),
192 found: found.into(),
193 line: span.start.line,
194 column: span.start.column,
195 }
196 }
197
198 pub fn invalid_expression(message: impl Into<String>) -> Self {
200 Self::InvalidExpression {
201 message: message.into(),
202 }
203 }
204
205 pub fn invalid_operator(
207 op: impl Into<String>,
208 type_name: impl Into<String>,
209 span: Span,
210 ) -> Self {
211 Self::InvalidOperator {
212 op: op.into(),
213 type_name: type_name.into(),
214 line: span.start.line,
215 column: span.start.column,
216 }
217 }
218
219 pub fn null_constraint_violation(column: impl Into<String>, span: Span) -> Self {
221 Self::NullConstraintViolation {
222 column: column.into(),
223 line: span.start.line,
224 col: span.start.column,
225 }
226 }
227
228 pub fn vector_dimension_mismatch(expected: u32, found: u32, span: Span) -> Self {
230 Self::VectorDimensionMismatch {
231 expected,
232 found,
233 line: span.start.line,
234 column: span.start.column,
235 }
236 }
237
238 pub fn invalid_metric(value: impl Into<String>, span: Span) -> Self {
240 Self::InvalidMetric {
241 value: value.into(),
242 line: span.start.line,
243 column: span.start.column,
244 }
245 }
246
247 pub fn column_value_count_mismatch(columns: usize, values: usize, span: Span) -> Self {
249 Self::ColumnValueCountMismatch {
250 columns,
251 values,
252 line: span.start.line,
253 column: span.start.column,
254 }
255 }
256
257 pub fn unsupported_feature(
259 feature: impl Into<String>,
260 version: impl Into<String>,
261 span: Span,
262 ) -> Self {
263 Self::UnsupportedFeature {
264 feature: feature.into(),
265 version: version.into(),
266 line: span.start.line,
267 column: span.start.column,
268 }
269 }
270}