mirror of
https://github.com/GreptimeTeam/greptimedb.git
synced 2026-05-31 20:30:37 +00:00
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:
@@ -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,
|
||||
|
||||
@@ -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(),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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 }),
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user