Skip to content

Commit f958264

Browse files
yoabot-droidLucaCappelletti94
authored andcommitted
Redshift: support wildcard select items with alias (apache#2230)
1 parent aaf2516 commit f958264

File tree

6 files changed

+57
-1
lines changed

6 files changed

+57
-1
lines changed

src/ast/query.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -934,6 +934,9 @@ pub struct WildcardAdditionalOptions {
934934
pub opt_replace: Option<ReplaceSelectItem>,
935935
/// `[RENAME ...]`.
936936
pub opt_rename: Option<RenameSelectItem>,
937+
/// `[AS <alias>]`.
938+
/// Redshift syntax: <https://docs.aws.amazon.com/redshift/latest/dg/r_SELECT_list.html>
939+
pub opt_alias: Option<Ident>,
937940
}
938941

939942
impl Default for WildcardAdditionalOptions {
@@ -945,6 +948,7 @@ impl Default for WildcardAdditionalOptions {
945948
opt_except: None,
946949
opt_replace: None,
947950
opt_rename: None,
951+
opt_alias: None,
948952
}
949953
}
950954
}
@@ -966,6 +970,9 @@ impl fmt::Display for WildcardAdditionalOptions {
966970
if let Some(rename) = &self.opt_rename {
967971
write!(f, " {rename}")?;
968972
}
973+
if let Some(alias) = &self.opt_alias {
974+
write!(f, " AS {alias}")?;
975+
}
969976
Ok(())
970977
}
971978
}

src/ast/spans.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1824,6 +1824,7 @@ impl Spanned for WildcardAdditionalOptions {
18241824
opt_except,
18251825
opt_replace,
18261826
opt_rename,
1827+
opt_alias,
18271828
} = self;
18281829

18291830
union_spans(
@@ -1832,7 +1833,8 @@ impl Spanned for WildcardAdditionalOptions {
18321833
.chain(opt_exclude.as_ref().map(|i| i.span()))
18331834
.chain(opt_rename.as_ref().map(|i| i.span()))
18341835
.chain(opt_replace.as_ref().map(|i| i.span()))
1835-
.chain(opt_except.as_ref().map(|i| i.span())),
1836+
.chain(opt_except.as_ref().map(|i| i.span()))
1837+
.chain(opt_alias.as_ref().map(|i| i.span)),
18361838
)
18371839
}
18381840
}

src/dialect/mod.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1517,6 +1517,18 @@ pub trait Dialect: Debug + Any {
15171517
false
15181518
}
15191519

1520+
/// Returns true if this dialect supports aliasing a wildcard select item.
1521+
///
1522+
/// Example:
1523+
/// ```sql
1524+
/// SELECT t.* AS alias FROM t
1525+
/// ```
1526+
///
1527+
/// [Redshift](https://docs.aws.amazon.com/redshift/latest/dg/r_SELECT_list.html)
1528+
fn supports_select_wildcard_with_alias(&self) -> bool {
1529+
false
1530+
}
1531+
15201532
/// Returns true if this dialect supports the `OPTIMIZE TABLE` statement.
15211533
///
15221534
/// Example:

src/dialect/redshift.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,10 @@ impl Dialect for RedshiftSqlDialect {
141141
true
142142
}
143143

144+
fn supports_select_wildcard_with_alias(&self) -> bool {
145+
true
146+
}
147+
144148
fn supports_select_exclude(&self) -> bool {
145149
true
146150
}

src/parser/mod.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17864,13 +17864,24 @@ impl<'a> Parser<'a> {
1786417864
None
1786517865
};
1786617866

17867+
let opt_alias = if self.dialect.supports_select_wildcard_with_alias() {
17868+
if self.parse_keyword(Keyword::AS) {
17869+
Some(self.parse_identifier()?)
17870+
} else {
17871+
None
17872+
}
17873+
} else {
17874+
None
17875+
};
17876+
1786717877
Ok(WildcardAdditionalOptions {
1786817878
wildcard_token: wildcard_token.into(),
1786917879
opt_ilike,
1787017880
opt_exclude,
1787117881
opt_except,
1787217882
opt_rename,
1787317883
opt_replace,
17884+
opt_alias,
1787417885
})
1787517886
}
1787617887

tests/sqlparser_common.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1280,6 +1280,26 @@ fn parse_select_expr_star() {
12801280
dialects.verified_only_select("SELECT myfunc().* EXCEPT (foo) FROM T");
12811281
}
12821282

1283+
#[test]
1284+
fn parse_select_wildcard_with_alias() {
1285+
let dialects = all_dialects_where(|d| d.supports_select_wildcard_with_alias());
1286+
1287+
// qualified wildcard with alias
1288+
dialects
1289+
.parse_sql_statements("SELECT t.* AS all_cols FROM t")
1290+
.unwrap();
1291+
1292+
// unqualified wildcard with alias
1293+
dialects
1294+
.parse_sql_statements("SELECT * AS all_cols FROM t")
1295+
.unwrap();
1296+
1297+
// mixed: regular column + qualified wildcard with alias
1298+
dialects
1299+
.parse_sql_statements("SELECT a.id, b.* AS b_cols FROM a JOIN b ON (a.id = b.a_id)")
1300+
.unwrap();
1301+
}
1302+
12831303
#[test]
12841304
fn test_eof_after_as() {
12851305
let res = parse_sql_statements("SELECT foo AS");

0 commit comments

Comments
 (0)