diff --git a/src/common/error/src/status_code.rs b/src/common/error/src/status_code.rs index 2afcbc278d..2b0a338b31 100644 --- a/src/common/error/src/status_code.rs +++ b/src/common/error/src/status_code.rs @@ -1,17 +1,22 @@ /// Common status code for public API. #[derive(Debug, Clone, Copy)] pub enum StatusCode { - // ====== Begin of common status code =========== + // ====== Begin of common status code ============== /// Unknown error. Unknown, /// Unsupported operation. Unsupported, /// Internal server error. Internal, - // ====== End of common status code ============= + // ====== End of common status code ================ - // ====== Begin of SQL related status code ====== + // ====== Begin of SQL related status code ========= /// SQL Syntax error. InvalidSyntax, - // ====== End of SQL related status code ======== + // ====== End of SQL related status code =========== + + // ====== Begin of catalog related status code ===== + /// Table already exists. + TableAlreadyExists, + // ====== End of catalog related status code ======= } diff --git a/src/datanode/src/error.rs b/src/datanode/src/error.rs index 6b4762d008..de767ffe8c 100644 --- a/src/datanode/src/error.rs +++ b/src/datanode/src/error.rs @@ -1,5 +1,4 @@ use common_error::prelude::*; -use snafu::Snafu; /// Business error of datanode. #[derive(Debug, Snafu)] diff --git a/src/query/src/catalog/memory.rs b/src/query/src/catalog/memory.rs index 6c4aa8be41..e2c194c001 100644 --- a/src/query/src/catalog/memory.rs +++ b/src/query/src/catalog/memory.rs @@ -3,6 +3,7 @@ use std::collections::HashMap; use std::sync::Arc; use std::sync::RwLock; +use common_error::prelude::*; use table::table::numbers::NumbersTable; use table::TableRef; @@ -11,8 +12,32 @@ use crate::catalog::{ CatalogList, CatalogListRef, CatalogProvider, CatalogProviderRef, DEFAULT_CATALOG_NAME, DEFAULT_SCHEMA_NAME, }; -use crate::error::Result; -use crate::query_engine::datafusion::error; +use crate::error::{Error, Result}; + +/// Error implementation of memory catalog. +#[derive(Debug, Snafu)] +pub enum InnerError { + #[snafu(display("Table {} already exists", table))] + TableExists { table: String, backtrace: Backtrace }, +} + +impl ErrorExt for InnerError { + fn status_code(&self) -> StatusCode { + match self { + InnerError::TableExists { .. } => StatusCode::TableAlreadyExists, + } + } + + fn backtrace_opt(&self) -> Option<&Backtrace> { + ErrorCompat::backtrace(self) + } +} + +impl From for Error { + fn from(err: InnerError) -> Self { + Self::new(err) + } +} /// Simple in-memory list of catalogs #[derive(Default)] @@ -129,10 +154,7 @@ impl SchemaProvider for MemorySchemaProvider { fn register_table(&self, name: String, table: TableRef) -> Result> { if self.table_exist(name.as_str()) { // FIXME(yingwen): Define another error. - return error::ExecutionSnafu { - message: format!("The table {} already exists", name), - } - .fail()?; + return TableExistsSnafu { table: name }.fail()?; } let mut tables = self.tables.write().unwrap(); Ok(tables.insert(name, table)) diff --git a/src/query/src/query_engine/datafusion/error.rs b/src/query/src/query_engine/datafusion/error.rs index 5798b20e9f..1d89deacd2 100644 --- a/src/query/src/query_engine/datafusion/error.rs +++ b/src/query/src/query_engine/datafusion/error.rs @@ -1,6 +1,5 @@ use common_error::prelude::*; use datafusion::error::DataFusionError; -use snafu::{Backtrace, ErrorCompat, Snafu}; use crate::error::Error; @@ -28,14 +27,21 @@ pub enum InnerError { source: DataFusionError, backtrace: Backtrace, }, - - #[snafu(display("Execution error: {}", message))] - Execution { message: String }, } -// TODO(yingwen): Implement status_code(). impl ErrorExt for InnerError { - fn backtrace_opt(&self) -> Option<&snafu::Backtrace> { + fn status_code(&self) -> StatusCode { + use InnerError::*; + + match self { + ParseSql { source, .. } => source.status_code(), + Datafusion { .. } | PhysicalPlanDowncast { .. } | Planner { .. } => { + StatusCode::Internal + } + } + } + + fn backtrace_opt(&self) -> Option<&Backtrace> { ErrorCompat::backtrace(self) } }