From da6edef4b0cc965a26fe089c518d8bbb22fe4016 Mon Sep 17 00:00:00 2001 From: Lilit0x Date: Fri, 15 Sep 2023 19:52:07 +0100 Subject: [PATCH 1/8] feat: added show tables command --- src/query/src/sql.rs | 39 ++++++++++++++++++++++++++++-- src/sql/src/parsers/show_parser.rs | 32 ++++++++++++++++++++++++ src/sql/src/statements/show.rs | 19 +++++++++++++++ 3 files changed, 88 insertions(+), 2 deletions(-) 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!(); + } + } + } } From 72a3634e3af958126c4242bd49d2604b09cb3fec Mon Sep 17 00:00:00 2001 From: Lilit0x Date: Sat, 16 Sep 2023 08:23:26 +0100 Subject: [PATCH 2/8] fix(tests): fixed parser and statement unit tests --- src/sql/src/parsers/show_parser.rs | 4 ++-- src/sql/src/statements/show.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sql/src/parsers/show_parser.rs b/src/sql/src/parsers/show_parser.rs index 872c135c4f8c..ee605d6bd7dc 100644 --- a/src/sql/src/parsers/show_parser.rs +++ b/src/sql/src/parsers/show_parser.rs @@ -323,9 +323,9 @@ mod tests { 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 { .. }); + assert_matches!(&stmts[0], Statement::ShowTables { .. }); match &stmts[0] { - Statement::ShowDatabases(show) => { + Statement::ShowTables(show) => { assert_eq!(ShowKind::Full, show.kind); } _ => { diff --git a/src/sql/src/statements/show.rs b/src/sql/src/statements/show.rs index 33ac85f2a69c..b5f8e631725d 100644 --- a/src/sql/src/statements/show.rs +++ b/src/sql/src/statements/show.rs @@ -146,9 +146,9 @@ mod tests { 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 { .. }); + assert_matches!(&stmts[0], Statement::ShowTables { .. }); match &stmts[0] { - Statement::ShowDatabases(show) => { + Statement::ShowTables(show) => { assert_eq!(ShowKind::Full, show.kind); } _ => { From 6c6fb1163031cfa111feffa6bfc8e9eb5271e2ca Mon Sep 17 00:00:00 2001 From: Lilit0x Date: Sat, 16 Sep 2023 08:42:03 +0100 Subject: [PATCH 3/8] chore: implemeted display trait for table type --- src/query/src/sql.rs | 9 ++------- src/table/src/metadata.rs | 10 ++++++++++ 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/query/src/sql.rs b/src/query/src/sql.rs index 08a1f43b6d49..f788e13fda8c 100644 --- a/src/query/src/sql.rs +++ b/src/query/src/sql.rs @@ -184,7 +184,7 @@ pub async fn show_tables( Ok(Output::RecordBatches(records)) } ShowKind::Full => { - let mut table_types = Vec::new(); + let mut table_types = Vec::with_capacity(tables.len()); for table_name in &tables { let table_type = catalog_manager .table(query_ctx.current_catalog(), &schema_name, table_name) @@ -193,12 +193,7 @@ pub async fn show_tables( .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); + table_types.push(format!("{table_type}")); } let table_types = Arc::new(StringVector::from(table_types)) as _; diff --git a/src/table/src/metadata.rs b/src/table/src/metadata.rs index ad1c7eb3571f..97d26d2748f1 100644 --- a/src/table/src/metadata.rs +++ b/src/table/src/metadata.rs @@ -80,6 +80,16 @@ pub enum TableType { Temporary, } +impl std::fmt::Display for TableType { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + TableType::Base => f.write_str("BASE TABLE"), + TableType::Temporary => f.write_str("TEMPORARY"), + TableType::View => f.write_str("VIEW"), + } + } +} + /// Identifier of the table. #[derive(Serialize, Deserialize, Clone, Debug, Eq, PartialEq, Default)] pub struct TableIdent { From 5cb65c054067810fd72550cf4ed580de8be0180d Mon Sep 17 00:00:00 2001 From: Lilit0x Date: Sat, 16 Sep 2023 19:33:14 +0100 Subject: [PATCH 4/8] fix: handled no tabletype and error for usopprted command in show databse --- src/query/src/sql.rs | 11 +++++------ src/sql/src/statements/show.rs | 16 ---------------- 2 files changed, 5 insertions(+), 22 deletions(-) diff --git a/src/query/src/sql.rs b/src/query/src/sql.rs index f788e13fda8c..9b5910276ea0 100644 --- a/src/query/src/sql.rs +++ b/src/query/src/sql.rs @@ -135,7 +135,7 @@ pub async fn show_databases( .context(error::CreateRecordBatchSnafu)?; Ok(Output::RecordBatches(records)) } - ShowKind::Full => todo!(), + ShowKind::Full => error::UnsupportedExprSnafu { name: "FULL" }.fail()?, } } @@ -186,14 +186,13 @@ pub async fn show_tables( ShowKind::Full => { let mut table_types = Vec::with_capacity(tables.len()); for table_name in &tables { - let table_type = catalog_manager + if let Some(table_type) = catalog_manager .table(query_ctx.current_catalog(), &schema_name, table_name) .await .context(error::CatalogSnafu)? - .unwrap() - .table_type(); - - table_types.push(format!("{table_type}")); + { + table_types.push(table_type.table_type().to_string()); + } } let table_types = Arc::new(StringVector::from(table_types)) as _; diff --git a/src/sql/src/statements/show.rs b/src/sql/src/statements/show.rs index b5f8e631725d..e3f7fa0b1132 100644 --- a/src/sql/src/statements/show.rs +++ b/src/sql/src/statements/show.rs @@ -140,20 +140,4 @@ 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::ShowTables { .. }); - match &stmts[0] { - Statement::ShowTables(show) => { - assert_eq!(ShowKind::Full, show.kind); - } - _ => { - unreachable!(); - } - } - } } From 009a3d12fcabb6d85b83adc21a410986448e0a8a Mon Sep 17 00:00:00 2001 From: Lilit0x Date: Wed, 20 Sep 2023 08:44:04 +0100 Subject: [PATCH 5/8] chore: removed full as a show kind, instead as a show option --- src/query/src/sql.rs | 99 ++++++++++++++++++++---------- src/sql/src/parsers/show_parser.rs | 30 ++++----- src/sql/src/statements/show.rs | 4 +- 3 files changed, 83 insertions(+), 50 deletions(-) diff --git a/src/query/src/sql.rs b/src/query/src/sql.rs index 9f2e86be6f04..2b7b94a16646 100644 --- a/src/query/src/sql.rs +++ b/src/query/src/sql.rs @@ -136,7 +136,6 @@ pub async fn show_databases( .context(error::CreateRecordBatchSnafu)?; Ok(Output::RecordBatches(records)) } - ShowKind::Full => error::UnsupportedExprSnafu { name: "FULL" }.fail()?, } } @@ -158,20 +157,55 @@ pub async fn show_tables( // TODO(dennis): Specify the order of the results in schema provider API tables.sort(); - let schema = Arc::new(Schema::new(vec![ColumnSchema::new( + + let table_types: Option> = { + if stmt.full { + Some( + get_table_types( + &tables, + catalog_manager.clone(), + query_ctx.clone(), + &schema_name, + ) + .await?, + ) + } else { + None + } + }; + + let mut column_schema = vec![ColumnSchema::new( TABLES_COLUMN, ConcreteDataType::string_datatype(), false, - )])); + )]; + if table_types.is_some() { + column_schema.push(ColumnSchema::new( + "Table_type", + ConcreteDataType::string_datatype(), + false, + )); + } + + let schema = Arc::new(Schema::new(column_schema)); + match stmt.kind { ShowKind::All => { let tables = Arc::new(StringVector::from(tables)) as _; - let records = RecordBatches::try_from_columns(schema, vec![tables]) + let mut columns = vec![tables]; + if let Some(table_types) = table_types { + columns.push(table_types) + } + + let records = RecordBatches::try_from_columns(schema, columns) .context(error::CreateRecordBatchSnafu)?; Ok(Output::RecordBatches(records)) } ShowKind::Where(filter) => { - let columns = vec![Arc::new(StringVector::from(tables)) as _]; + let mut columns = vec![Arc::new(StringVector::from(tables)) as _]; + if let Some(table_types) = table_types { + columns.push(table_types) + } let record_batch = RecordBatch::new(schema, columns).context(error::CreateRecordBatchSnafu)?; let result = execute_show_with_filter(record_batch, Some(filter)).await?; @@ -180,35 +214,17 @@ pub async fn show_tables( ShowKind::Like(ident) => { let tables = Helper::like_utf8(tables, &ident.value).context(error::VectorComputationSnafu)?; - let records = RecordBatches::try_from_columns(schema, vec![tables]) - .context(error::CreateRecordBatchSnafu)?; - Ok(Output::RecordBatches(records)) - } - ShowKind::Full => { - let mut table_types = Vec::with_capacity(tables.len()); - for table_name in &tables { - if let Some(table_type) = catalog_manager - .table(query_ctx.current_catalog(), &schema_name, table_name) - .await - .context(error::CatalogSnafu)? - { - table_types.push(table_type.table_type().to_string()); - } + let mut columns = vec![tables.clone()]; + if stmt.full { + //convert to string + let tables = (0..tables.len()) + .map(|i| tables.get(i).to_string()) + .collect::>(); + columns + .push(get_table_types(&tables, catalog_manager, query_ctx, &schema_name).await?) } - 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]) + let records = RecordBatches::try_from_columns(schema, columns) .context(error::CreateRecordBatchSnafu)?; Ok(Output::RecordBatches(records)) } @@ -481,6 +497,25 @@ fn parse_file_table_format(options: &HashMap) -> Result, + catalog_manager: CatalogManagerRef, + query_ctx: QueryContextRef, + schema_name: &str, +) -> Result> { + let mut table_types: Vec = Vec::with_capacity(tables.len()); + for table_name in tables { + if let Some(table_type) = catalog_manager + .table(query_ctx.current_catalog(), schema_name, table_name) + .await + .context(error::CatalogSnafu)? + { + table_types.push(table_type.table_type().to_string()); + } + } + Ok(Arc::new(StringVector::from(table_types)) as _) +} + #[cfg(test)] mod test { use std::sync::Arc; diff --git a/src/sql/src/parsers/show_parser.rs b/src/sql/src/parsers/show_parser.rs index ee605d6bd7dc..7f5a496c7f87 100644 --- a/src/sql/src/parsers/show_parser.rs +++ b/src/sql/src/parsers/show_parser.rs @@ -30,7 +30,7 @@ impl<'a> ParserContext<'a> { self.parse_show_databases() } else if self.matches_keyword(Keyword::TABLES) { let _ = self.parser.next_token(); - self.parse_show_tables() + self.parse_show_tables(false) } else if self.consume_token("CREATE") { if self.consume_token("TABLE") { self.parse_show_create_table() @@ -39,7 +39,7 @@ impl<'a> ParserContext<'a> { } } else if self.consume_token("FULL") { if self.consume_token("TABLES") { - self.parse_show_full_tables() + self.parse_show_tables(true) } else { self.unsupported(self.peek_token_as_string()) } @@ -48,16 +48,6 @@ impl<'a> ParserContext<'a> { } } - 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 = @@ -77,12 +67,13 @@ impl<'a> ParserContext<'a> { Ok(Statement::ShowCreateTable(ShowCreateTable { table_name })) } - fn parse_show_tables(&mut self) -> Result { + fn parse_show_tables(&mut self, full: bool) -> Result { let database = match self.parser.peek_token().token { Token::EOF | Token::SemiColon => { return Ok(Statement::ShowTables(ShowTables { kind: ShowKind::All, database: None, + full, })); } @@ -142,7 +133,11 @@ impl<'a> ParserContext<'a> { _ => return self.unsupported(self.peek_token_as_string()), }; - Ok(Statement::ShowTables(ShowTables { kind, database })) + Ok(Statement::ShowTables(ShowTables { + kind, + database, + full, + })) } /// Parses `SHOW DATABASES` statement. @@ -250,6 +245,7 @@ mod tests { Statement::ShowTables(ShowTables { kind: ShowKind::All, database: None, + full: false }) ); } @@ -269,6 +265,7 @@ mod tests { quote_style: None, }), database: None, + full: false }) ); @@ -285,6 +282,7 @@ mod tests { quote_style: None, }), database: Some(_), + full: false }) ); } @@ -301,6 +299,7 @@ mod tests { Statement::ShowTables(ShowTables { kind: ShowKind::Where(sqlparser::ast::Expr::Like { .. }), database: None, + full: false }) ); @@ -314,6 +313,7 @@ mod tests { Statement::ShowTables(ShowTables { kind: ShowKind::Where(sqlparser::ast::Expr::Like { .. }), database: Some(_), + full: false }) ); } @@ -326,7 +326,7 @@ mod tests { assert_matches!(&stmts[0], Statement::ShowTables { .. }); match &stmts[0] { Statement::ShowTables(show) => { - assert_eq!(ShowKind::Full, show.kind); + assert!(!show.full); } _ => { unreachable!(); diff --git a/src/sql/src/statements/show.rs b/src/sql/src/statements/show.rs index 17e2d23a25d9..b0d712142863 100644 --- a/src/sql/src/statements/show.rs +++ b/src/sql/src/statements/show.rs @@ -22,7 +22,6 @@ use crate::ast::{Expr, Ident, ObjectName}; #[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut)] pub enum ShowKind { All, - Full, Like(Ident), Where(Expr), } @@ -31,7 +30,6 @@ 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}"), } @@ -56,6 +54,7 @@ impl ShowDatabases { pub struct ShowTables { pub kind: ShowKind, pub database: Option, + pub full: bool, } /// SQL structure for `SHOW CREATE TABLE`. @@ -78,7 +77,6 @@ mod tests { #[test] fn test_kind_display() { assert_eq!("ALL", format!("{}", ShowKind::All)); - assert_eq!("FULL", format!("{}", ShowKind::Full)); assert_eq!( "LIKE test", format!( From 63183b57c70906b280a80999f20f062ad7fa8247 Mon Sep 17 00:00:00 2001 From: Lilit0x Date: Wed, 20 Sep 2023 09:23:24 +0100 Subject: [PATCH 6/8] chore(tests): fixed failing test and added more tests for show full --- src/sql/src/parsers/show_parser.rs | 55 +++++++++++++++++++++++++++++- 1 file changed, 54 insertions(+), 1 deletion(-) diff --git a/src/sql/src/parsers/show_parser.rs b/src/sql/src/parsers/show_parser.rs index 7f5a496c7f87..48a64e86ec5f 100644 --- a/src/sql/src/parsers/show_parser.rs +++ b/src/sql/src/parsers/show_parser.rs @@ -326,11 +326,64 @@ mod tests { assert_matches!(&stmts[0], Statement::ShowTables { .. }); match &stmts[0] { Statement::ShowTables(show) => { - assert!(!show.full); + assert!(show.full); } _ => { unreachable!(); } } } + + #[test] + pub fn test_show_full_tables_where() { + let sql = "SHOW FULL TABLES IN test_db WHERE Tables LIKE test_table"; + let stmts = ParserContext::create_with_dialect(sql, &GreptimeDbDialect {}).unwrap(); + assert_eq!(1, stmts.len()); + + assert_matches!( + &stmts[0], + Statement::ShowTables(ShowTables { + kind: ShowKind::Where(sqlparser::ast::Expr::Like { .. }), + database: Some(_), + full: true + }) + ); + } + + #[test] + pub fn test_show_full_tables_like() { + let sql = "SHOW FULL TABLES LIKE test_table"; + let result = ParserContext::create_with_dialect(sql, &GreptimeDbDialect {}); + let stmts = result.unwrap(); + assert_eq!(1, stmts.len()); + + assert_matches!( + &stmts[0], + Statement::ShowTables(ShowTables { + kind: ShowKind::Like(sqlparser::ast::Ident { + value: _, + quote_style: None, + }), + database: None, + full: true + }) + ); + + let sql = "SHOW FULL TABLES in test_db LIKE test_table"; + let result = ParserContext::create_with_dialect(sql, &GreptimeDbDialect {}); + let stmts = result.unwrap(); + assert_eq!(1, stmts.len()); + + assert_matches!( + &stmts[0], + Statement::ShowTables(ShowTables { + kind: ShowKind::Like(sqlparser::ast::Ident { + value: _, + quote_style: None, + }), + database: Some(_), + full: true + }) + ); + } } From e70e80edc0bc76e1d9746cf35797411df79af406 Mon Sep 17 00:00:00 2001 From: Lilit0x Date: Wed, 20 Sep 2023 11:53:54 +0100 Subject: [PATCH 7/8] chore: refactored table types to use filters --- src/datatypes/src/vectors/helper.rs | 40 +++++++++++++++++++++++++++++ src/query/src/sql.rs | 21 ++++++++------- 2 files changed, 50 insertions(+), 11 deletions(-) diff --git a/src/datatypes/src/vectors/helper.rs b/src/datatypes/src/vectors/helper.rs index 37e2cbb47be7..8d3128411259 100644 --- a/src/datatypes/src/vectors/helper.rs +++ b/src/datatypes/src/vectors/helper.rs @@ -350,6 +350,15 @@ impl Helper { let result = compute::filter(&array, &filter).context(error::ArrowComputeSnafu)?; Helper::try_into_vector(result) } + + pub fn like_utf8_filter(names: Vec, s: &str) -> Result<(VectorRef, BooleanVector)> { + let array = StringArray::from(names); + let filter = comparison::like_utf8_scalar(&array, s).context(error::ArrowComputeSnafu)?; + let result = compute::filter(&array, &filter).context(error::ArrowComputeSnafu)?; + let vector = Helper::try_into_vector(result)?; + + Ok((vector, BooleanVector::from(filter))) + } } #[cfg(test)] @@ -463,6 +472,37 @@ mod tests { assert_vector(vec!["greptime", "hello", "public", "world"], &ret); } + #[test] + fn test_like_utf8_filter() { + fn assert_vector(expected: Vec<&str>, actual: &VectorRef) { + let actual = actual.as_any().downcast_ref::().unwrap(); + assert_eq!(*actual, StringVector::from(expected)); + } + + fn assert_filter(array: Vec, s: &str, expected_filter: &BooleanVector) { + let array = StringArray::from(array); + let actual_filter = comparison::like_utf8_scalar(&array, s).unwrap(); + assert_eq!(BooleanVector::from(actual_filter), *expected_filter); + } + + let names: Vec = vec!["greptime", "timeseries", "cloud", "database"] + .into_iter() + .map(|x| x.to_string()) + .collect(); + + let (table, filter) = Helper::like_utf8_filter(names.clone(), "%ti%").unwrap(); + assert_vector(vec!["greptime", "timeseries"], &table); + assert_filter(names.clone(), "%ti%", &filter); + + let (tables, filter) = Helper::like_utf8_filter(names.clone(), "%lou").unwrap(); + assert_vector(vec![], &tables); + assert_filter(names.clone(), "%lou", &filter); + + let (tables, filter) = Helper::like_utf8_filter(names.clone(), "%d%").unwrap(); + assert_vector(vec!["cloud", "database"], &tables); + assert_filter(names.clone(), "%d%", &filter); + } + fn check_try_into_vector(array: impl Array + 'static) { let array: ArrayRef = Arc::new(array); let vector = Helper::try_into_vector(array.clone()).unwrap(); diff --git a/src/query/src/sql.rs b/src/query/src/sql.rs index 2b7b94a16646..a0cfc4f9a133 100644 --- a/src/query/src/sql.rs +++ b/src/query/src/sql.rs @@ -212,16 +212,15 @@ pub async fn show_tables( Ok(result) } ShowKind::Like(ident) => { - let tables = - Helper::like_utf8(tables, &ident.value).context(error::VectorComputationSnafu)?; + let (tables, filter) = Helper::like_utf8_filter(tables, &ident.value) + .context(error::VectorComputationSnafu)?; let mut columns = vec![tables.clone()]; - if stmt.full { - //convert to string - let tables = (0..tables.len()) - .map(|i| tables.get(i).to_string()) - .collect::>(); - columns - .push(get_table_types(&tables, catalog_manager, query_ctx, &schema_name).await?) + + if let Some(table_types) = table_types { + let table_types = table_types + .filter(&filter) + .context(error::VectorComputationSnafu)?; + columns.push(table_types) } let records = RecordBatches::try_from_columns(schema, columns) @@ -498,12 +497,12 @@ fn parse_file_table_format(options: &HashMap) -> Result, + tables: &[String], catalog_manager: CatalogManagerRef, query_ctx: QueryContextRef, schema_name: &str, ) -> Result> { - let mut table_types: Vec = Vec::with_capacity(tables.len()); + let mut table_types = Vec::with_capacity(tables.len()); for table_name in tables { if let Some(table_type) = catalog_manager .table(query_ctx.current_catalog(), schema_name, table_name) From b1c60738364c473c1568d82825abc40da947b13f Mon Sep 17 00:00:00 2001 From: Lilit0x Date: Wed, 20 Sep 2023 20:26:16 +0100 Subject: [PATCH 8/8] fix: changed table_type to tables --- src/query/src/sql.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/query/src/sql.rs b/src/query/src/sql.rs index a0cfc4f9a133..4369d4205c3e 100644 --- a/src/query/src/sql.rs +++ b/src/query/src/sql.rs @@ -214,7 +214,7 @@ pub async fn show_tables( ShowKind::Like(ident) => { let (tables, filter) = Helper::like_utf8_filter(tables, &ident.value) .context(error::VectorComputationSnafu)?; - let mut columns = vec![tables.clone()]; + let mut columns = vec![tables]; if let Some(table_types) = table_types { let table_types = table_types @@ -504,12 +504,12 @@ async fn get_table_types( ) -> Result> { let mut table_types = Vec::with_capacity(tables.len()); for table_name in tables { - if let Some(table_type) = catalog_manager + if let Some(table) = catalog_manager .table(query_ctx.current_catalog(), schema_name, table_name) .await .context(error::CatalogSnafu)? { - table_types.push(table_type.table_type().to_string()); + table_types.push(table.table_type().to_string()); } } Ok(Arc::new(StringVector::from(table_types)) as _)