mirror of
https://github.com/apache/datafusion-sqlparser-rs.git
synced 2025-08-04 06:18:17 +00:00
Fix Snowflake SELECT *
wildcard REPLACE ... RENAME
order (#1321)
This commit is contained in:
parent
a685e11993
commit
f5ccef6ea9
3 changed files with 51 additions and 12 deletions
|
@ -547,19 +547,20 @@ impl fmt::Display for IdentWithAlias {
|
|||
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
|
||||
pub struct WildcardAdditionalOptions {
|
||||
/// `[ILIKE...]`.
|
||||
/// Snowflake syntax: <https://docs.snowflake.com/en/sql-reference/sql/select>
|
||||
/// Snowflake syntax: <https://docs.snowflake.com/en/sql-reference/sql/select#parameters>
|
||||
pub opt_ilike: Option<IlikeSelectItem>,
|
||||
/// `[EXCLUDE...]`.
|
||||
pub opt_exclude: Option<ExcludeSelectItem>,
|
||||
/// `[EXCEPT...]`.
|
||||
/// Clickhouse syntax: <https://clickhouse.com/docs/en/sql-reference/statements/select#except>
|
||||
pub opt_except: Option<ExceptSelectItem>,
|
||||
/// `[RENAME ...]`.
|
||||
pub opt_rename: Option<RenameSelectItem>,
|
||||
/// `[REPLACE]`
|
||||
/// BigQuery syntax: <https://cloud.google.com/bigquery/docs/reference/standard-sql/query-syntax#select_replace>
|
||||
/// Clickhouse syntax: <https://clickhouse.com/docs/en/sql-reference/statements/select#replace>
|
||||
/// Snowflake syntax: <https://docs.snowflake.com/en/sql-reference/sql/select#parameters>
|
||||
pub opt_replace: Option<ReplaceSelectItem>,
|
||||
/// `[RENAME ...]`.
|
||||
pub opt_rename: Option<RenameSelectItem>,
|
||||
}
|
||||
|
||||
impl fmt::Display for WildcardAdditionalOptions {
|
||||
|
@ -573,12 +574,12 @@ impl fmt::Display for WildcardAdditionalOptions {
|
|||
if let Some(except) = &self.opt_except {
|
||||
write!(f, " {except}")?;
|
||||
}
|
||||
if let Some(rename) = &self.opt_rename {
|
||||
write!(f, " {rename}")?;
|
||||
}
|
||||
if let Some(replace) = &self.opt_replace {
|
||||
write!(f, " {replace}")?;
|
||||
}
|
||||
if let Some(rename) = &self.opt_rename {
|
||||
write!(f, " {rename}")?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10175,15 +10175,14 @@ impl<'a> Parser<'a> {
|
|||
} else {
|
||||
None
|
||||
};
|
||||
let opt_rename = if dialect_of!(self is GenericDialect | SnowflakeDialect) {
|
||||
self.parse_optional_select_item_rename()?
|
||||
let opt_replace = if dialect_of!(self is GenericDialect | BigQueryDialect | ClickHouseDialect | DuckDbDialect | SnowflakeDialect)
|
||||
{
|
||||
self.parse_optional_select_item_replace()?
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let opt_replace = if dialect_of!(self is GenericDialect | BigQueryDialect | ClickHouseDialect | DuckDbDialect | SnowflakeDialect)
|
||||
{
|
||||
self.parse_optional_select_item_replace()?
|
||||
let opt_rename = if dialect_of!(self is GenericDialect | SnowflakeDialect) {
|
||||
self.parse_optional_select_item_rename()?
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
|
|
@ -1016,6 +1016,44 @@ fn test_select_wildcard_with_rename() {
|
|||
assert_eq!(expected, select.projection[0]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_select_wildcard_with_replace_and_rename() {
|
||||
let select = snowflake_and_generic().verified_only_select(
|
||||
"SELECT * REPLACE (col_z || col_z AS col_z) RENAME (col_z AS col_zz) FROM data",
|
||||
);
|
||||
let expected = SelectItem::Wildcard(WildcardAdditionalOptions {
|
||||
opt_replace: Some(ReplaceSelectItem {
|
||||
items: vec![Box::new(ReplaceSelectElement {
|
||||
expr: Expr::BinaryOp {
|
||||
left: Box::new(Expr::Identifier(Ident::new("col_z"))),
|
||||
op: BinaryOperator::StringConcat,
|
||||
right: Box::new(Expr::Identifier(Ident::new("col_z"))),
|
||||
},
|
||||
column_name: Ident::new("col_z"),
|
||||
as_keyword: true,
|
||||
})],
|
||||
}),
|
||||
opt_rename: Some(RenameSelectItem::Multiple(vec![IdentWithAlias {
|
||||
ident: Ident::new("col_z"),
|
||||
alias: Ident::new("col_zz"),
|
||||
}])),
|
||||
..Default::default()
|
||||
});
|
||||
assert_eq!(expected, select.projection[0]);
|
||||
|
||||
// rename cannot precede replace
|
||||
// https://docs.snowflake.com/en/sql-reference/sql/select#parameters
|
||||
assert_eq!(
|
||||
snowflake_and_generic()
|
||||
.parse_sql_statements(
|
||||
"SELECT * RENAME (col_z AS col_zz) REPLACE (col_z || col_z AS col_z) FROM data"
|
||||
)
|
||||
.unwrap_err()
|
||||
.to_string(),
|
||||
"sql parser error: Expected: end of statement, found: REPLACE"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_select_wildcard_with_exclude_and_rename() {
|
||||
let select = snowflake_and_generic()
|
||||
|
@ -1031,6 +1069,7 @@ fn test_select_wildcard_with_exclude_and_rename() {
|
|||
assert_eq!(expected, select.projection[0]);
|
||||
|
||||
// rename cannot precede exclude
|
||||
// https://docs.snowflake.com/en/sql-reference/sql/select#parameters
|
||||
assert_eq!(
|
||||
snowflake_and_generic()
|
||||
.parse_sql_statements("SELECT * RENAME col_a AS col_b EXCLUDE col_z FROM data")
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue