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("Unknown location type: {}", location_type))]
77 UnknownLocationType {
78 location_type: i32,
79 #[snafu(implicit)]
80 location: Location,
81 },
82
83 #[snafu(display("Unknown proto column datatype: {}", datatype))]
84 UnknownColumnDataType {
85 datatype: i32,
86 #[snafu(implicit)]
87 location: Location,
88 #[snafu(source)]
89 error: prost::UnknownEnumValue,
90 },
91
92 #[snafu(display(
93 "Fulltext or Skipping index only supports string type, column: {column_name}, unexpected type: {column_type:?}"
94 ))]
95 InvalidStringIndexColumnType {
96 column_name: String,
97 column_type: ColumnDataType,
98 #[snafu(implicit)]
99 location: Location,
100 },
101
102 #[snafu(display("Invalid set table option request"))]
103 InvalidSetTableOptionRequest {
104 #[snafu(source)]
105 error: MetadataError,
106 },
107
108 #[snafu(display("Invalid unset table option request"))]
109 InvalidUnsetTableOptionRequest {
110 #[snafu(source)]
111 error: MetadataError,
112 },
113
114 #[snafu(display("Invalid set fulltext option request"))]
115 InvalidSetFulltextOptionRequest {
116 #[snafu(implicit)]
117 location: Location,
118 #[snafu(source)]
119 error: prost::UnknownEnumValue,
120 },
121
122 #[snafu(display("Invalid set skipping index option request"))]
123 InvalidSetSkippingIndexOptionRequest {
124 #[snafu(implicit)]
125 location: Location,
126 #[snafu(source)]
127 error: prost::UnknownEnumValue,
128 },
129
130 #[snafu(display("Missing alter index options"))]
131 MissingAlterIndexOption {
132 #[snafu(implicit)]
133 location: Location,
134 },
135
136 #[snafu(display("Invalid index option"))]
137 InvalidIndexOption {
138 #[snafu(implicit)]
139 location: Location,
140 #[snafu(source)]
141 error: datatypes::error::Error,
142 },
143
144 #[snafu(display("Sql common error"))]
145 SqlCommon {
146 source: common_sql::error::Error,
147 #[snafu(implicit)]
148 location: Location,
149 },
150
151 #[snafu(display("Missing required field in protobuf, column name: {}", column_name))]
152 ColumnNotFound {
153 column_name: String,
154 #[snafu(implicit)]
155 location: Location,
156 },
157
158 #[snafu(display("Need table metadata, but not found, table_id: {}", table_id))]
159 MissingTableMeta {
160 table_id: u32,
161 #[snafu(implicit)]
162 location: Location,
163 },
164}
165
166pub type Result<T> = std::result::Result<T, Error>;
167
168impl ErrorExt for Error {
169 fn status_code(&self) -> StatusCode {
170 match self {
171 Error::ColumnDataType { .. } => StatusCode::Internal,
172 Error::DuplicatedTimestampColumn { .. }
173 | Error::DuplicatedColumnName { .. }
174 | Error::MissingTimestampColumn { .. } => StatusCode::InvalidArguments,
175 Error::MissingField { .. } => StatusCode::InvalidArguments,
176 Error::InvalidColumnDef { source, .. } => source.status_code(),
177 Error::UnknownLocationType { .. } => StatusCode::InvalidArguments,
178
179 Error::UnknownColumnDataType { .. } | Error::InvalidStringIndexColumnType { .. } => {
180 StatusCode::InvalidArguments
181 }
182 Error::InvalidSetTableOptionRequest { .. }
183 | Error::InvalidUnsetTableOptionRequest { .. }
184 | Error::InvalidSetFulltextOptionRequest { .. }
185 | Error::InvalidSetSkippingIndexOptionRequest { .. }
186 | Error::MissingAlterIndexOption { .. }
187 | Error::InvalidIndexOption { .. } => StatusCode::InvalidArguments,
188 Error::ColumnNotFound { .. } => StatusCode::TableColumnNotFound,
189 Error::SqlCommon { source, .. } => source.status_code(),
190 Error::MissingTableMeta { .. } => StatusCode::Unexpected,
191 }
192 }
193
194 fn as_any(&self) -> &dyn Any {
195 self
196 }
197}