Skip to content

Commit 9db20e2

Browse files
fix: have wildcard replace work in duckdb and snowflake syntax (apache#1226)
1 parent 2f03fad commit 9db20e2

4 files changed

Lines changed: 79 additions & 49 deletions

File tree

src/parser/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9059,7 +9059,7 @@ impl<'a> Parser<'a> {
90599059
None
90609060
};
90619061

9062-
let opt_replace = if dialect_of!(self is GenericDialect | BigQueryDialect | ClickHouseDialect)
9062+
let opt_replace = if dialect_of!(self is GenericDialect | BigQueryDialect | ClickHouseDialect | DuckDbDialect | SnowflakeDialect)
90639063
{
90649064
self.parse_optional_select_item_replace()?
90659065
} else {

tests/sqlparser_bigquery.rs

Lines changed: 0 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1280,49 +1280,6 @@ fn test_select_wildcard_with_except() {
12801280
);
12811281
}
12821282

1283-
#[test]
1284-
fn test_select_wildcard_with_replace() {
1285-
let select = bigquery_and_generic()
1286-
.verified_only_select(r#"SELECT * REPLACE ('widget' AS item_name) FROM orders"#);
1287-
let expected = SelectItem::Wildcard(WildcardAdditionalOptions {
1288-
opt_replace: Some(ReplaceSelectItem {
1289-
items: vec![Box::new(ReplaceSelectElement {
1290-
expr: Expr::Value(Value::SingleQuotedString("widget".to_owned())),
1291-
column_name: Ident::new("item_name"),
1292-
as_keyword: true,
1293-
})],
1294-
}),
1295-
..Default::default()
1296-
});
1297-
assert_eq!(expected, select.projection[0]);
1298-
1299-
let select = bigquery_and_generic().verified_only_select(
1300-
r#"SELECT * REPLACE (quantity / 2 AS quantity, 3 AS order_id) FROM orders"#,
1301-
);
1302-
let expected = SelectItem::Wildcard(WildcardAdditionalOptions {
1303-
opt_replace: Some(ReplaceSelectItem {
1304-
items: vec![
1305-
Box::new(ReplaceSelectElement {
1306-
expr: Expr::BinaryOp {
1307-
left: Box::new(Expr::Identifier(Ident::new("quantity"))),
1308-
op: BinaryOperator::Divide,
1309-
right: Box::new(Expr::Value(number("2"))),
1310-
},
1311-
column_name: Ident::new("quantity"),
1312-
as_keyword: true,
1313-
}),
1314-
Box::new(ReplaceSelectElement {
1315-
expr: Expr::Value(number("3")),
1316-
column_name: Ident::new("order_id"),
1317-
as_keyword: true,
1318-
}),
1319-
],
1320-
}),
1321-
..Default::default()
1322-
});
1323-
assert_eq!(expected, select.projection[0]);
1324-
}
1325-
13261283
#[test]
13271284
fn parse_big_query_declare() {
13281285
for (sql, expected_names, expected_data_type, expected_assigned_expr) in [

tests/sqlparser_clickhouse.rs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -382,11 +382,6 @@ fn parse_select_star_except_no_parens() {
382382
);
383383
}
384384

385-
#[test]
386-
fn parse_select_star_replace() {
387-
clickhouse().verified_stmt("SELECT * REPLACE (i + 1 AS i) FROM columns_transformers");
388-
}
389-
390385
fn clickhouse() -> TestedDialects {
391386
TestedDialects {
392387
dialects: vec![Box::new(ClickHouseDialect {})],

tests/sqlparser_common.rs

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8685,3 +8685,81 @@ fn parse_map_access_expr() {
86858685
let _ = dialects.verified_expr(sql);
86868686
}
86878687
}
8688+
8689+
#[test]
8690+
fn test_select_wildcard_with_replace() {
8691+
let sql = r#"SELECT * REPLACE (lower(city) AS city) FROM addresses"#;
8692+
let dialects = TestedDialects {
8693+
dialects: vec![
8694+
Box::new(GenericDialect {}),
8695+
Box::new(BigQueryDialect {}),
8696+
Box::new(ClickHouseDialect {}),
8697+
Box::new(SnowflakeDialect {}),
8698+
Box::new(DuckDbDialect {}),
8699+
],
8700+
options: None,
8701+
};
8702+
let select = dialects.verified_only_select(sql);
8703+
let expected = SelectItem::Wildcard(WildcardAdditionalOptions {
8704+
opt_replace: Some(ReplaceSelectItem {
8705+
items: vec![Box::new(ReplaceSelectElement {
8706+
expr: Expr::Function(Function {
8707+
name: ObjectName(vec![Ident::new("lower")]),
8708+
args: vec![FunctionArg::Unnamed(FunctionArgExpr::Expr(
8709+
Expr::Identifier(Ident::new("city")),
8710+
))],
8711+
filter: None,
8712+
null_treatment: None,
8713+
over: None,
8714+
distinct: false,
8715+
special: false,
8716+
order_by: vec![],
8717+
}),
8718+
column_name: Ident::new("city"),
8719+
as_keyword: true,
8720+
})],
8721+
}),
8722+
..Default::default()
8723+
});
8724+
assert_eq!(expected, select.projection[0]);
8725+
8726+
let select =
8727+
dialects.verified_only_select(r#"SELECT * REPLACE ('widget' AS item_name) FROM orders"#);
8728+
let expected = SelectItem::Wildcard(WildcardAdditionalOptions {
8729+
opt_replace: Some(ReplaceSelectItem {
8730+
items: vec![Box::new(ReplaceSelectElement {
8731+
expr: Expr::Value(Value::SingleQuotedString("widget".to_owned())),
8732+
column_name: Ident::new("item_name"),
8733+
as_keyword: true,
8734+
})],
8735+
}),
8736+
..Default::default()
8737+
});
8738+
assert_eq!(expected, select.projection[0]);
8739+
8740+
let select = dialects.verified_only_select(
8741+
r#"SELECT * REPLACE (quantity / 2 AS quantity, 3 AS order_id) FROM orders"#,
8742+
);
8743+
let expected = SelectItem::Wildcard(WildcardAdditionalOptions {
8744+
opt_replace: Some(ReplaceSelectItem {
8745+
items: vec![
8746+
Box::new(ReplaceSelectElement {
8747+
expr: Expr::BinaryOp {
8748+
left: Box::new(Expr::Identifier(Ident::new("quantity"))),
8749+
op: BinaryOperator::Divide,
8750+
right: Box::new(Expr::Value(number("2"))),
8751+
},
8752+
column_name: Ident::new("quantity"),
8753+
as_keyword: true,
8754+
}),
8755+
Box::new(ReplaceSelectElement {
8756+
expr: Expr::Value(number("3")),
8757+
column_name: Ident::new("order_id"),
8758+
as_keyword: true,
8759+
}),
8760+
],
8761+
}),
8762+
..Default::default()
8763+
});
8764+
assert_eq!(expected, select.projection[0]);
8765+
}

0 commit comments

Comments
 (0)