diff --git a/rust/datafusion/src/execution/context.rs b/rust/datafusion/src/execution/context.rs index 3a7c24ddc3e..98a49ec1f60 100644 --- a/rust/datafusion/src/execution/context.rs +++ b/rust/datafusion/src/execution/context.rs @@ -2204,6 +2204,57 @@ mod tests { assert_batches_sorted_eq!(expected, &result); } + #[tokio::test] + async fn information_schema_show_tables_no_information_schema() { + let mut ctx = ExecutionContext::with_config(ExecutionConfig::new()); + + ctx.register_table("t", table_with_sequence(1, 1).unwrap()) + .unwrap(); + + // use show tables alias + let err = plan_and_collect(&mut ctx, "SHOW TABLES").await.unwrap_err(); + + assert_eq!(err.to_string(), "Error during planning: SHOW TABLES is not supported unless information_schema is enabled"); + } + + #[tokio::test] + async fn information_schema_show_tables() { + let mut ctx = ExecutionContext::with_config( + ExecutionConfig::new().with_information_schema(true), + ); + + ctx.register_table("t", table_with_sequence(1, 1).unwrap()) + .unwrap(); + + // use show tables alias + let result = plan_and_collect(&mut ctx, "SHOW TABLES").await.unwrap(); + + let expected = vec![ + "+---------------+--------------------+------------+------------+", + "| table_catalog | table_schema | table_name | table_type |", + "+---------------+--------------------+------------+------------+", + "| datafusion | information_schema | tables | VIEW |", + "| datafusion | public | t | BASE TABLE |", + "+---------------+--------------------+------------+------------+", + ]; + assert_batches_sorted_eq!(expected, &result); + + let result = plan_and_collect(&mut ctx, "SHOW tables").await.unwrap(); + + assert_batches_sorted_eq!(expected, &result); + } + + #[tokio::test] + async fn show_unsupported() { + let mut ctx = ExecutionContext::with_config(ExecutionConfig::new()); + + let err = plan_and_collect(&mut ctx, "SHOW SOMETHING_UNKNOWN") + .await + .unwrap_err(); + + assert_eq!(err.to_string(), "This feature is not implemented: SHOW SOMETHING_UNKNOWN not implemented. Supported syntax: SHOW "); + } + #[tokio::test] async fn disabled_default_catalog_and_schema() -> Result<()> { let mut ctx = ExecutionContext::with_config( diff --git a/rust/datafusion/src/sql/planner.rs b/rust/datafusion/src/sql/planner.rs index 7b62a4feac3..5d638a3e449 100644 --- a/rust/datafusion/src/sql/planner.rs +++ b/rust/datafusion/src/sql/planner.rs @@ -45,16 +45,19 @@ use hashbrown::HashMap; use crate::prelude::JoinType; use sqlparser::ast::{ BinaryOperator, DataType as SQLDataType, DateTimeField, Expr as SQLExpr, FunctionArg, - Join, JoinConstraint, JoinOperator, Query, Select, SelectItem, SetExpr, SetOperator, - TableFactor, TableWithJoins, UnaryOperator, Value, + Ident, Join, JoinConstraint, JoinOperator, ObjectName, Query, Select, SelectItem, + SetExpr, SetOperator, TableFactor, TableWithJoins, UnaryOperator, Value, }; use sqlparser::ast::{ColumnDef as SQLColumnDef, ColumnOption}; use sqlparser::ast::{OrderByExpr, Statement}; use sqlparser::parser::ParserError::ParserError; -use super::utils::{ - can_columns_satisfy_exprs, expand_wildcard, expr_as_column_expr, extract_aliases, - find_aggregate_exprs, find_column_exprs, rebase_expr, resolve_aliases_to_exprs, +use super::{ + parser::DFParser, + utils::{ + can_columns_satisfy_exprs, expand_wildcard, expr_as_column_expr, extract_aliases, + find_aggregate_exprs, find_column_exprs, rebase_expr, resolve_aliases_to_exprs, + }, }; /// The ContextProvider trait allows the query planner to obtain meta-data about tables and @@ -96,6 +99,7 @@ impl<'a, S: ContextProvider> SqlToRel<'a, S> { analyze: _, } => self.explain_statement_to_plan(*verbose, &statement), Statement::Query(query) => self.query_to_plan(&query), + Statement::ShowVariable { variable } => self.show_variable_to_plan(&variable), _ => Err(DataFusionError::NotImplemented( "Only SELECT statements are implemented".to_string(), )), @@ -1271,6 +1275,36 @@ impl<'a, S: ContextProvider> SqlToRel<'a, S> { let result: i64 = (result_days << 32) | result_millis; Ok(Expr::Literal(ScalarValue::IntervalDayTime(Some(result)))) } + + fn show_variable_to_plan(&self, variable: &[Ident]) -> Result { + // Special case SHOW TABLES + let variable = ObjectName(variable.to_vec()).to_string(); + if variable.as_str().eq_ignore_ascii_case("tables") { + let tables_reference = TableReference::Partial { + schema: "information_schema", + table: "tables", + }; + if self + .schema_provider + .get_table_provider(tables_reference) + .is_some() + { + let rewrite = + DFParser::parse_sql("SELECT * FROM information_schema.tables;")?; + self.statement_to_plan(&rewrite[0]) + } else { + Err(DataFusionError::Plan( + "SHOW TABLES is not supported unless information_schema is enabled" + .to_string(), + )) + } + } else { + Err(DataFusionError::NotImplemented(format!( + "SHOW {} not implemented. Supported syntax: SHOW ", + variable + ))) + } + } } /// Remove join expressions from a filter expression