diff --git a/datafusion/sql/src/select.rs b/datafusion/sql/src/select.rs index c7ccda7232e2a..1a90e5e09b778 100644 --- a/datafusion/sql/src/select.rs +++ b/datafusion/sql/src/select.rs @@ -664,6 +664,15 @@ impl SqlToRel<'_, S> { ) -> Result> { let mut prepared_select_exprs = vec![]; let mut error_builder = DataFusionErrorBuilder::new(); + + // Handle the case where no projection is specified but we have a valid FROM clause + // In this case, implicitly add a wildcard projection (SELECT *) + let projection = if projection.is_empty() && !empty_from { + vec![SelectItem::Wildcard(WildcardAdditionalOptions::default())] + } else { + projection + }; + for expr in projection { match self.sql_select_to_rex(expr, plan, empty_from, planner_context) { Ok(expr) => prepared_select_exprs.push(expr), diff --git a/datafusion/sqllogictest/test_files/from-first.slt b/datafusion/sqllogictest/test_files/from-first.slt new file mode 100644 index 0000000000000..c4a305e85ea77 --- /dev/null +++ b/datafusion/sqllogictest/test_files/from-first.slt @@ -0,0 +1,55 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at + +# http://www.apache.org/licenses/LICENSE-2.0 + +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +query I +FROM range(2) +---- +0 +1 + +query I +FROM range(2) +SELECT * +---- +0 +1 + +query I +FROM (SELECT * FROM range(2)) +---- +0 +1 + +query I +FROM (FROM range(2)) +---- +0 +1 + +query I +FROM range(2) +SELECT 1 +---- +1 +1 + +query I +FROM range(2) as r +SELECT r.value +---- +0 +1 diff --git a/docs/source/user-guide/sql/select.md b/docs/source/user-guide/sql/select.md index 39163cf492a4a..eb8bca7a75ef0 100644 --- a/docs/source/user-guide/sql/select.md +++ b/docs/source/user-guide/sql/select.md @@ -75,6 +75,20 @@ Example: SELECT t.a FROM table AS t ``` +The `FROM` clause can also come before the `SELECT` clause. +Example: + +```sql +FROM table AS t +SELECT t.a +``` + +If the `SELECT` clause is omitted, the `FROM` clause will return all columns from the table. + +```sql +FROM table +``` + ## WHERE clause Example: