Skip to main content

operator/
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::sync::Arc;
17
18use common_datasource::file_format::Format;
19use common_error::define_into_tonic_status;
20use common_error::ext::{BoxedError, ErrorExt, RetryHint};
21use common_error::status_code::StatusCode;
22use common_macro::stack_trace_debug;
23use common_query::error::Error as QueryResult;
24use datafusion::parquet;
25use datafusion_common::DataFusionError;
26use datatypes::arrow::error::ArrowError;
27use object_store::error::retry_hint_from_opendal_error;
28use snafu::{Location, Snafu};
29use table::metadata::TableType;
30
31#[derive(Snafu)]
32#[snafu(visibility(pub))]
33#[stack_trace_debug]
34pub enum Error {
35    #[snafu(display("Table already exists: `{}`", table))]
36    TableAlreadyExists {
37        table: String,
38        #[snafu(implicit)]
39        location: Location,
40    },
41
42    #[snafu(display("Failed to cast result: `{}`", source))]
43    Cast {
44        #[snafu(source)]
45        source: QueryResult,
46        #[snafu(implicit)]
47        location: Location,
48    },
49
50    #[snafu(display("View already exists: `{name}`"))]
51    ViewAlreadyExists {
52        name: String,
53        #[snafu(implicit)]
54        location: Location,
55    },
56
57    #[snafu(display("Failed to build admin function args: {msg}"))]
58    BuildAdminFunctionArgs { msg: String },
59
60    #[snafu(display("Failed to execute admin function {msg}"))]
61    ExecuteAdminFunction {
62        msg: String,
63        #[snafu(source)]
64        error: DataFusionError,
65        #[snafu(implicit)]
66        location: Location,
67    },
68
69    #[snafu(display("Admin function execution was cancelled"))]
70    AdminFunctionCancelled,
71
72    #[snafu(display("Expected {expected} args, but actual {actual}"))]
73    FunctionArityMismatch { expected: usize, actual: usize },
74
75    #[snafu(display("Failed to invalidate table cache"))]
76    InvalidateTableCache {
77        #[snafu(implicit)]
78        location: Location,
79        source: common_meta::error::Error,
80    },
81
82    #[snafu(display("Failed to execute ddl"))]
83    ExecuteDdl {
84        #[snafu(implicit)]
85        location: Location,
86        source: common_meta::error::Error,
87    },
88
89    #[snafu(display("Invalid database export: {reason}"))]
90    InvalidDatabaseExport { reason: String },
91
92    #[snafu(display("Database export cancelled"))]
93    DatabaseExportCancelled {},
94
95    #[snafu(display("Packed import cancelled"))]
96    PackedImportCancelled {},
97
98    #[snafu(display("Invalid logical table export: {reason}"))]
99    InvalidLogicalTableExport { reason: String },
100
101    #[snafu(display("Logical table export resource limit exceeded: {reason}"))]
102    LogicalTableExportResource { reason: String },
103
104    #[snafu(display("Logical table export cancelled"))]
105    LogicalTableExportCancelled {},
106
107    #[snafu(display("Unexpected, violated: {}", violated))]
108    Unexpected {
109        violated: String,
110        #[snafu(implicit)]
111        location: Location,
112    },
113
114    #[snafu(display("Failed to flush pending batch: {source}"))]
115    BatchFlush {
116        source: Arc<Error>,
117        #[snafu(implicit)]
118        location: Location,
119    },
120
121    #[snafu(display("external error"))]
122    External {
123        #[snafu(implicit)]
124        location: Location,
125        source: BoxedError,
126    },
127
128    #[snafu(display("Write rejected: {error}"))]
129    WriteRejected {
130        #[snafu(source)]
131        error: meter_core::collect::WriteRejected,
132        #[snafu(implicit)]
133        location: Location,
134    },
135
136    #[snafu(display("Failed to insert data"))]
137    RequestInserts {
138        #[snafu(implicit)]
139        location: Location,
140        source: common_meta::error::Error,
141    },
142
143    #[snafu(display("Failed to delete data"))]
144    RequestDeletes {
145        #[snafu(implicit)]
146        location: Location,
147        source: common_meta::error::Error,
148    },
149
150    #[snafu(display("Failed to send request to region"))]
151    RequestRegion {
152        #[snafu(implicit)]
153        location: Location,
154        source: common_meta::error::Error,
155    },
156
157    #[snafu(display("Unsupported region request"))]
158    UnsupportedRegionRequest {
159        #[snafu(implicit)]
160        location: Location,
161    },
162
163    #[snafu(display("Failed to parse SQL"))]
164    ParseSql {
165        #[snafu(implicit)]
166        location: Location,
167        source: sql::error::Error,
168    },
169
170    #[snafu(display("Failed to convert identifier: {}", ident))]
171    ConvertIdentifier {
172        ident: String,
173        #[snafu(implicit)]
174        location: Location,
175        #[snafu(source)]
176        error: datafusion::error::DataFusionError,
177    },
178
179    #[snafu(display("Failed to extract table names"))]
180    ExtractTableNames {
181        #[snafu(implicit)]
182        location: Location,
183        source: query::error::Error,
184    },
185
186    #[snafu(display("Column datatype error"))]
187    ColumnDataType {
188        #[snafu(implicit)]
189        location: Location,
190        source: api::error::Error,
191    },
192
193    #[snafu(display("Invalid column proto definition, column: {}", column))]
194    InvalidColumnDef {
195        column: String,
196        #[snafu(implicit)]
197        location: Location,
198        source: api::error::Error,
199    },
200
201    #[snafu(display("Invalid statement to create view"))]
202    InvalidViewStmt {
203        #[snafu(implicit)]
204        location: Location,
205    },
206
207    #[snafu(display("Expect {expected} columns for view {view_name}, but found {actual}"))]
208    ViewColumnsMismatch {
209        view_name: String,
210        expected: usize,
211        actual: usize,
212    },
213
214    #[snafu(display("Invalid view \"{view_name}\": {msg}"))]
215    InvalidView {
216        msg: String,
217        view_name: String,
218        #[snafu(implicit)]
219        location: Location,
220    },
221
222    #[snafu(display("Failed to convert column default constraint, column: {}", column_name))]
223    ConvertColumnDefaultConstraint {
224        column_name: String,
225        #[snafu(implicit)]
226        location: Location,
227        source: datatypes::error::Error,
228    },
229
230    #[snafu(display("Failed to convert datafusion schema"))]
231    ConvertSchema {
232        source: datatypes::error::Error,
233        #[snafu(implicit)]
234        location: Location,
235    },
236
237    #[snafu(display("Failed to convert expr to struct"))]
238    InvalidExpr {
239        #[snafu(implicit)]
240        location: Location,
241        source: common_meta::error::Error,
242    },
243
244    #[snafu(display("Invalid partition"))]
245    InvalidPartition {
246        #[snafu(implicit)]
247        location: Location,
248        source: partition::error::Error,
249    },
250
251    #[snafu(display("Invalid SQL, error: {}", err_msg))]
252    InvalidSql {
253        err_msg: String,
254        #[snafu(implicit)]
255        location: Location,
256    },
257
258    #[snafu(display("Invalid InsertRequest, reason: {}", reason))]
259    InvalidInsertRequest {
260        reason: String,
261        #[snafu(implicit)]
262        location: Location,
263    },
264
265    #[snafu(display("Invalid DeleteRequest, reason: {}", reason))]
266    InvalidDeleteRequest {
267        reason: String,
268        #[snafu(implicit)]
269        location: Location,
270    },
271
272    #[snafu(display("Table not found: {}", table_name))]
273    TableNotFound { table_name: String },
274
275    #[snafu(display("Admin function not found: {}", name))]
276    AdminFunctionNotFound { name: String },
277
278    #[snafu(display("Flow not found: {}", flow_name))]
279    FlowNotFound { flow_name: String },
280
281    #[snafu(display("Failed to join task"))]
282    JoinTask {
283        #[snafu(source)]
284        error: common_runtime::JoinError,
285        #[snafu(implicit)]
286        location: Location,
287    },
288
289    #[snafu(display("General catalog error"))]
290    Catalog {
291        #[snafu(implicit)]
292        location: Location,
293        source: catalog::error::Error,
294    },
295
296    #[snafu(display("Failed to find view info for: {}", view_name))]
297    FindViewInfo {
298        view_name: String,
299        #[snafu(implicit)]
300        location: Location,
301        source: common_meta::error::Error,
302    },
303
304    #[snafu(display("View info not found: {}", view_name))]
305    ViewInfoNotFound {
306        view_name: String,
307        #[snafu(implicit)]
308        location: Location,
309    },
310
311    #[snafu(display("View not found: {}", view_name))]
312    ViewNotFound {
313        view_name: String,
314        #[snafu(implicit)]
315        location: Location,
316    },
317
318    #[snafu(display("Failed to find table partition rule for table {}", table_name))]
319    FindTablePartitionRule {
320        table_name: String,
321        #[snafu(implicit)]
322        location: Location,
323        source: partition::error::Error,
324    },
325
326    #[snafu(display("Failed to split insert request"))]
327    SplitInsert {
328        source: partition::error::Error,
329        #[snafu(implicit)]
330        location: Location,
331    },
332
333    #[snafu(display("Failed to split delete request"))]
334    SplitDelete {
335        source: partition::error::Error,
336        #[snafu(implicit)]
337        location: Location,
338    },
339
340    #[snafu(display("Failed to find leader for region"))]
341    FindRegionLeader {
342        source: partition::error::Error,
343        #[snafu(implicit)]
344        location: Location,
345    },
346
347    #[snafu(display("Failed to build CreateExpr on insertion"))]
348    BuildCreateExprOnInsertion {
349        #[snafu(implicit)]
350        location: Location,
351        source: common_grpc_expr::error::Error,
352    },
353
354    #[snafu(display("Failed to find schema, schema info: {}", schema_info))]
355    SchemaNotFound {
356        schema_info: String,
357        #[snafu(implicit)]
358        location: Location,
359    },
360
361    #[snafu(display("Schema {} already exists", name))]
362    SchemaExists {
363        name: String,
364        #[snafu(implicit)]
365        location: Location,
366    },
367
368    #[snafu(display("Schema `{name}` is in use"))]
369    SchemaInUse {
370        name: String,
371        #[snafu(implicit)]
372        location: Location,
373    },
374
375    #[snafu(display("Schema `{name}` is read-only"))]
376    SchemaReadOnly {
377        name: String,
378        #[snafu(implicit)]
379        location: Location,
380    },
381
382    #[snafu(display("Table `{name}` is read-only"))]
383    TableReadOnly {
384        name: String,
385        #[snafu(implicit)]
386        location: Location,
387    },
388
389    #[snafu(display(
390        "The definition of table `{name}` is managed by GreptimeDB; it cannot be created or altered (DROP recreates it on the next write)"
391    ))]
392    TableDdlReserved {
393        name: String,
394        #[snafu(implicit)]
395        location: Location,
396    },
397
398    #[snafu(display("Table occurs error"))]
399    Table {
400        #[snafu(implicit)]
401        location: Location,
402        source: table::error::Error,
403    },
404
405    #[snafu(display("Cannot find column by name: {}", msg))]
406    ColumnNotFound {
407        msg: String,
408        #[snafu(implicit)]
409        location: Location,
410    },
411
412    #[snafu(display("Failed to execute statement"))]
413    ExecuteStatement {
414        #[snafu(implicit)]
415        location: Location,
416        source: query::error::Error,
417    },
418
419    #[snafu(display("Failed to plan statement"))]
420    PlanStatement {
421        #[snafu(implicit)]
422        location: Location,
423        source: query::error::Error,
424    },
425
426    #[snafu(display("Failed to parse query"))]
427    ParseQuery {
428        #[snafu(implicit)]
429        location: Location,
430        source: query::error::Error,
431    },
432
433    #[snafu(display("Failed to execute logical plan"))]
434    ExecLogicalPlan {
435        #[snafu(implicit)]
436        location: Location,
437        source: query::error::Error,
438    },
439
440    #[snafu(display("Failed to build DataFusion logical plan"))]
441    BuildDfLogicalPlan {
442        #[snafu(source)]
443        error: datafusion_common::DataFusionError,
444        #[snafu(implicit)]
445        location: Location,
446    },
447
448    #[snafu(display("Failed to convert AlterExpr to AlterRequest"))]
449    AlterExprToRequest {
450        #[snafu(implicit)]
451        location: Location,
452        source: common_grpc_expr::error::Error,
453    },
454
455    #[snafu(display("Failed to build table meta for table: {}", table_name))]
456    BuildTableMeta {
457        table_name: String,
458        #[snafu(source)]
459        error: table::metadata::TableMetaBuilderError,
460        #[snafu(implicit)]
461        location: Location,
462    },
463
464    #[snafu(display("Not supported: {}", feat))]
465    NotSupported { feat: String },
466
467    #[snafu(display("Failed to find new columns on insertion"))]
468    FindNewColumnsOnInsertion {
469        #[snafu(implicit)]
470        location: Location,
471        source: common_grpc_expr::error::Error,
472    },
473
474    #[snafu(display("Failed to convert into vectors"))]
475    IntoVectors {
476        #[snafu(implicit)]
477        location: Location,
478        source: datatypes::error::Error,
479    },
480
481    #[snafu(display("Failed to describe schema for given statement"))]
482    DescribeStatement {
483        #[snafu(implicit)]
484        location: Location,
485        source: query::error::Error,
486    },
487
488    #[snafu(display("Illegal primary keys definition: {}", msg))]
489    IllegalPrimaryKeysDef {
490        msg: String,
491        #[snafu(implicit)]
492        location: Location,
493    },
494
495    #[snafu(display("Unrecognized table option"))]
496    UnrecognizedTableOption {
497        #[snafu(implicit)]
498        location: Location,
499        source: table::error::Error,
500    },
501
502    #[snafu(display("Missing time index column"))]
503    MissingTimeIndexColumn {
504        #[snafu(implicit)]
505        location: Location,
506        source: table::error::Error,
507    },
508
509    #[snafu(display("Failed to build regex"))]
510    BuildRegex {
511        #[snafu(implicit)]
512        location: Location,
513        #[snafu(source)]
514        error: regex::Error,
515    },
516
517    #[snafu(display("Failed to insert value into table: {}", table_name))]
518    Insert {
519        table_name: String,
520        #[snafu(implicit)]
521        location: Location,
522        source: table::error::Error,
523    },
524
525    #[snafu(display("Unsupported format: {:?}", format))]
526    UnsupportedFormat {
527        #[snafu(implicit)]
528        location: Location,
529        format: Format,
530    },
531
532    #[snafu(display("Failed to parse file format"))]
533    ParseFileFormat {
534        #[snafu(implicit)]
535        location: Location,
536        source: common_datasource::error::Error,
537    },
538
539    #[snafu(display("Failed to build data source backend"))]
540    BuildBackend {
541        #[snafu(implicit)]
542        location: Location,
543        source: common_datasource::error::Error,
544    },
545
546    #[snafu(display("Failed to list objects"))]
547    ListObjects {
548        #[snafu(implicit)]
549        location: Location,
550        source: common_datasource::error::Error,
551    },
552
553    #[snafu(display("Failed to infer schema from path: {}", path))]
554    InferSchema {
555        path: String,
556        #[snafu(implicit)]
557        location: Location,
558        source: common_datasource::error::Error,
559    },
560
561    #[snafu(display("Failed to write stream to path: {}", path))]
562    WriteStreamToFile {
563        path: String,
564        #[snafu(implicit)]
565        location: Location,
566        source: common_datasource::error::Error,
567    },
568
569    #[snafu(display("Failed to read object in path: {}", path))]
570    ReadObject {
571        path: String,
572        #[snafu(implicit)]
573        location: Location,
574        #[snafu(source)]
575        error: object_store::Error,
576    },
577
578    #[snafu(display("Failed to read record batch"))]
579    ReadDfRecordBatch {
580        #[snafu(source)]
581        error: datafusion::error::DataFusionError,
582        #[snafu(implicit)]
583        location: Location,
584    },
585
586    #[snafu(display("Failed to read parquet file metadata"))]
587    ReadParquetMetadata {
588        #[snafu(source)]
589        error: parquet::errors::ParquetError,
590        #[snafu(implicit)]
591        location: Location,
592    },
593
594    #[snafu(display("Failed to build record batch"))]
595    BuildRecordBatch {
596        #[snafu(implicit)]
597        location: Location,
598        source: common_recordbatch::error::Error,
599    },
600
601    #[snafu(display("Failed to read orc schema"))]
602    ReadOrc {
603        source: common_datasource::error::Error,
604        #[snafu(implicit)]
605        location: Location,
606    },
607
608    #[snafu(display("Failed to build parquet record batch stream"))]
609    BuildParquetRecordBatchStream {
610        #[snafu(implicit)]
611        location: Location,
612        #[snafu(source)]
613        error: parquet::errors::ParquetError,
614    },
615
616    #[snafu(display("Failed to build file stream"))]
617    BuildFileStream {
618        #[snafu(implicit)]
619        location: Location,
620        #[snafu(source)]
621        error: common_datasource::error::Error,
622    },
623
624    #[snafu(display(
625        "Schema datatypes not match at index {}, expected table schema: {}, actual file schema: {}",
626        index,
627        table_schema,
628        file_schema
629    ))]
630    InvalidSchema {
631        index: usize,
632        table_schema: String,
633        file_schema: String,
634        #[snafu(implicit)]
635        location: Location,
636    },
637
638    #[snafu(display(
639        "CSV header mismatch in path: {}, unknown columns: {:?}, missing columns: {:?}, duplicate columns: {:?}",
640        path,
641        unknown_columns,
642        missing_columns,
643        duplicate_columns
644    ))]
645    CsvHeaderMismatch {
646        path: String,
647        unknown_columns: Vec<String>,
648        missing_columns: Vec<String>,
649        duplicate_columns: Vec<String>,
650        #[snafu(implicit)]
651        location: Location,
652    },
653
654    #[snafu(display("Failed to project schema"))]
655    ProjectSchema {
656        #[snafu(source)]
657        error: ArrowError,
658        #[snafu(implicit)]
659        location: Location,
660    },
661
662    #[snafu(display("Failed to encode object into json"))]
663    EncodeJson {
664        #[snafu(source)]
665        error: serde_json::error::Error,
666        #[snafu(implicit)]
667        location: Location,
668    },
669
670    #[snafu(display("Invalid COPY parameter, key: {}, value: {}", key, value))]
671    InvalidCopyParameter {
672        key: String,
673        value: String,
674        #[snafu(implicit)]
675        location: Location,
676    },
677
678    #[snafu(display("Invalid COPY DATABASE location, must end with '/': {}", value))]
679    InvalidCopyDatabasePath {
680        value: String,
681        #[snafu(implicit)]
682        location: Location,
683    },
684
685    #[snafu(display("Table metadata manager error"))]
686    TableMetadataManager {
687        source: common_meta::error::Error,
688        #[snafu(implicit)]
689        location: Location,
690    },
691
692    #[snafu(display("Missing insert body"))]
693    MissingInsertBody {
694        source: sql::error::Error,
695        #[snafu(implicit)]
696        location: Location,
697    },
698
699    #[snafu(display("Failed to parse sql value"))]
700    ParseSqlValue {
701        source: sql::error::Error,
702        #[snafu(implicit)]
703        location: Location,
704    },
705
706    #[snafu(display("Failed to build default value, column: {}", column))]
707    ColumnDefaultValue {
708        column: String,
709        #[snafu(implicit)]
710        location: Location,
711        source: datatypes::error::Error,
712    },
713
714    #[snafu(display(
715        "No valid default value can be built automatically, column: {}",
716        column,
717    ))]
718    ColumnNoneDefaultValue {
719        column: String,
720        #[snafu(implicit)]
721        location: Location,
722    },
723
724    #[snafu(display("Failed to prepare file table"))]
725    PrepareFileTable {
726        #[snafu(implicit)]
727        location: Location,
728        source: query::error::Error,
729    },
730
731    #[snafu(display("Failed to infer file table schema"))]
732    InferFileTableSchema {
733        #[snafu(implicit)]
734        location: Location,
735        source: query::error::Error,
736    },
737
738    #[snafu(display("The schema of the file table is incompatible with the table schema"))]
739    SchemaIncompatible {
740        #[snafu(implicit)]
741        location: Location,
742        source: query::error::Error,
743    },
744
745    #[snafu(display("Invalid table name: {}", table_name))]
746    InvalidTableName {
747        table_name: String,
748        #[snafu(implicit)]
749        location: Location,
750    },
751
752    #[snafu(display("Invalid view name: {name}"))]
753    InvalidViewName {
754        name: String,
755        #[snafu(implicit)]
756        location: Location,
757    },
758
759    #[snafu(display("Invalid flow name: {name}"))]
760    InvalidFlowName {
761        name: String,
762        #[snafu(implicit)]
763        location: Location,
764    },
765
766    #[cfg(feature = "enterprise")]
767    #[snafu(display("Invalid trigger name: {name}"))]
768    InvalidTriggerName {
769        name: String,
770        #[snafu(implicit)]
771        location: Location,
772    },
773
774    #[snafu(display("Empty {} expr", name))]
775    EmptyDdlExpr {
776        name: String,
777        #[snafu(implicit)]
778        location: Location,
779    },
780
781    #[snafu(display("Failed to create logical tables: {}", reason))]
782    CreateLogicalTables {
783        reason: String,
784        #[snafu(implicit)]
785        location: Location,
786    },
787
788    #[snafu(display("Invalid partition rule: {}", reason))]
789    InvalidPartitionRule {
790        reason: String,
791        #[snafu(implicit)]
792        location: Location,
793    },
794
795    #[snafu(display("Failed to serialize partition expression"))]
796    SerializePartitionExpr {
797        #[snafu(implicit)]
798        location: Location,
799        source: partition::error::Error,
800    },
801
802    #[snafu(display("Failed to deserialize partition expression"))]
803    DeserializePartitionExpr {
804        #[snafu(source)]
805        source: partition::error::Error,
806        #[snafu(implicit)]
807        location: Location,
808    },
809
810    #[snafu(display("Invalid configuration value."))]
811    InvalidConfigValue {
812        source: session::session_config::Error,
813        #[snafu(implicit)]
814        location: Location,
815    },
816
817    #[snafu(display("Invalid timestamp range, start: `{}`, end: `{}`", start, end))]
818    InvalidTimestampRange {
819        start: String,
820        end: String,
821        #[snafu(implicit)]
822        location: Location,
823    },
824
825    #[snafu(display("Failed to convert between logical plan and substrait plan"))]
826    SubstraitCodec {
827        #[snafu(implicit)]
828        location: Location,
829        source: substrait::error::Error,
830    },
831
832    #[snafu(display(
833        "Show create table only for base table. {} is {}",
834        table_name,
835        table_type
836    ))]
837    ShowCreateTableBaseOnly {
838        table_name: String,
839        table_type: TableType,
840        #[snafu(implicit)]
841        location: Location,
842    },
843    #[snafu(display("Create physical expr error"))]
844    PhysicalExpr {
845        #[snafu(source)]
846        error: common_recordbatch::error::Error,
847        #[snafu(implicit)]
848        location: Location,
849    },
850
851    #[snafu(display("Failed to upgrade catalog manager reference"))]
852    UpgradeCatalogManagerRef {
853        #[snafu(implicit)]
854        location: Location,
855    },
856
857    #[snafu(display("Invalid json text: {}", json))]
858    InvalidJsonFormat {
859        #[snafu(implicit)]
860        location: Location,
861        json: String,
862    },
863
864    #[snafu(display("Cursor {name} is not found"))]
865    CursorNotFound { name: String },
866
867    #[snafu(display("A cursor named {name} already exists"))]
868    CursorExists { name: String },
869
870    #[snafu(display("Column options error"))]
871    ColumnOptions {
872        #[snafu(source)]
873        source: api::error::Error,
874        #[snafu(implicit)]
875        location: Location,
876    },
877
878    #[snafu(display("Failed to create partition rules"))]
879    CreatePartitionRules {
880        #[snafu(source)]
881        source: sql::error::Error,
882        #[snafu(implicit)]
883        location: Location,
884    },
885
886    #[snafu(display("Failed to decode arrow flight data"))]
887    DecodeFlightData {
888        source: common_grpc::error::Error,
889        #[snafu(implicit)]
890        location: Location,
891    },
892
893    #[snafu(display("Failed to perform arrow compute"))]
894    ComputeArrow {
895        #[snafu(source)]
896        error: ArrowError,
897        #[snafu(implicit)]
898        location: Location,
899    },
900
901    #[snafu(display("Invalid time index type: {}", ty))]
902    InvalidTimeIndexType {
903        ty: arrow::datatypes::DataType,
904        #[snafu(implicit)]
905        location: Location,
906    },
907
908    #[snafu(display("Invalid timezone: {}", timezone))]
909    InvalidTimezone {
910        timezone: String,
911        #[snafu(source)]
912        source: common_time::error::Error,
913        #[snafu(implicit)]
914        location: Location,
915    },
916
917    #[snafu(display("Invalid process id: {}", id))]
918    InvalidProcessId { id: String },
919
920    #[snafu(display("ProcessManager is not present, this can be caused by misconfiguration."))]
921    ProcessManagerMissing {
922        #[snafu(implicit)]
923        location: Location,
924    },
925
926    #[snafu(display("Sql common error"))]
927    SqlCommon {
928        source: common_sql::error::Error,
929        #[snafu(implicit)]
930        location: Location,
931    },
932
933    #[snafu(display("Failed to convert partition expression to protobuf"))]
934    PartitionExprToPb {
935        source: partition::error::Error,
936        #[snafu(implicit)]
937        location: Location,
938    },
939
940    #[snafu(display(
941        "{} not supported when transforming to {} format type",
942        format,
943        file_format
944    ))]
945    TimestampFormatNotSupported {
946        file_format: String,
947        format: String,
948        #[snafu(implicit)]
949        location: Location,
950    },
951
952    #[cfg(feature = "enterprise")]
953    #[snafu(display("Too large duration"))]
954    TooLargeDuration {
955        #[snafu(source)]
956        error: prost_types::DurationError,
957        #[snafu(implicit)]
958        location: Location,
959    },
960
961    #[cfg(feature = "enterprise")]
962    #[snafu(display("Not trigger querier is specified"))]
963    MissingTriggerQuerier {
964        #[snafu(implicit)]
965        location: Location,
966    },
967
968    #[cfg(feature = "enterprise")]
969    #[snafu(display("Trigger querier error"))]
970    TriggerQuerier {
971        source: BoxedError,
972        #[snafu(implicit)]
973        location: Location,
974    },
975}
976
977pub type Result<T> = std::result::Result<T, Error>;
978
979impl ErrorExt for Error {
980    fn status_code(&self) -> StatusCode {
981        match self {
982            Error::Cast { source, .. } => source.status_code(),
983            Error::InvalidSql { .. }
984            | Error::InvalidConfigValue { .. }
985            | Error::InvalidInsertRequest { .. }
986            | Error::InvalidDeleteRequest { .. }
987            | Error::IllegalPrimaryKeysDef { .. }
988            | Error::SchemaNotFound { .. }
989            | Error::SchemaExists { .. }
990            | Error::SchemaInUse { .. }
991            | Error::ColumnNotFound { .. }
992            | Error::BuildRegex { .. }
993            | Error::InvalidSchema { .. }
994            | Error::CsvHeaderMismatch { .. }
995            | Error::ProjectSchema { .. }
996            | Error::UnsupportedFormat { .. }
997            | Error::ColumnNoneDefaultValue { .. }
998            | Error::PrepareFileTable { .. }
999            | Error::InferFileTableSchema { .. }
1000            | Error::SchemaIncompatible { .. }
1001            | Error::ConvertSchema { .. }
1002            | Error::UnsupportedRegionRequest { .. }
1003            | Error::InvalidTableName { .. }
1004            | Error::InvalidViewName { .. }
1005            | Error::InvalidFlowName { .. }
1006            | Error::InvalidView { .. }
1007            | Error::InvalidExpr { .. }
1008            | Error::AdminFunctionNotFound { .. }
1009            | Error::ViewColumnsMismatch { .. }
1010            | Error::InvalidViewStmt { .. }
1011            | Error::ConvertIdentifier { .. }
1012            | Error::BuildAdminFunctionArgs { .. }
1013            | Error::FunctionArityMismatch { .. }
1014            | Error::InvalidPartition { .. }
1015            | Error::PhysicalExpr { .. }
1016            | Error::InvalidJsonFormat { .. }
1017            | Error::PartitionExprToPb { .. }
1018            | Error::CursorNotFound { .. }
1019            | Error::CursorExists { .. }
1020            | Error::CreatePartitionRules { .. } => StatusCode::InvalidArguments,
1021            Error::TableAlreadyExists { .. } | Error::ViewAlreadyExists { .. } => {
1022                StatusCode::TableAlreadyExists
1023            }
1024            Error::NotSupported { .. }
1025            | Error::ShowCreateTableBaseOnly { .. }
1026            | Error::SchemaReadOnly { .. }
1027            | Error::TableReadOnly { .. }
1028            | Error::TableDdlReserved { .. } => StatusCode::Unsupported,
1029            Error::TableMetadataManager { source, .. } => source.status_code(),
1030            Error::ParseSql { source, .. } => source.status_code(),
1031            Error::InvalidateTableCache { source, .. } => source.status_code(),
1032            Error::ParseFileFormat { source, .. } | Error::InferSchema { source, .. } => {
1033                source.status_code()
1034            }
1035            Error::Table { source, .. } | Error::Insert { source, .. } => source.status_code(),
1036            Error::ConvertColumnDefaultConstraint { source, .. }
1037            | Error::IntoVectors { source, .. } => source.status_code(),
1038            Error::RequestInserts { source, .. } | Error::FindViewInfo { source, .. } => {
1039                source.status_code()
1040            }
1041            Error::RequestRegion { source, .. } => source.status_code(),
1042            Error::RequestDeletes { source, .. } => source.status_code(),
1043            Error::SubstraitCodec { source, .. } => source.status_code(),
1044            Error::ColumnDataType { source, .. } | Error::InvalidColumnDef { source, .. } => {
1045                source.status_code()
1046            }
1047            Error::MissingTimeIndexColumn { source, .. } => source.status_code(),
1048            Error::BuildDfLogicalPlan { .. }
1049            | Error::BuildTableMeta { .. }
1050            | Error::MissingInsertBody { .. } => StatusCode::Internal,
1051            Error::ExecuteAdminFunction { error, .. } => admin_external_error(error)
1052                .map(ErrorExt::status_code)
1053                .unwrap_or(StatusCode::Unexpected),
1054            Error::EncodeJson { .. }
1055            | Error::DeserializePartitionExpr { .. }
1056            | Error::SerializePartitionExpr { .. } => StatusCode::Unexpected,
1057            Error::AdminFunctionCancelled => StatusCode::Cancelled,
1058            Error::ViewNotFound { .. }
1059            | Error::ViewInfoNotFound { .. }
1060            | Error::TableNotFound { .. } => StatusCode::TableNotFound,
1061            Error::FlowNotFound { .. } => StatusCode::FlowNotFound,
1062            Error::JoinTask { .. } => StatusCode::Internal,
1063            Error::BuildParquetRecordBatchStream { .. }
1064            | Error::BuildFileStream { .. }
1065            | Error::WriteStreamToFile { .. }
1066            | Error::ReadDfRecordBatch { .. }
1067            | Error::Unexpected { .. } => StatusCode::Unexpected,
1068            Error::Catalog { source, .. } => source.status_code(),
1069            Error::BuildCreateExprOnInsertion { source, .. }
1070            | Error::FindNewColumnsOnInsertion { source, .. } => source.status_code(),
1071            Error::ExecuteStatement { source, .. }
1072            | Error::ExtractTableNames { source, .. }
1073            | Error::PlanStatement { source, .. }
1074            | Error::ParseQuery { source, .. }
1075            | Error::ExecLogicalPlan { source, .. }
1076            | Error::DescribeStatement { source, .. } => source.status_code(),
1077            Error::AlterExprToRequest { source, .. } => source.status_code(),
1078            Error::External { source, .. } => source.status_code(),
1079            Error::BatchFlush { source, .. } => source.status_code(),
1080            Error::WriteRejected { .. } => StatusCode::RateLimited,
1081            Error::FindTablePartitionRule { source, .. }
1082            | Error::SplitInsert { source, .. }
1083            | Error::SplitDelete { source, .. }
1084            | Error::FindRegionLeader { source, .. } => source.status_code(),
1085            Error::UnrecognizedTableOption { .. } => StatusCode::InvalidArguments,
1086            Error::ReadObject { .. }
1087            | Error::ReadParquetMetadata { .. }
1088            | Error::ReadOrc { .. } => StatusCode::StorageUnavailable,
1089            Error::ListObjects { source, .. } | Error::BuildBackend { source, .. } => {
1090                source.status_code()
1091            }
1092            Error::ExecuteDdl { source, .. } => source.status_code(),
1093            Error::InvalidCopyParameter { .. } | Error::InvalidCopyDatabasePath { .. } => {
1094                StatusCode::InvalidArguments
1095            }
1096            Error::ColumnDefaultValue { source, .. } => source.status_code(),
1097            Error::EmptyDdlExpr { .. }
1098            | Error::InvalidPartitionRule { .. }
1099            | Error::ParseSqlValue { .. }
1100            | Error::InvalidTimestampRange { .. } => StatusCode::InvalidArguments,
1101            Error::CreateLogicalTables { .. } => StatusCode::Unexpected,
1102            Error::BuildRecordBatch { source, .. } => source.status_code(),
1103            Error::UpgradeCatalogManagerRef { .. } => StatusCode::Internal,
1104            Error::ColumnOptions { source, .. } => source.status_code(),
1105            Error::DecodeFlightData { source, .. } => source.status_code(),
1106            Error::ComputeArrow { .. } => StatusCode::Internal,
1107            Error::InvalidTimeIndexType { .. } | Error::InvalidTimezone { .. } => {
1108                StatusCode::InvalidArguments
1109            }
1110            Error::InvalidDatabaseExport { .. } => StatusCode::InvalidArguments,
1111            Error::DatabaseExportCancelled { .. } | Error::PackedImportCancelled { .. } => {
1112                StatusCode::Cancelled
1113            }
1114            Error::InvalidLogicalTableExport { .. } => StatusCode::InvalidArguments,
1115            Error::LogicalTableExportResource { .. } => StatusCode::Suspended,
1116            Error::LogicalTableExportCancelled { .. } => StatusCode::Cancelled,
1117            Error::InvalidProcessId { .. } => StatusCode::InvalidArguments,
1118            Error::ProcessManagerMissing { .. } => StatusCode::Unexpected,
1119            Error::TimestampFormatNotSupported { .. } => StatusCode::InvalidArguments,
1120            Error::SqlCommon { source, .. } => source.status_code(),
1121            #[cfg(feature = "enterprise")]
1122            Error::InvalidTriggerName { .. } => StatusCode::InvalidArguments,
1123            #[cfg(feature = "enterprise")]
1124            Error::TooLargeDuration { .. } => StatusCode::InvalidArguments,
1125            #[cfg(feature = "enterprise")]
1126            Error::MissingTriggerQuerier { .. } => StatusCode::Internal,
1127            #[cfg(feature = "enterprise")]
1128            Error::TriggerQuerier { source, .. } => source.status_code(),
1129        }
1130    }
1131
1132    fn as_any(&self) -> &dyn Any {
1133        self
1134    }
1135
1136    fn retry_hint(&self) -> RetryHint {
1137        match self {
1138            Error::ReadObject { error, .. } => retry_hint_from_opendal_error(error),
1139            Error::ReadParquetMetadata { .. } | Error::WriteRejected { .. } => RetryHint::Retryable,
1140            Error::InvalidateTableCache { source, .. }
1141            | Error::ExecuteDdl { source, .. }
1142            | Error::RequestInserts { source, .. }
1143            | Error::RequestDeletes { source, .. }
1144            | Error::RequestRegion { source, .. }
1145            | Error::FindViewInfo { source, .. }
1146            | Error::TableMetadataManager { source, .. } => source.retry_hint(),
1147
1148            Error::ParseFileFormat { source, .. }
1149            | Error::InferSchema { source, .. }
1150            | Error::ListObjects { source, .. }
1151            | Error::BuildBackend { source, .. }
1152            | Error::ReadOrc { source, .. } => source.retry_hint(),
1153
1154            Error::ExtractTableNames { source, .. }
1155            | Error::ExecuteStatement { source, .. }
1156            | Error::PlanStatement { source, .. }
1157            | Error::ParseQuery { source, .. }
1158            | Error::ExecLogicalPlan { source, .. }
1159            | Error::DescribeStatement { source, .. } => source.retry_hint(),
1160
1161            Error::FindTablePartitionRule { source, .. }
1162            | Error::SplitInsert { source, .. }
1163            | Error::SplitDelete { source, .. }
1164            | Error::FindRegionLeader { source, .. } => source.retry_hint(),
1165
1166            Error::BuildCreateExprOnInsertion { source, .. }
1167            | Error::FindNewColumnsOnInsertion { source, .. }
1168            | Error::AlterExprToRequest { source, .. } => source.retry_hint(),
1169
1170            Error::ConvertColumnDefaultConstraint { source, .. }
1171            | Error::IntoVectors { source, .. }
1172            | Error::ColumnDefaultValue { source, .. } => source.retry_hint(),
1173
1174            Error::ColumnDataType { source, .. }
1175            | Error::InvalidColumnDef { source, .. }
1176            | Error::ColumnOptions { source, .. } => source.retry_hint(),
1177
1178            Error::Table { source, .. }
1179            | Error::Insert { source, .. }
1180            | Error::MissingTimeIndexColumn { source, .. } => source.retry_hint(),
1181
1182            Error::Cast { source, .. } => source.retry_hint(),
1183            Error::ExecuteAdminFunction { error, .. } => admin_external_error(error)
1184                .map(ErrorExt::retry_hint)
1185                .unwrap_or(RetryHint::NonRetryable),
1186            Error::ParseSql { source, .. } => source.retry_hint(),
1187            Error::Catalog { source, .. } => source.retry_hint(),
1188            Error::SubstraitCodec { source, .. } => source.retry_hint(),
1189            Error::External { source, .. } => source.retry_hint(),
1190            Error::BatchFlush { source, .. } => source.retry_hint(),
1191            Error::BuildRecordBatch { source, .. } => source.retry_hint(),
1192            Error::DecodeFlightData { source, .. } => source.retry_hint(),
1193            Error::SqlCommon { source, .. } => source.retry_hint(),
1194            Error::ConvertSchema { source, .. } => source.retry_hint(),
1195            Error::WriteStreamToFile { source, .. } => source.retry_hint(),
1196            Error::PrepareFileTable { source, .. } | Error::InferFileTableSchema { source, .. } => {
1197                source.retry_hint()
1198            }
1199            #[cfg(feature = "enterprise")]
1200            Error::TriggerQuerier { source, .. } => source.retry_hint(),
1201            _ => RetryHint::NonRetryable,
1202        }
1203    }
1204}
1205
1206fn admin_external_error(error: &DataFusionError) -> Option<&BoxedError> {
1207    match error {
1208        DataFusionError::External(error) => error.downcast_ref::<BoxedError>(),
1209        DataFusionError::Diagnostic(_, error) => admin_external_error(error),
1210        _ => None,
1211    }
1212}
1213
1214define_into_tonic_status!(Error);
1215
1216#[cfg(test)]
1217mod tests {
1218    use crate::error::*;
1219
1220    #[test]
1221    fn admin_function_preserves_external_error_metadata() {
1222        let external = BoxedError::new(meta_client::error::Error::MetaServer {
1223            code: StatusCode::TableUnavailable,
1224            msg: "leader changed".to_string(),
1225            tonic_code: tonic::Code::Unavailable,
1226            retry_hint: RetryHint::Retryable,
1227            location: snafu::location!(),
1228        });
1229        let error = Error::ExecuteAdminFunction {
1230            msg: "test_admin".to_string(),
1231            error: DataFusionError::External(Box::new(external)),
1232            location: snafu::location!(),
1233        };
1234
1235        assert_eq!(StatusCode::TableUnavailable, error.status_code());
1236        assert_eq!(RetryHint::Retryable, error.retry_hint());
1237    }
1238}