diff --git a/src/query/src/sql.rs b/src/query/src/sql.rs index a978d74c6ce2..08a1f43b6d49 100644 --- a/src/query/src/sql.rs +++ b/src/query/src/sql.rs @@ -135,6 +135,7 @@ pub async fn show_databases( .context(error::CreateRecordBatchSnafu)?; Ok(Output::RecordBatches(records)) } + ShowKind::Full => todo!(), } } @@ -143,14 +144,14 @@ pub async fn show_tables( catalog_manager: CatalogManagerRef, query_ctx: QueryContextRef, ) -> Result { - let schema = if let Some(database) = stmt.database { + let schema_name = if let Some(database) = stmt.database { database } else { query_ctx.current_schema().to_owned() }; // TODO(sunng87): move this function into query_ctx let mut tables = catalog_manager - .table_names(query_ctx.current_catalog(), &schema) + .table_names(query_ctx.current_catalog(), &schema_name) .await .context(error::CatalogSnafu)?; @@ -182,6 +183,40 @@ pub async fn show_tables( .context(error::CreateRecordBatchSnafu)?; Ok(Output::RecordBatches(records)) } + ShowKind::Full => { + let mut table_types = Vec::new(); + for table_name in &tables { + let table_type = catalog_manager + .table(query_ctx.current_catalog(), &schema_name, table_name) + .await + .context(error::CatalogSnafu)? + .unwrap() + .table_type(); + + let table_type = match table_type { + table::metadata::TableType::Base => "BASE TABLE", + table::metadata::TableType::Temporary => "TEMPORARY", + table::metadata::TableType::View => "VIEW", + }; + table_types.push(table_type); + } + + let table_types = Arc::new(StringVector::from(table_types)) as _; + let tables = Arc::new(StringVector::from(tables)) as _; + + let schema = Arc::new(Schema::new(vec![ + ColumnSchema::new( + format!("Tables_in_{schema_name}"), + ConcreteDataType::string_datatype(), + false, + ), + ColumnSchema::new("Table_type", ConcreteDataType::string_datatype(), false), + ])); + + let records = RecordBatches::try_from_columns(schema, vec![tables, table_types]) + .context(error::CreateRecordBatchSnafu)?; + Ok(Output::RecordBatches(records)) + } } } diff --git a/src/sql/src/parsers/show_parser.rs b/src/sql/src/parsers/show_parser.rs index 90baef8ff6fc..872c135c4f8c 100644 --- a/src/sql/src/parsers/show_parser.rs +++ b/src/sql/src/parsers/show_parser.rs @@ -37,11 +37,27 @@ impl<'a> ParserContext<'a> { } else { self.unsupported(self.peek_token_as_string()) } + } else if self.consume_token("FULL") { + if self.consume_token("TABLES") { + self.parse_show_full_tables() + } else { + self.unsupported(self.peek_token_as_string()) + } } else { self.unsupported(self.peek_token_as_string()) } } + fn parse_show_full_tables(&mut self) -> Result { + match self.parser.peek_token().token { + Token::EOF | Token::SemiColon => Ok(Statement::ShowTables(ShowTables { + kind: ShowKind::Full, + database: None, + })), + _ => self.unsupported(self.peek_token_as_string()), + } + } + /// Parse SHOW CREATE TABLE statement fn parse_show_create_table(&mut self) -> Result { let table_name = @@ -301,4 +317,20 @@ mod tests { }) ); } + + #[test] + pub fn test_show_full_tables() { + let sql = "SHOW FULL TABLES"; + let stmts = ParserContext::create_with_dialect(sql, &GreptimeDbDialect {}).unwrap(); + assert_eq!(1, stmts.len()); + assert_matches!(&stmts[0], Statement::ShowDatabases { .. }); + match &stmts[0] { + Statement::ShowDatabases(show) => { + assert_eq!(ShowKind::Full, show.kind); + } + _ => { + unreachable!(); + } + } + } } diff --git a/src/sql/src/statements/show.rs b/src/sql/src/statements/show.rs index 409398227960..33ac85f2a69c 100644 --- a/src/sql/src/statements/show.rs +++ b/src/sql/src/statements/show.rs @@ -20,6 +20,7 @@ use crate::ast::{Expr, Ident, ObjectName}; #[derive(Debug, Clone, PartialEq, Eq)] pub enum ShowKind { All, + Full, Like(Ident), Where(Expr), } @@ -28,6 +29,7 @@ impl fmt::Display for ShowKind { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { ShowKind::All => write!(f, "ALL"), + ShowKind::Full => write!(f, "FULL"), ShowKind::Like(ident) => write!(f, "LIKE {ident}"), ShowKind::Where(expr) => write!(f, "WHERE {expr}"), } @@ -74,6 +76,7 @@ mod tests { #[test] fn test_kind_display() { assert_eq!("ALL", format!("{}", ShowKind::All)); + assert_eq!("FULL", format!("{}", ShowKind::Full)); assert_eq!( "LIKE test", format!( @@ -137,4 +140,20 @@ mod tests { let sql = "SHOW CREATE TABLE"; assert!(ParserContext::create_with_dialect(sql, &GreptimeDbDialect {}).is_err()); } + + #[test] + pub fn test_show_full_tables() { + let sql = "SHOW FULL TABLES"; + let stmts = ParserContext::create_with_dialect(sql, &GreptimeDbDialect {}).unwrap(); + assert_eq!(1, stmts.len()); + assert_matches!(&stmts[0], Statement::ShowDatabases { .. }); + match &stmts[0] { + Statement::ShowDatabases(show) => { + assert_eq!(ShowKind::Full, show.kind); + } + _ => { + unreachable!(); + } + } + } }