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