Skip to content

Commit e2516e2

Browse files
authored
Implement DESCRIBE SELECT to show schema rather than EXPLAIN plan (#18238)
## Which issue does this PR close? <!-- We generally require a GitHub issue to be filed for all bug fixes and enhancements and this helps us generate change logs for our releases. You can link an issue to this PR using the GitHub syntax. For example `Closes #123` indicates that this PR will close issue #123. --> - Closes #18234. ## Rationale for this change <!-- Why are you proposing this change? If this is already explained clearly in the issue then this section is not needed. Explaining clearly why changes are proposed helps reviewers understand your changes and offer better suggestions for fixes. --> https://discord.com/channels/885562378132000778/1430237388474552380/1430618776751313018 ## What changes are included in this PR? <!-- There is no need to duplicate the description in the issue here but it is sometimes worth providing a summary of the individual changes in this PR. --> ``` cargo run -q --bin datafusion-cli DataFusion CLI v50.3.0 > DESCRIBE SELECT 1; +-------------+-----------+-------------+ | column_name | data_type | is_nullable | +-------------+-----------+-------------+ | Int64(1) | Int64 | NO | +-------------+-----------+-------------+ 1 row(s) fetched. Elapsed 0.022 seconds. ``` ## Are these changes tested? No, looking for feedback on approach first... happy to add a test. <!-- We typically require tests for all PRs in order to: 1. Prevent the code from being accidentally broken by subsequent changes 2. Serve as another way to document the expected behavior of the code If tests are not included in your PR, please explain why (for example, are they covered by existing tests)? --> ## Are there any user-facing changes? Yes, it changes to behavior of `DESCRIBE SELECT` from explaining the physical plan (EXPLAIN) to describing the schema of the query (like DESCRIBE table). <!-- If there are user-facing changes then we may require documentation to be updated before approving the PR. --> <!-- If there are any breaking changes to public APIs, please add the `api change` label. -->
1 parent 2bb7bf6 commit e2516e2

File tree

3 files changed

+55
-0
lines changed

3 files changed

+55
-0
lines changed

datafusion/sql/src/statement.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,16 @@ impl<S: ContextProvider> SqlToRel<'_, S> {
242242
table_name,
243243
..
244244
} => self.describe_table_to_plan(table_name),
245+
Statement::Explain {
246+
describe_alias: DescribeAlias::Describe | DescribeAlias::Desc, // only parse 'DESCRIBE statement' or 'DESC statement' and not 'EXPLAIN statement'
247+
statement,
248+
..
249+
} => match *statement {
250+
Statement::Query(query) => self.describe_query_to_plan(*query),
251+
_ => {
252+
not_impl_err!("Describing statements other than SELECT not supported")
253+
}
254+
},
245255
Statement::Explain {
246256
verbose,
247257
statement,
@@ -1399,6 +1409,19 @@ impl<S: ContextProvider> SqlToRel<'_, S> {
13991409
}))
14001410
}
14011411

1412+
fn describe_query_to_plan(&self, query: Query) -> Result<LogicalPlan> {
1413+
let plan = self.query_to_plan(query, &mut PlannerContext::new())?;
1414+
1415+
let schema = Arc::new(plan.schema().as_arrow().clone());
1416+
1417+
let output_schema = DFSchema::try_from(LogicalPlan::describe_schema()).unwrap();
1418+
1419+
Ok(LogicalPlan::DescribeTable(DescribeTable {
1420+
schema,
1421+
output_schema: Arc::new(output_schema),
1422+
}))
1423+
}
1424+
14021425
fn copy_to_plan(&self, statement: CopyToStatement) -> Result<LogicalPlan> {
14031426
// Determine if source is table or query and handle accordingly
14041427
let copy_source = statement.source;

datafusion/sqllogictest/test_files/describe.slt

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,3 +116,29 @@ col1 Int32 YES
116116
# Test error cases
117117
statement error
118118
DESC nonexistent_table;
119+
120+
##########
121+
# Describe statement
122+
##########
123+
124+
# Test describing the schema of a simple statement
125+
query TTT
126+
DESCRIBE SELECT 1;
127+
----
128+
Int64(1) Int64 NO
129+
130+
# Insert some data into the existing test table...
131+
statement ok
132+
INSERT INTO test_desc_table (id, name) VALUES (1, 'Alice'), (2, 'Bob'), (3, 'Charlie'), (4, 'Alice');
133+
134+
# ... and describe the schema of a more complex query
135+
query TTT
136+
DESCRIBE SELECT name, COUNT(*) AS name_count FROM test_desc_table
137+
GROUP BY name HAVING COUNT(*) > 1 ORDER BY name_count DESC;
138+
----
139+
name Utf8View YES
140+
name_count Int64 NO
141+
142+
# Describing a statement that's not a query is not supported
143+
statement error Describing statements other than SELECT not supported
144+
DESCRIBE CREATE TABLE test_desc_table (id INT, name VARCHAR);

docs/source/library-user-guide/upgrading.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,12 @@ Users may need to update their paths to account for these changes.
116116

117117
See [issue #17713] for more details.
118118

119+
### `DESCRIBE query` support
120+
121+
`DESCRIBE query` was previously an alias for `EXPLAIN query`, which outputs the
122+
_execution plan_ of the query. With this release, `DESCRIBE query` now outputs
123+
the computed _schema_ of the query, consistent with the behavior of `DESCRIBE table_name`.
124+
119125
## DataFusion `50.0.0`
120126

121127
### ListingTable automatically detects Hive Partitioned tables

0 commit comments

Comments
 (0)