mirror of
https://github.com/apache/datafusion-sqlparser-rs.git
synced 2025-09-23 06:02:30 +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))]
|
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
|
||||||
pub struct WildcardAdditionalOptions {
|
pub struct WildcardAdditionalOptions {
|
||||||
/// `[ILIKE...]`.
|
/// `[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>,
|
pub opt_ilike: Option<IlikeSelectItem>,
|
||||||
/// `[EXCLUDE...]`.
|
/// `[EXCLUDE...]`.
|
||||||
pub opt_exclude: Option<ExcludeSelectItem>,
|
pub opt_exclude: Option<ExcludeSelectItem>,
|
||||||
/// `[EXCEPT...]`.
|
/// `[EXCEPT...]`.
|
||||||
/// Clickhouse syntax: <https://clickhouse.com/docs/en/sql-reference/statements/select#except>
|
/// Clickhouse syntax: <https://clickhouse.com/docs/en/sql-reference/statements/select#except>
|
||||||
pub opt_except: Option<ExceptSelectItem>,
|
pub opt_except: Option<ExceptSelectItem>,
|
||||||
/// `[RENAME ...]`.
|
|
||||||
pub opt_rename: Option<RenameSelectItem>,
|
|
||||||
/// `[REPLACE]`
|
/// `[REPLACE]`
|
||||||
/// BigQuery syntax: <https://cloud.google.com/bigquery/docs/reference/standard-sql/query-syntax#select_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>
|
/// 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>,
|
pub opt_replace: Option<ReplaceSelectItem>,
|
||||||
|
/// `[RENAME ...]`.
|
||||||
|
pub opt_rename: Option<RenameSelectItem>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for WildcardAdditionalOptions {
|
impl fmt::Display for WildcardAdditionalOptions {
|
||||||
|
@ -573,12 +574,12 @@ impl fmt::Display for WildcardAdditionalOptions {
|
||||||
if let Some(except) = &self.opt_except {
|
if let Some(except) = &self.opt_except {
|
||||||
write!(f, " {except}")?;
|
write!(f, " {except}")?;
|
||||||
}
|
}
|
||||||
if let Some(rename) = &self.opt_rename {
|
|
||||||
write!(f, " {rename}")?;
|
|
||||||
}
|
|
||||||
if let Some(replace) = &self.opt_replace {
|
if let Some(replace) = &self.opt_replace {
|
||||||
write!(f, " {replace}")?;
|
write!(f, " {replace}")?;
|
||||||
}
|
}
|
||||||
|
if let Some(rename) = &self.opt_rename {
|
||||||
|
write!(f, " {rename}")?;
|
||||||
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10175,15 +10175,14 @@ impl<'a> Parser<'a> {
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
let opt_rename = if dialect_of!(self is GenericDialect | SnowflakeDialect) {
|
let opt_replace = if dialect_of!(self is GenericDialect | BigQueryDialect | ClickHouseDialect | DuckDbDialect | SnowflakeDialect)
|
||||||
self.parse_optional_select_item_rename()?
|
{
|
||||||
|
self.parse_optional_select_item_replace()?
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
let opt_rename = if dialect_of!(self is GenericDialect | SnowflakeDialect) {
|
||||||
let opt_replace = if dialect_of!(self is GenericDialect | BigQueryDialect | ClickHouseDialect | DuckDbDialect | SnowflakeDialect)
|
self.parse_optional_select_item_rename()?
|
||||||
{
|
|
||||||
self.parse_optional_select_item_replace()?
|
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
|
@ -1016,6 +1016,44 @@ fn test_select_wildcard_with_rename() {
|
||||||
assert_eq!(expected, select.projection[0]);
|
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]
|
#[test]
|
||||||
fn test_select_wildcard_with_exclude_and_rename() {
|
fn test_select_wildcard_with_exclude_and_rename() {
|
||||||
let select = snowflake_and_generic()
|
let select = snowflake_and_generic()
|
||||||
|
@ -1031,6 +1069,7 @@ fn test_select_wildcard_with_exclude_and_rename() {
|
||||||
assert_eq!(expected, select.projection[0]);
|
assert_eq!(expected, select.projection[0]);
|
||||||
|
|
||||||
// rename cannot precede exclude
|
// rename cannot precede exclude
|
||||||
|
// https://docs.snowflake.com/en/sql-reference/sql/select#parameters
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
snowflake_and_generic()
|
snowflake_and_generic()
|
||||||
.parse_sql_statements("SELECT * RENAME col_a AS col_b EXCLUDE col_z FROM data")
|
.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