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

github-bot pushed a commit to branch 
gh-readonly-queue/main/pr-2230-982068ec51cbd60cb8489fb50286c344ba339e0c
in repository https://gitbox.apache.org/repos/asf/datafusion-sqlparser-rs.git

commit 8afcad8fcb915d0366d4cdda9aa9958365f968ae
Author: Yoabot <[email protected]>
AuthorDate: Thu Feb 26 11:37:30 2026 +0100

    Redshift: support wildcard select items with alias (#2230)
---
 src/ast/query.rs          |  7 +++++++
 src/ast/spans.rs          |  4 +++-
 src/dialect/mod.rs        | 12 ++++++++++++
 src/dialect/redshift.rs   |  4 ++++
 src/parser/mod.rs         | 11 +++++++++++
 tests/sqlparser_common.rs | 20 ++++++++++++++++++++
 6 files changed, 57 insertions(+), 1 deletion(-)

diff --git a/src/ast/query.rs b/src/ast/query.rs
index b4d3fdb2..159f02a6 100644
--- a/src/ast/query.rs
+++ b/src/ast/query.rs
@@ -934,6 +934,9 @@ pub struct WildcardAdditionalOptions {
     pub opt_replace: Option<ReplaceSelectItem>,
     /// `[RENAME ...]`.
     pub opt_rename: Option<RenameSelectItem>,
+    /// `[AS <alias>]`.
+    ///  Redshift syntax: 
<https://docs.aws.amazon.com/redshift/latest/dg/r_SELECT_list.html>
+    pub opt_alias: Option<Ident>,
 }
 
 impl Default for WildcardAdditionalOptions {
@@ -945,6 +948,7 @@ impl Default for WildcardAdditionalOptions {
             opt_except: None,
             opt_replace: None,
             opt_rename: None,
+            opt_alias: None,
         }
     }
 }
@@ -966,6 +970,9 @@ impl fmt::Display for WildcardAdditionalOptions {
         if let Some(rename) = &self.opt_rename {
             write!(f, " {rename}")?;
         }
+        if let Some(alias) = &self.opt_alias {
+            write!(f, " AS {alias}")?;
+        }
         Ok(())
     }
 }
diff --git a/src/ast/spans.rs b/src/ast/spans.rs
index b29a134b..1e216208 100644
--- a/src/ast/spans.rs
+++ b/src/ast/spans.rs
@@ -1824,6 +1824,7 @@ impl Spanned for WildcardAdditionalOptions {
             opt_except,
             opt_replace,
             opt_rename,
+            opt_alias,
         } = self;
 
         union_spans(
@@ -1832,7 +1833,8 @@ impl Spanned for WildcardAdditionalOptions {
                 .chain(opt_exclude.as_ref().map(|i| i.span()))
                 .chain(opt_rename.as_ref().map(|i| i.span()))
                 .chain(opt_replace.as_ref().map(|i| i.span()))
-                .chain(opt_except.as_ref().map(|i| i.span())),
+                .chain(opt_except.as_ref().map(|i| i.span()))
+                .chain(opt_alias.as_ref().map(|i| i.span)),
         )
     }
 }
diff --git a/src/dialect/mod.rs b/src/dialect/mod.rs
index bcca455e..698c12ec 100644
--- a/src/dialect/mod.rs
+++ b/src/dialect/mod.rs
@@ -1517,6 +1517,18 @@ pub trait Dialect: Debug + Any {
         false
     }
 
+    /// Returns true if this dialect supports aliasing a wildcard select item.
+    ///
+    /// Example:
+    /// ```sql
+    /// SELECT t.* AS alias FROM t
+    /// ```
+    ///
+    /// 
[Redshift](https://docs.aws.amazon.com/redshift/latest/dg/r_SELECT_list.html)
+    fn supports_select_wildcard_with_alias(&self) -> bool {
+        false
+    }
+
     /// Returns true if this dialect supports the `OPTIMIZE TABLE` statement.
     ///
     /// Example:
diff --git a/src/dialect/redshift.rs b/src/dialect/redshift.rs
index 21958e38..5969ee55 100644
--- a/src/dialect/redshift.rs
+++ b/src/dialect/redshift.rs
@@ -141,6 +141,10 @@ impl Dialect for RedshiftSqlDialect {
         true
     }
 
+    fn supports_select_wildcard_with_alias(&self) -> bool {
+        true
+    }
+
     fn supports_select_exclude(&self) -> bool {
         true
     }
diff --git a/src/parser/mod.rs b/src/parser/mod.rs
index bb11d79c..667a1535 100644
--- a/src/parser/mod.rs
+++ b/src/parser/mod.rs
@@ -17864,6 +17864,16 @@ impl<'a> Parser<'a> {
             None
         };
 
+        let opt_alias = if self.dialect.supports_select_wildcard_with_alias() {
+            if self.parse_keyword(Keyword::AS) {
+                Some(self.parse_identifier()?)
+            } else {
+                None
+            }
+        } else {
+            None
+        };
+
         Ok(WildcardAdditionalOptions {
             wildcard_token: wildcard_token.into(),
             opt_ilike,
@@ -17871,6 +17881,7 @@ impl<'a> Parser<'a> {
             opt_except,
             opt_rename,
             opt_replace,
+            opt_alias,
         })
     }
 
diff --git a/tests/sqlparser_common.rs b/tests/sqlparser_common.rs
index a3b5404d..3f0ca96a 100644
--- a/tests/sqlparser_common.rs
+++ b/tests/sqlparser_common.rs
@@ -1280,6 +1280,26 @@ fn parse_select_expr_star() {
     dialects.verified_only_select("SELECT myfunc().* EXCEPT (foo) FROM T");
 }
 
+#[test]
+fn parse_select_wildcard_with_alias() {
+    let dialects = all_dialects_where(|d| 
d.supports_select_wildcard_with_alias());
+
+    // qualified wildcard with alias
+    dialects
+        .parse_sql_statements("SELECT t.* AS all_cols FROM t")
+        .unwrap();
+
+    // unqualified wildcard with alias
+    dialects
+        .parse_sql_statements("SELECT * AS all_cols FROM t")
+        .unwrap();
+
+    // mixed: regular column + qualified wildcard with alias
+    dialects
+        .parse_sql_statements("SELECT a.id, b.* AS b_cols FROM a JOIN b ON 
(a.id = b.a_id)")
+        .unwrap();
+}
+
 #[test]
 fn test_eof_after_as() {
     let res = parse_sql_statements("SELECT foo AS");


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to