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_sql::sqlparser::ast::UnaryOperator;
23use datatypes::prelude::{ConcreteDataType, Value};
24use snafu::{Location, Snafu};
25pub use sqlparser::ast::{Expr, Value as SqlValue};
26
27pub type Result<T> = std::result::Result<T, Error>;
28
29#[derive(Snafu)]
33#[snafu(visibility(pub))]
34#[stack_trace_debug]
35pub enum Error {
36 #[snafu(display(
37 "Column {} expect type: {:?}, actual: {:?}",
38 column_name,
39 expect,
40 actual,
41 ))]
42 ColumnTypeMismatch {
43 column_name: String,
44 expect: ConcreteDataType,
45 actual: ConcreteDataType,
46 #[snafu(implicit)]
47 location: Location,
48 },
49
50 #[snafu(display("Failed to parse value: {}", msg))]
51 ParseSqlValue {
52 msg: String,
53 #[snafu(implicit)]
54 location: Location,
55 },
56
57 #[snafu(display(
58 "Unsupported expr in default constraint: {:?} for column: {}",
59 expr,
60 column_name
61 ))]
62 UnsupportedDefaultValue {
63 column_name: String,
64 expr: Expr,
65 #[snafu(implicit)]
66 location: Location,
67 },
68
69 #[snafu(display("Unable to convert sql value {} to datatype {:?}", value, datatype))]
70 ConvertSqlValue {
71 value: SqlValue,
72 datatype: ConcreteDataType,
73 #[snafu(implicit)]
74 location: Location,
75 },
76
77 #[snafu(display("Invalid sql value: {}", value))]
78 InvalidSqlValue {
79 value: String,
80 #[snafu(implicit)]
81 location: Location,
82 },
83
84 #[snafu(display("Unsupported unary operator {}", unary_op))]
85 UnsupportedUnaryOp {
86 unary_op: UnaryOperator,
87 #[snafu(implicit)]
88 location: Location,
89 },
90
91 #[snafu(display("Invalid unary operator {} for value {}", unary_op, value))]
92 InvalidUnaryOp {
93 unary_op: UnaryOperator,
94 value: Value,
95 #[snafu(implicit)]
96 location: Location,
97 },
98
99 #[snafu(display("Failed to cast SQL value {} to datatype {}", sql_value, datatype))]
100 InvalidCast {
101 sql_value: sqlparser::ast::Value,
102 datatype: ConcreteDataType,
103 #[snafu(implicit)]
104 location: Location,
105 source: datatypes::error::Error,
106 },
107
108 #[snafu(display("Unable to convert {} to datatype {:?}", value, datatype))]
109 ConvertStr {
110 value: String,
111 datatype: ConcreteDataType,
112 #[snafu(implicit)]
113 location: Location,
114 },
115
116 #[snafu(display(
117 "Converting timestamp {:?} to unit {:?} overflow",
118 timestamp,
119 target_unit
120 ))]
121 TimestampOverflow {
122 timestamp: Timestamp,
123 target_unit: TimeUnit,
124 #[snafu(implicit)]
125 location: Location,
126 },
127
128 #[snafu(display("Datatype error: {}", source))]
129 Datatype {
130 source: datatypes::error::Error,
131 #[snafu(implicit)]
132 location: Location,
133 },
134}
135
136impl ErrorExt for Error {
137 fn status_code(&self) -> StatusCode {
138 use Error::*;
139
140 match self {
141 UnsupportedDefaultValue { .. } => StatusCode::Unsupported,
142 ParseSqlValue { .. } => StatusCode::InvalidSyntax,
143 ColumnTypeMismatch { .. }
144 | InvalidSqlValue { .. }
145 | UnsupportedUnaryOp { .. }
146 | InvalidUnaryOp { .. }
147 | InvalidCast { .. }
148 | ConvertStr { .. }
149 | TimestampOverflow { .. } => StatusCode::InvalidArguments,
150 Datatype { source, .. } => source.status_code(),
151 ConvertSqlValue { .. } => StatusCode::Unsupported,
152 }
153 }
154
155 fn as_any(&self) -> &dyn Any {
156 self
157 }
158}