1use std::any::Any;
16
17use common_error::ext::ErrorExt;
18use common_error::status_code::StatusCode;
19use common_macro::stack_trace_debug;
20use common_time::timestamp::TimeUnit;
21use common_time::Timestamp;
22use datafusion_common::DataFusionError;
23use datafusion_sql::sqlparser::ast::UnaryOperator;
24use datatypes::prelude::{ConcreteDataType, Value};
25use snafu::{Location, Snafu};
26use sqlparser::ast::Ident;
27use sqlparser::parser::ParserError;
28
29use crate::ast::{Expr, Value as SqlValue};
30use crate::parsers::error::TQLError;
31
32pub type Result<T> = std::result::Result<T, Error>;
33
34#[derive(Snafu)]
38#[snafu(visibility(pub))]
39#[stack_trace_debug]
40pub enum Error {
41 #[snafu(display("SQL statement is not supported, keyword: {}", keyword))]
42 Unsupported {
43 keyword: String,
44 #[snafu(implicit)]
45 location: Location,
46 },
47
48 #[snafu(display(
49 "Unexpected token while parsing SQL statement, expected: '{}', found: {}",
50 expected,
51 actual,
52 ))]
53 Unexpected {
54 expected: String,
55 actual: String,
56 #[snafu(source)]
57 error: ParserError,
58 #[snafu(implicit)]
59 location: Location,
60 },
61
62 #[snafu(display(
63 "Unsupported expr in default constraint: {:?} for column: {}",
64 expr,
65 column_name
66 ))]
67 UnsupportedDefaultValue {
68 column_name: String,
69 expr: Expr,
70 #[snafu(implicit)]
71 location: Location,
72 },
73
74 #[snafu(display("Invalid SQL syntax"))]
76 Syntax {
77 #[snafu(source)]
78 error: ParserError,
79 #[snafu(implicit)]
80 location: Location,
81 },
82
83 #[snafu(display("Invalid TQL syntax"))]
85 TQLSyntax {
86 #[snafu(source)]
87 error: TQLError,
88 #[snafu(implicit)]
89 location: Location,
90 },
91
92 #[snafu(display("Missing time index constraint"))]
93 MissingTimeIndex {},
94
95 #[snafu(display("Invalid time index: {}", msg))]
96 InvalidTimeIndex {
97 msg: String,
98 #[snafu(implicit)]
99 location: Location,
100 },
101
102 #[snafu(display("Invalid SQL, error: {}", msg))]
103 InvalidSql {
104 msg: String,
105 #[snafu(implicit)]
106 location: Location,
107 },
108
109 #[snafu(display(
110 "Unexpected token while parsing SQL statement, expected: '{}', found: {}",
111 expected,
112 actual,
113 ))]
114 UnexpectedToken {
115 expected: String,
116 actual: String,
117 #[snafu(implicit)]
118 location: Location,
119 },
120
121 #[snafu(display("Invalid column option, column name: {}, error: {}", name, msg))]
122 InvalidColumnOption {
123 name: String,
124 msg: String,
125 #[snafu(implicit)]
126 location: Location,
127 },
128
129 #[snafu(display("SQL data type not supported yet: {:?}", t))]
130 SqlTypeNotSupported {
131 t: crate::ast::DataType,
132 #[snafu(implicit)]
133 location: Location,
134 },
135 #[snafu(display("ConcreteDataType not supported yet: {:?}", t))]
136 ConcreteTypeNotSupported {
137 t: ConcreteDataType,
138 #[snafu(implicit)]
139 location: Location,
140 },
141
142 #[snafu(display("Failed to parse value: {}", msg))]
143 ParseSqlValue {
144 msg: String,
145 #[snafu(implicit)]
146 location: Location,
147 },
148
149 #[snafu(display(
150 "Column {} expect type: {:?}, actual: {:?}",
151 column_name,
152 expect,
153 actual,
154 ))]
155 ColumnTypeMismatch {
156 column_name: String,
157 expect: ConcreteDataType,
158 actual: ConcreteDataType,
159 #[snafu(implicit)]
160 location: Location,
161 },
162
163 #[snafu(display("Invalid database name: {}", name))]
164 InvalidDatabaseName {
165 name: String,
166 #[snafu(implicit)]
167 location: Location,
168 },
169
170 #[snafu(display("Invalid interval provided: {}", reason))]
171 InvalidInterval {
172 reason: String,
173 #[snafu(implicit)]
174 location: Location,
175 },
176
177 #[snafu(display("Unrecognized database option key: {}", key))]
178 InvalidDatabaseOption {
179 key: String,
180 #[snafu(implicit)]
181 location: Location,
182 },
183
184 #[snafu(display("Invalid table name: {}", name))]
185 InvalidTableName {
186 name: String,
187 #[snafu(implicit)]
188 location: Location,
189 },
190
191 #[snafu(display("Invalid flow name: {}", name))]
192 InvalidFlowName {
193 name: String,
194 #[snafu(implicit)]
195 location: Location,
196 },
197
198 #[snafu(display("Invalid default constraint, column: {}", column))]
199 InvalidDefault {
200 column: String,
201 #[snafu(implicit)]
202 location: Location,
203 source: datatypes::error::Error,
204 },
205
206 #[snafu(display("Failed to cast SQL value {} to datatype {}", sql_value, datatype))]
207 InvalidCast {
208 sql_value: sqlparser::ast::Value,
209 datatype: ConcreteDataType,
210 #[snafu(implicit)]
211 location: Location,
212 source: datatypes::error::Error,
213 },
214
215 #[snafu(display("Invalid unary operator {} for value {}", unary_op, value))]
216 InvalidUnaryOp {
217 unary_op: UnaryOperator,
218 value: Value,
219 #[snafu(implicit)]
220 location: Location,
221 },
222
223 #[snafu(display("Unsupported unary operator {}", unary_op))]
224 UnsupportedUnaryOp {
225 unary_op: UnaryOperator,
226 #[snafu(implicit)]
227 location: Location,
228 },
229
230 #[snafu(display("Unrecognized table option key: {}", key))]
231 InvalidTableOption {
232 key: String,
233 #[snafu(implicit)]
234 location: Location,
235 },
236
237 #[snafu(display("Unrecognized table option key: {}, value: {}", key, value))]
238 InvalidTableOptionValue {
239 key: Ident,
240 value: Expr,
241 #[snafu(implicit)]
242 location: Location,
243 },
244
245 #[snafu(display("Failed to serialize column default constraint"))]
246 SerializeColumnDefaultConstraint {
247 #[snafu(implicit)]
248 location: Location,
249 source: datatypes::error::Error,
250 },
251
252 #[snafu(display("Failed to convert data type to gRPC data type defined in proto"))]
253 ConvertToGrpcDataType {
254 #[snafu(implicit)]
255 location: Location,
256 source: api::error::Error,
257 },
258
259 #[snafu(display("Invalid sql value: {}", value))]
260 InvalidSqlValue {
261 value: String,
262 #[snafu(implicit)]
263 location: Location,
264 },
265
266 #[snafu(display(
267 "Converting timestamp {:?} to unit {:?} overflow",
268 timestamp,
269 target_unit
270 ))]
271 TimestampOverflow {
272 timestamp: Timestamp,
273 target_unit: TimeUnit,
274 #[snafu(implicit)]
275 location: Location,
276 },
277
278 #[snafu(display("Unable to convert statement {} to DataFusion statement", statement))]
279 ConvertToDfStatement {
280 statement: String,
281 #[snafu(implicit)]
282 location: Location,
283 },
284
285 #[snafu(display("Unable to convert sql value {} to datatype {:?}", value, datatype))]
286 ConvertSqlValue {
287 value: SqlValue,
288 datatype: ConcreteDataType,
289 #[snafu(implicit)]
290 location: Location,
291 },
292
293 #[snafu(display("Unable to convert value {} to sql value", value))]
294 ConvertValue {
295 value: Value,
296 #[snafu(implicit)]
297 location: Location,
298 },
299
300 #[snafu(display("Failed to convert to logical TQL expression"))]
301 ConvertToLogicalExpression {
302 #[snafu(source)]
303 error: DataFusionError,
304 #[snafu(implicit)]
305 location: Location,
306 },
307
308 #[snafu(display("Failed to simplify TQL expression"))]
309 Simplification {
310 #[snafu(source)]
311 error: DataFusionError,
312 #[snafu(implicit)]
313 location: Location,
314 },
315
316 #[snafu(display(
317 "Permission denied while operating catalog {} from current catalog {}",
318 target,
319 current
320 ))]
321 PermissionDenied {
322 target: String,
323 current: String,
324 #[snafu(implicit)]
325 location: Location,
326 },
327
328 #[snafu(display("Failed to set fulltext option"))]
329 SetFulltextOption {
330 source: datatypes::error::Error,
331 #[snafu(implicit)]
332 location: Location,
333 },
334
335 #[snafu(display("Failed to set SKIPPING index option"))]
336 SetSkippingIndexOption {
337 source: datatypes::error::Error,
338 #[snafu(implicit)]
339 location: Location,
340 },
341
342 #[snafu(display("Datatype error: {}", source))]
343 Datatype {
344 source: datatypes::error::Error,
345 #[snafu(implicit)]
346 location: Location,
347 },
348
349 #[snafu(display(
350 "Invalid partition number: {}, should be in range [2, 65536]",
351 partition_num
352 ))]
353 InvalidPartitionNumber {
354 partition_num: u32,
355 #[snafu(implicit)]
356 location: Location,
357 },
358
359 #[snafu(display("Unable to convert {} to datatype {:?}", value, datatype))]
360 ConvertStr {
361 value: String,
362 datatype: ConcreteDataType,
363 #[snafu(implicit)]
364 location: Location,
365 },
366}
367
368impl ErrorExt for Error {
369 fn status_code(&self) -> StatusCode {
370 use Error::*;
371
372 match self {
373 UnsupportedDefaultValue { .. } | Unsupported { .. } => StatusCode::Unsupported,
374 Unexpected { .. }
375 | Syntax { .. }
376 | TQLSyntax { .. }
377 | MissingTimeIndex { .. }
378 | InvalidTimeIndex { .. }
379 | InvalidSql { .. }
380 | ParseSqlValue { .. }
381 | SqlTypeNotSupported { .. }
382 | ConcreteTypeNotSupported { .. }
383 | UnexpectedToken { .. }
384 | InvalidDefault { .. } => StatusCode::InvalidSyntax,
385
386 InvalidColumnOption { .. }
387 | InvalidTableOptionValue { .. }
388 | InvalidDatabaseName { .. }
389 | InvalidDatabaseOption { .. }
390 | ColumnTypeMismatch { .. }
391 | InvalidTableName { .. }
392 | InvalidFlowName { .. }
393 | InvalidSqlValue { .. }
394 | TimestampOverflow { .. }
395 | InvalidTableOption { .. }
396 | InvalidCast { .. }
397 | ConvertToLogicalExpression { .. }
398 | Simplification { .. }
399 | InvalidInterval { .. }
400 | InvalidUnaryOp { .. }
401 | InvalidPartitionNumber { .. }
402 | UnsupportedUnaryOp { .. }
403 | ConvertStr { .. } => StatusCode::InvalidArguments,
404
405 SerializeColumnDefaultConstraint { source, .. } => source.status_code(),
406 ConvertToGrpcDataType { source, .. } => source.status_code(),
407 Datatype { source, .. } => source.status_code(),
408 ConvertToDfStatement { .. } => StatusCode::Internal,
409 ConvertSqlValue { .. } | ConvertValue { .. } => StatusCode::Unsupported,
410
411 PermissionDenied { .. } => StatusCode::PermissionDenied,
412 SetFulltextOption { .. } | SetSkippingIndexOption { .. } => StatusCode::Unexpected,
413 }
414 }
415
416 fn as_any(&self) -> &dyn Any {
417 self
418 }
419}