You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@datafusion.apache.org by lu...@apache.org on 2026/10/03 06:44:12 UTC

(datafusion-sqlparser-rs) branch upstream/postgres-bare-select created (now 178ca568)

This is an automated email from the ASF dual-hosted git repository.

LucaCappelletti94 pushed a change to branch upstream/postgres-bare-select
in repository https://gitbox.apache.org/repos/asf/datafusion-sqlparser-rs.git


      at 178ca568 PostgreSQL: Parse an empty SELECT target list without FROM

This branch includes the following new commits:

     new 178ca568 PostgreSQL: Parse an empty SELECT target list without FROM

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@datafusion.apache.org
For additional commands, e-mail: commits-help@datafusion.apache.org


(datafusion-sqlparser-rs) 01/01: PostgreSQL: Parse an empty SELECT target list without FROM

Posted by lu...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

LucaCappelletti94 pushed a commit to branch upstream/postgres-bare-select
in repository https://gitbox.apache.org/repos/asf/datafusion-sqlparser-rs.git

commit 178ca56888595450605f024656d4b2d2e9504196
Author: LucaCappelletti94 <ca...@gmail.com>
AuthorDate: Sat Oct 3 08:44:02 2026 +0200

    PostgreSQL: Parse an empty SELECT target list without FROM
---
 src/parser/mod.rs         | 27 ++++++++++++++++++++++++++-
 tests/sqlparser_common.rs | 37 +++++++++++++++++++++++++++++++++++++
 2 files changed, 63 insertions(+), 1 deletion(-)

diff --git a/src/parser/mod.rs b/src/parser/mod.rs
index 1a46c6e5..0a5f1a7a 100644
--- a/src/parser/mod.rs
+++ b/src/parser/mod.rs
@@ -15462,7 +15462,7 @@ impl<'a> Parser<'a> {
         }
 
         let projection =
-            if self.dialect.supports_empty_projections() && self.peek_keyword(Keyword::FROM) {
+            if self.dialect.supports_empty_projections() && self.peek_empty_projection() {
                 vec![]
             } else {
                 self.parse_projection()?
@@ -15623,6 +15623,31 @@ impl<'a> Parser<'a> {
         })
     }
 
+    /// Returns true if the next token ends a `SELECT` target list before it begins.
+    fn peek_empty_projection(&self) -> bool {
+        match &self.peek_token_ref().token {
+            Token::EOF | Token::SemiColon | Token::RParen => true,
+            Token::Word(w) => matches!(
+                w.keyword,
+                Keyword::INTO
+                    | Keyword::FROM
+                    | Keyword::WHERE
+                    | Keyword::GROUP
+                    | Keyword::HAVING
+                    | Keyword::WINDOW
+                    | Keyword::ORDER
+                    | Keyword::LIMIT
+                    | Keyword::OFFSET
+                    | Keyword::FETCH
+                    | Keyword::FOR
+                    | Keyword::UNION
+                    | Keyword::INTERSECT
+                    | Keyword::EXCEPT
+            ),
+            _ => false,
+        }
+    }
+
     /// Parses optimizer hints at the current token position.
     ///
     /// Collects all `/*prefix+...*/` and `--prefix+...` patterns.
diff --git a/tests/sqlparser_common.rs b/tests/sqlparser_common.rs
index 8e08c657..793065a6 100644
--- a/tests/sqlparser_common.rs
+++ b/tests/sqlparser_common.rs
@@ -16374,6 +16374,43 @@ fn parse_deeply_nested_boolean_expr_does_not_stackoverflow() {
 fn parse_select_without_projection() {
     let dialects = all_dialects_where(|d| d.supports_empty_projections());
     dialects.verified_stmt("SELECT FROM users");
+    for sql in [
+        "SELECT",
+        "SELECT ALL",
+        "SELECT INTO t",
+        "SELECT WHERE true",
+        "SELECT GROUP BY () HAVING true",
+        "SELECT WINDOW w AS ()",
+        "SELECT ORDER BY 1",
+        "SELECT LIMIT 1",
+        "SELECT OFFSET 1",
+        "SELECT FETCH FIRST 1 ROWS ONLY",
+        "SELECT FOR UPDATE",
+        "SELECT UNION SELECT",
+        "SELECT INTERSECT SELECT",
+        "SELECT EXCEPT SELECT",
+        "SELECT EXISTS (SELECT)",
+        "SELECT * FROM (SELECT) AS t",
+    ] {
+        dialects.verified_stmt(sql);
+    }
+    assert_eq!(
+        dialects
+            .parse_sql_statements("SELECT; SELECT")
+            .unwrap()
+            .len(),
+        2
+    );
+    assert_eq!(
+        dialects.parse_sql_statements("SELECT WHERE").unwrap_err(),
+        ParserError::ParserError("Expected: an expression, found: EOF".to_string())
+    );
+
+    let dialects = all_dialects_where(|d| !d.supports_empty_projections());
+    assert_eq!(
+        dialects.parse_sql_statements("SELECT").unwrap_err(),
+        ParserError::ParserError("Expected: an expression, found: EOF".to_string())
+    );
 }
 
 #[test]


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@datafusion.apache.org
For additional commands, e-mail: commits-help@datafusion.apache.org