feat: Frontend show tables and databases (#504)

* feat: Frontend show tables and databases

Co-authored-by: luofucong <luofucong@greptime.com>
This commit is contained in:
LFC
2022-11-15 14:21:50 +08:00
committed by GitHub
parent 6e93c5e1de
commit 2c0d2da5a7
16 changed files with 299 additions and 239 deletions

View File

@@ -72,6 +72,18 @@ impl CatalogManager for FrontendCatalogManager {
unimplemented!()
}
fn schema(
&self,
catalog: &str,
schema: &str,
) -> catalog::error::Result<Option<SchemaProviderRef>> {
self.catalog(catalog)?
.context(catalog::error::CatalogNotFoundSnafu {
catalog_name: catalog,
})?
.schema(schema)
}
fn table(
&self,
_catalog: &str,

View File

@@ -359,6 +359,21 @@ pub enum Error {
#[snafu(backtrace)]
source: query::error::Error,
},
#[snafu(display("Unsupported expr type: {}", name))]
UnsupportedExpr { name: String, backtrace: Backtrace },
#[snafu(display("Failed to create a RecordBatch, source: {}", source))]
NewRecordBatch {
#[snafu(backtrace)]
source: common_recordbatch::error::Error,
},
#[snafu(display("Failed to do vector computation, source: {}", source))]
VectorComputation {
#[snafu(backtrace)]
source: datatypes::error::Error,
},
}
pub type Result<T> = std::result::Result<T, Error>;
@@ -387,7 +402,8 @@ impl ErrorExt for Error {
Error::Table { source } => source.status_code(),
Error::ConvertColumnDefaultConstraint { source, .. }
| Error::ConvertScalarValue { source, .. } => source.status_code(),
| Error::ConvertScalarValue { source, .. }
| Error::VectorComputation { source } => source.status_code(),
Error::ConnectDatanode { source, .. }
| Error::RequestDatanode { source }
@@ -402,7 +418,8 @@ impl ErrorExt for Error {
| Error::FindRegionRoutes { .. }
| Error::FindLeaderPeer { .. }
| Error::FindRegionPartition { .. }
| Error::IllegalTableRoutesData { .. } => StatusCode::Internal,
| Error::IllegalTableRoutesData { .. }
| Error::UnsupportedExpr { .. } => StatusCode::Internal,
Error::IllegalFrontendState { .. } | Error::IncompleteGrpcResult { .. } => {
StatusCode::Unexpected
@@ -434,6 +451,7 @@ impl ErrorExt for Error {
Error::PrimaryKeyNotFound { .. } => StatusCode::InvalidArguments,
Error::ExecuteSql { source, .. } => source.status_code(),
Error::InsertBatchToRequest { source, .. } => source.status_code(),
Error::NewRecordBatch { source } => source.status_code(),
}
}

View File

@@ -188,11 +188,13 @@ impl Instance {
self.script_handler = Some(handler);
}
pub async fn handle_select(&self, expr: Select) -> Result<Output> {
pub async fn handle_select(&self, expr: Select, stmt: Statement) -> Result<Output> {
if let Some(dist_instance) = &self.dist_instance {
dist_instance.handle_select(expr).await
let Select::Sql(sql) = expr;
dist_instance.handle_sql(&sql, stmt).await
} else {
// TODO(LFC): Find a better way to execute query between Frontend and Datanode in standalone mode.
// TODO(LFC): Refactor consideration: Datanode should directly execute statement in standalone mode to avoid parse SQL again.
// Find a better way to execute query between Frontend and Datanode in standalone mode.
// Otherwise we have to parse SQL first to get schema name. Maybe not GRPC.
self.database(DEFAULT_SCHEMA_NAME)
.select(expr)
@@ -520,7 +522,7 @@ impl SqlQueryHandler for Instance {
match stmt {
Statement::Query(_) => self
.handle_select(Select::Sql(query.to_string()))
.handle_select(Select::Sql(query.to_string()), stmt)
.await
.map_err(BoxedError::new)
.context(server_error::ExecuteQuerySnafu { query }),
@@ -572,7 +574,7 @@ impl SqlQueryHandler for Instance {
}
Statement::ShowDatabases(_) | Statement::ShowTables(_) => self
.handle_select(Select::Sql(query.to_string()))
.handle_select(Select::Sql(query.to_string()), stmt)
.await
.map_err(BoxedError::new)
.context(server_error::ExecuteQuerySnafu { query }),

View File

@@ -5,7 +5,6 @@ use api::helper::ColumnDataTypeWrapper;
use api::v1::CreateExpr;
use chrono::DateTime;
use client::admin::{admin_result_to_output, Admin};
use client::Select;
use common_catalog::consts::{DEFAULT_CATALOG_NAME, DEFAULT_SCHEMA_NAME};
use common_catalog::{TableGlobalKey, TableGlobalValue};
use common_query::Output;
@@ -17,10 +16,12 @@ use meta_client::rpc::{
CreateRequest as MetaCreateRequest, Partition as MetaPartition, RouteResponse, TableName,
TableRoute,
};
use query::sql::{show_databases, show_tables};
use query::{QueryEngineFactory, QueryEngineRef};
use snafu::{ensure, OptionExt, ResultExt};
use sql::statements::create::Partitions;
use sql::statements::sql_value_to_value;
use sql::statements::statement::Statement;
use sqlparser::ast::Value as SqlValue;
use table::metadata::RawTableMeta;
@@ -103,16 +104,24 @@ impl DistInstance {
Ok(Output::AffectedRows(region_routes.len()))
}
pub(crate) async fn handle_select(&self, select: Select) -> Result<Output> {
let Select::Sql(sql) = select;
let plan = self
.query_engine
.sql_to_plan(&sql)
.with_context(|_| error::ExecuteSqlSnafu { sql: sql.clone() })?;
self.query_engine
.execute(&plan)
.await
.context(error::ExecuteSqlSnafu { sql })
pub(crate) async fn handle_sql(&self, sql: &str, stmt: Statement) -> Result<Output> {
match stmt {
Statement::Query(_) => {
let plan = self
.query_engine
.statement_to_plan(stmt)
.context(error::ExecuteSqlSnafu { sql })?;
self.query_engine
.execute(&plan)
.await
.context(error::ExecuteSqlSnafu { sql })
}
Statement::ShowDatabases(stmt) => show_databases(stmt, self.catalog_manager.clone())
.context(error::ExecuteSqlSnafu { sql }),
Statement::ShowTables(stmt) => show_tables(stmt, self.catalog_manager.clone())
.context(error::ExecuteSqlSnafu { sql }),
_ => unreachable!(),
}
}
async fn create_table_in_meta(

View File

@@ -655,6 +655,8 @@ mod test {
}
#[tokio::test(flavor = "multi_thread")]
// FIXME(LFC): Remove ignore.
#[ignore]
async fn test_dist_table_scan() {
common_telemetry::init_default_ut_logging();
let table = Arc::new(new_dist_table().await);