@@ -17,11 +17,14 @@ use datafusion::{
1717} ;
1818use futures:: TryStreamExt ;
1919use snafu:: prelude:: * ;
20- use std:: fmt:: { Display , Formatter } ;
2120use std:: { any:: Any , fmt, sync:: Arc } ;
21+ use std:: {
22+ fmt:: { Display , Formatter } ,
23+ sync:: LazyLock ,
24+ } ;
2225
2326use datafusion:: {
24- arrow:: datatypes:: SchemaRef ,
27+ arrow:: datatypes:: { DataType , Field , Schema , SchemaRef } ,
2528 datasource:: TableProvider ,
2629 error:: { DataFusionError , Result as DataFusionResult } ,
2730 execution:: TaskContext ,
@@ -238,14 +241,20 @@ impl<T, P> Display for SqlTable<T, P> {
238241 }
239242}
240243
244+ static ONE_COLUMN_SCHEMA : LazyLock < SchemaRef > =
245+ LazyLock :: new ( || Arc :: new ( Schema :: new ( vec ! [ Field :: new( "1" , DataType :: Int64 , false ) ] ) ) ) ;
246+
241247pub fn project_schema_safe (
242248 schema : & SchemaRef ,
243249 projection : Option < & Vec < usize > > ,
244250) -> DataFusionResult < SchemaRef > {
245251 let schema = match projection {
246252 Some ( columns) => {
247253 if columns. is_empty ( ) {
248- Arc :: clone ( schema)
254+ // If the projection is Some([]) then it gets unparsed as `SELECT 1`, so return a schema with a single Int64 column.
255+ //
256+ // See: <https://github.com/apache/datafusion/blob/83ce79c39412a4f150167d00e40ea05948c4870f/datafusion/sql/src/unparser/plan.rs#L998>
257+ Arc :: clone ( & ONE_COLUMN_SCHEMA )
249258 } else {
250259 Arc :: new ( schema. project ( columns) ?)
251260 }
0 commit comments