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]
