1use std::any::Any;
16
17use api::v1::ColumnDataType;
18use common_error::ext::ErrorExt;
19use common_error::status_code::StatusCode;
20use common_macro::stack_trace_debug;
21use snafu::{Location, Snafu};
22use store_api::metadata::MetadataError;
23
24#[derive(Snafu)]
25#[snafu(visibility(pub))]
26#[stack_trace_debug]
27pub enum Error {
28 #[snafu(display("Column datatype error"))]
29 ColumnDataType {
30 #[snafu(implicit)]
31 location: Location,
32 source: api::error::Error,
33 },
34
35 #[snafu(display(
36 "Duplicated timestamp column in gRPC requests, exists {}, duplicated: {}",
37 exists,
38 duplicated
39 ))]
40 DuplicatedTimestampColumn {
41 exists: String,
42 duplicated: String,
43 #[snafu(implicit)]
44 location: Location,
45 },
46
47 #[snafu(display("Duplicated column name in gRPC requests, name: {}", name,))]
48 DuplicatedColumnName {
49 name: String,
50 #[snafu(implicit)]
51 location: Location,
52 },
53
54 #[snafu(display("Missing timestamp column, msg: {}", msg))]
55 MissingTimestampColumn {
56 msg: String,
57 #[snafu(implicit)]
58 location: Location,
59 },
60
61 #[snafu(display("Missing required field in protobuf, field: {}", field))]
62 MissingField {
63 field: String,
64 #[snafu(implicit)]
65 location: Location,
66 },
67
68 #[snafu(display("Invalid column proto definition, column: {}", column))]
69 InvalidColumnDef {
70 column: String,
71 #[snafu(implicit)]
72 location: Location,
73 source: api::error::Error,
74 },
75
76 #[snafu(display("Invalid JSON settings: {}", err))]
77 InvalidJsonSettings {
78 err: String,
79 #[snafu(implicit)]
80 location: Location,
81 },
82
83 #[snafu(display("Unknown location type: {}", location_type))]
84 UnknownLocationType {
85 location_type: i32,
86 #[snafu(implicit)]
87 location: Location,
88 },
89
90 #[snafu(display("Unknown proto column datatype: {}", datatype))]
91 UnknownColumnDataType {
92 datatype: i32,
93 #[snafu(implicit)]
94 location: Location,
95 #[snafu(source)]
96 error: prost::UnknownEnumValue,
97 },
98
99 #[snafu(display(
100 "Fulltext index only supports string type, column: {column_name}, unexpected type: {column_type:?}"
101 ))]
102 InvalidFulltextIndexColumnType {
103 column_name: String,
104 column_type: ColumnDataType,
105 #[snafu(implicit)]
106 location: Location,
107 },
108
109 #[snafu(display("Invalid set table option request"))]
110 InvalidSetTableOptionRequest {
111 #[snafu(source)]
112 error: MetadataError,
113 },
114
115 #[snafu(display("Invalid unset table option request"))]
116 InvalidUnsetTableOptionRequest {
117 #[snafu(source)]
118 error: MetadataError,
119 },
120
121 #[snafu(display("Invalid table option request: {err_msg}"))]
122 InvalidTableOptionRequest {
123 err_msg: String,
124 #[snafu(implicit)]
125 location: Location,
126 },
127
128 #[snafu(display("Invalid set fulltext option request"))]
129 InvalidSetFulltextOptionRequest {
130 #[snafu(implicit)]
131 location: Location,
132 #[snafu(source)]
133 error: prost::UnknownEnumValue,
134 },
135
136 #[snafu(display("Invalid set skipping index option request"))]
137 InvalidSetSkippingIndexOptionRequest {
138 #[snafu(implicit)]
139 location: Location,
140 #[snafu(source)]
141 error: prost::UnknownEnumValue,
142 },
143
144 #[snafu(display("Missing alter index options"))]
145 MissingAlterIndexOption {
146 #[snafu(implicit)]
147 location: Location,
148 },
149
150 #[snafu(display("Invalid index option"))]
151 InvalidIndexOption {
152 #[snafu(implicit)]
153 location: Location,
154 #[snafu(source)]
155 error: datatypes::error::Error,
156 },
157
158 #[snafu(display("Sql common error"))]
159 SqlCommon {
160 source: common_sql::error::Error,
161 #[snafu(implicit)]
162 location: Location,
163 },
164
165 #[snafu(display("Missing required field in protobuf, column name: {}", column_name))]
166 ColumnNotFound {
167 column_name: String,
168 #[snafu(implicit)]
169 location: Location,
170 },
171
172 #[snafu(display("Need table metadata, but not found, table_id: {}", table_id))]
173 MissingTableMeta {
174 table_id: u32,
175 #[snafu(implicit)]
176 location: Location,
177 },
178
179 #[snafu(display("Unexpected: {err_msg}"))]
180 Unexpected {
181 err_msg: String,
182 #[snafu(implicit)]
183 location: Location,
184 },
185}
186
187pub type Result<T> = std::result::Result<T, Error>;
188
189impl ErrorExt for Error {
190 fn status_code(&self) -> StatusCode {
191 match self {
192 Error::ColumnDataType { .. } => StatusCode::Internal,
193 Error::DuplicatedTimestampColumn { .. }
194 | Error::DuplicatedColumnName { .. }
195 | Error::MissingTimestampColumn { .. } => StatusCode::InvalidArguments,
196 Error::MissingField { .. } => StatusCode::InvalidArguments,
197 Error::InvalidColumnDef { source, .. } => source.status_code(),
198 Error::InvalidJsonSettings { .. } => StatusCode::InvalidArguments,
199 Error::UnknownLocationType { .. } => StatusCode::InvalidArguments,
200
201 Error::UnknownColumnDataType { .. } | Error::InvalidFulltextIndexColumnType { .. } => {
202 StatusCode::InvalidArguments
203 }
204 Error::InvalidSetTableOptionRequest { .. }
205 | Error::InvalidUnsetTableOptionRequest { .. }
206 | Error::InvalidTableOptionRequest { .. }
207 | Error::InvalidSetFulltextOptionRequest { .. }
208 | Error::InvalidSetSkippingIndexOptionRequest { .. }
209 | Error::MissingAlterIndexOption { .. }
210 | Error::InvalidIndexOption { .. } => StatusCode::InvalidArguments,
211 Error::ColumnNotFound { .. } => StatusCode::TableColumnNotFound,
212 Error::SqlCommon { source, .. } => source.status_code(),
213 Error::MissingTableMeta { .. } => StatusCode::Unexpected,
214 Error::Unexpected { .. } => StatusCode::Unexpected,
215 }
216 }
217
218 fn as_any(&self) -> &dyn Any {
219 self
220 }
221}