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