diff --git a/datafusion/sql/src/statement.rs b/datafusion/sql/src/statement.rs index 0e868e8c2689..54b28b1f191e 100644 --- a/datafusion/sql/src/statement.rs +++ b/datafusion/sql/src/statement.rs @@ -242,6 +242,16 @@ impl SqlToRel<'_, S> { table_name, .. } => self.describe_table_to_plan(table_name), + Statement::Explain { + describe_alias: DescribeAlias::Describe | DescribeAlias::Desc, // only parse 'DESCRIBE statement' or 'DESC statement' and not 'EXPLAIN statement' + statement, + .. + } => match *statement { + Statement::Query(query) => self.describe_query_to_plan(*query), + _ => { + not_impl_err!("Describing statements other than SELECT not supported") + } + }, Statement::Explain { verbose, statement, @@ -1396,6 +1406,19 @@ impl SqlToRel<'_, S> { })) } + fn describe_query_to_plan(&self, query: Query) -> Result { + let plan = self.query_to_plan(query, &mut PlannerContext::new())?; + + let schema = Arc::new(plan.schema().as_arrow().clone()); + + let output_schema = DFSchema::try_from(LogicalPlan::describe_schema()).unwrap(); + + Ok(LogicalPlan::DescribeTable(DescribeTable { + schema, + output_schema: Arc::new(output_schema), + })) + } + fn copy_to_plan(&self, statement: CopyToStatement) -> Result { // Determine if source is table or query and handle accordingly let copy_source = statement.source; diff --git a/datafusion/sqllogictest/test_files/describe.slt b/datafusion/sqllogictest/test_files/describe.slt index de5208b5483a..4c184c04d128 100644 --- a/datafusion/sqllogictest/test_files/describe.slt +++ b/datafusion/sqllogictest/test_files/describe.slt @@ -116,3 +116,29 @@ col1 Int32 YES # Test error cases statement error DESC nonexistent_table; + +########## +# Describe statement +########## + +# Test describing the schema of a simple statement +query TTT +DESCRIBE SELECT 1; +---- +Int64(1) Int64 NO + +# Insert some data into the existing test table... +statement ok +INSERT INTO test_desc_table (id, name) VALUES (1, 'Alice'), (2, 'Bob'), (3, 'Charlie'), (4, 'Alice'); + +# ... and describe the schema of a more complex query +query TTT +DESCRIBE SELECT name, COUNT(*) AS name_count FROM test_desc_table + GROUP BY name HAVING COUNT(*) > 1 ORDER BY name_count DESC; +---- +name Utf8View YES +name_count Int64 NO + +# Describing a statement that's not a query is not supported +statement error Describing statements other than SELECT not supported +DESCRIBE CREATE TABLE test_desc_table (id INT, name VARCHAR); diff --git a/docs/source/library-user-guide/upgrading.md b/docs/source/library-user-guide/upgrading.md index 8b03193e7f99..6b9cb0843c53 100644 --- a/docs/source/library-user-guide/upgrading.md +++ b/docs/source/library-user-guide/upgrading.md @@ -116,6 +116,12 @@ Users may need to update their paths to account for these changes. See [issue #17713] for more details. +### `DESCRIBE query` support + +`DESCRIBE query` was previously an alias for `EXPLAIN query`, which outputs the +_execution plan_ of the query. With this release, `DESCRIBE query` now outputs +the computed _schema_ of the query, consistent with the behavior of `DESCRIBE table_name`. + ## DataFusion `50.0.0` ### ListingTable automatically detects Hive Partitioned tables