index/inverted_index/
error.rs

1// Copyright 2023 Greptime Team
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use std::any::Any;
16use std::io::Error as IoError;
17
18use common_error::ext::{BoxedError, ErrorExt};
19use common_error::status_code::StatusCode;
20use common_macro::stack_trace_debug;
21use snafu::{Location, Snafu};
22
23use crate::inverted_index::search::predicate::Predicate;
24
25#[derive(Snafu)]
26#[snafu(visibility(pub))]
27#[stack_trace_debug]
28pub enum Error {
29    #[snafu(display("Failed to read"))]
30    Read {
31        #[snafu(source)]
32        error: IoError,
33        #[snafu(implicit)]
34        location: Location,
35    },
36
37    #[snafu(display("Failed to write"))]
38    Write {
39        #[snafu(source)]
40        error: IoError,
41        #[snafu(implicit)]
42        location: Location,
43    },
44
45    #[snafu(display("Failed to flush"))]
46    Flush {
47        #[snafu(source)]
48        error: IoError,
49        #[snafu(implicit)]
50        location: Location,
51    },
52
53    #[snafu(display("Failed to close"))]
54    Close {
55        #[snafu(source)]
56        error: IoError,
57        #[snafu(implicit)]
58        location: Location,
59    },
60
61    #[snafu(display(
62        "Unexpected inverted index blob size, min: {min_blob_size}, actual: {actual_blob_size}"
63    ))]
64    UnexpectedBlobSize {
65        min_blob_size: u64,
66        actual_blob_size: u64,
67        #[snafu(implicit)]
68        location: Location,
69    },
70
71    #[snafu(display("Blob size too small"))]
72    BlobSizeTooSmall {
73        #[snafu(implicit)]
74        location: Location,
75    },
76
77    #[snafu(display("Invalid footer payload size"))]
78    InvalidFooterPayloadSize {
79        #[snafu(implicit)]
80        location: Location,
81    },
82
83    #[snafu(display("Unexpected inverted index footer payload size, max: {max_payload_size}, actual: {actual_payload_size}"))]
84    UnexpectedFooterPayloadSize {
85        max_payload_size: u64,
86        actual_payload_size: u64,
87        #[snafu(implicit)]
88        location: Location,
89    },
90
91    #[snafu(display("Unexpected inverted index offset size, offset: {offset}, size: {size}, blob_size: {blob_size}, payload_size: {payload_size}"))]
92    UnexpectedOffsetSize {
93        offset: u64,
94        size: u64,
95        blob_size: u64,
96        payload_size: u64,
97    },
98
99    #[snafu(display("Unexpected zero segment row count"))]
100    UnexpectedZeroSegmentRowCount {
101        #[snafu(implicit)]
102        location: Location,
103    },
104
105    #[snafu(display("Failed to decode fst"))]
106    DecodeFst {
107        #[snafu(source)]
108        error: fst::Error,
109        #[snafu(implicit)]
110        location: Location,
111    },
112
113    #[snafu(display("Failed to decode bitmap"))]
114    DecodeBitmap {
115        #[snafu(source)]
116        error: IoError,
117        #[snafu(implicit)]
118        location: Location,
119    },
120
121    #[snafu(display("Failed to decode protobuf"))]
122    DecodeProto {
123        #[snafu(source)]
124        error: prost::DecodeError,
125        #[snafu(implicit)]
126        location: Location,
127    },
128
129    #[snafu(display("Failed to parse regex pattern: {pattern}"))]
130    ParseRegex {
131        #[snafu(source)]
132        error: regex::Error,
133        pattern: String,
134        #[snafu(implicit)]
135        location: Location,
136    },
137
138    #[snafu(display("Failed to parse regex DFA"))]
139    ParseDFA {
140        #[snafu(source)]
141        error: Box<regex_automata::dfa::dense::BuildError>,
142        #[snafu(implicit)]
143        location: Location,
144    },
145
146    #[snafu(display("Unexpected empty predicates to construct fst applier"))]
147    EmptyPredicates {
148        #[snafu(implicit)]
149        location: Location,
150    },
151
152    #[snafu(display("Failed to construct intersection fst applier with InList predicate"))]
153    IntersectionApplierWithInList {
154        #[snafu(implicit)]
155        location: Location,
156    },
157
158    #[snafu(display("Failed to construct keys fst applier without InList predicate"))]
159    KeysApplierWithoutInList {
160        #[snafu(implicit)]
161        location: Location,
162    },
163
164    #[snafu(display(
165        "Failed to construct keys fst applier with unexpected predicates: {predicates:?}"
166    ))]
167    KeysApplierUnexpectedPredicates {
168        #[snafu(implicit)]
169        location: Location,
170        predicates: Vec<Predicate>,
171    },
172
173    #[snafu(display("index not found, name: {name}"))]
174    IndexNotFound {
175        name: String,
176        #[snafu(implicit)]
177        location: Location,
178    },
179
180    #[snafu(display("Failed to insert value to FST"))]
181    FstInsert {
182        #[snafu(source)]
183        error: fst::Error,
184        #[snafu(implicit)]
185        location: Location,
186    },
187
188    #[snafu(display("Failed to compile FST"))]
189    FstCompile {
190        #[snafu(source)]
191        error: fst::Error,
192        #[snafu(implicit)]
193        location: Location,
194    },
195
196    #[snafu(display("Failed to perform IO operation"))]
197    CommonIo {
198        #[snafu(source)]
199        error: IoError,
200        #[snafu(implicit)]
201        location: Location,
202    },
203
204    #[snafu(display("Unknown intermediate codec magic: {magic:?}"))]
205    UnknownIntermediateCodecMagic {
206        magic: [u8; 4],
207        #[snafu(implicit)]
208        location: Location,
209    },
210
211    #[snafu(display("Inconsistent row count, index_name: {index_name}, total_row_count: {total_row_count}, expected: {expected_row_count}"))]
212    InconsistentRowCount {
213        index_name: String,
214        total_row_count: usize,
215        expected_row_count: usize,
216    },
217
218    #[snafu(display("External error"))]
219    External {
220        source: BoxedError,
221        #[snafu(implicit)]
222        location: Location,
223    },
224
225    #[snafu(display("Intermediate error"))]
226    Intermediate {
227        source: crate::error::Error,
228        #[snafu(implicit)]
229        location: Location,
230    },
231}
232
233impl ErrorExt for Error {
234    fn status_code(&self) -> StatusCode {
235        use Error::*;
236        match self {
237            Read { .. }
238            | Write { .. }
239            | Flush { .. }
240            | Close { .. }
241            | UnexpectedFooterPayloadSize { .. }
242            | UnexpectedZeroSegmentRowCount { .. }
243            | UnexpectedOffsetSize { .. }
244            | UnexpectedBlobSize { .. }
245            | DecodeProto { .. }
246            | DecodeFst { .. }
247            | KeysApplierUnexpectedPredicates { .. }
248            | CommonIo { .. }
249            | UnknownIntermediateCodecMagic { .. }
250            | FstCompile { .. }
251            | DecodeBitmap { .. }
252            | InvalidFooterPayloadSize { .. }
253            | BlobSizeTooSmall { .. } => StatusCode::Unexpected,
254
255            ParseRegex { .. }
256            | ParseDFA { .. }
257            | KeysApplierWithoutInList { .. }
258            | IntersectionApplierWithInList { .. }
259            | EmptyPredicates { .. }
260            | FstInsert { .. }
261            | InconsistentRowCount { .. }
262            | IndexNotFound { .. } => StatusCode::InvalidArguments,
263
264            Intermediate { source, .. } => source.status_code(),
265            External { source, .. } => source.status_code(),
266        }
267    }
268
269    fn as_any(&self) -> &dyn Any {
270        self
271    }
272}
273
274pub type Result<T> = std::result::Result<T, Error>;