diff --git a/src/parser/mod.rs b/src/parser/mod.rs index 5bae7a13..de96625b 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -9059,7 +9059,7 @@ impl<'a> Parser<'a> { None }; - let opt_replace = if dialect_of!(self is GenericDialect | BigQueryDialect | ClickHouseDialect) + let opt_replace = if dialect_of!(self is GenericDialect | BigQueryDialect | ClickHouseDialect | DuckDbDialect | SnowflakeDialect) { self.parse_optional_select_item_replace()? } else { diff --git a/tests/sqlparser_bigquery.rs b/tests/sqlparser_bigquery.rs index c8f1bb7c..43e6a84b 100644 --- a/tests/sqlparser_bigquery.rs +++ b/tests/sqlparser_bigquery.rs @@ -1280,49 +1280,6 @@ fn test_select_wildcard_with_except() { ); } -#[test] -fn test_select_wildcard_with_replace() { - let select = bigquery_and_generic() - .verified_only_select(r#"SELECT * REPLACE ('widget' AS item_name) FROM orders"#); - let expected = SelectItem::Wildcard(WildcardAdditionalOptions { - opt_replace: Some(ReplaceSelectItem { - items: vec![Box::new(ReplaceSelectElement { - expr: Expr::Value(Value::SingleQuotedString("widget".to_owned())), - column_name: Ident::new("item_name"), - as_keyword: true, - })], - }), - ..Default::default() - }); - assert_eq!(expected, select.projection[0]); - - let select = bigquery_and_generic().verified_only_select( - r#"SELECT * REPLACE (quantity / 2 AS quantity, 3 AS order_id) FROM orders"#, - ); - let expected = SelectItem::Wildcard(WildcardAdditionalOptions { - opt_replace: Some(ReplaceSelectItem { - items: vec![ - Box::new(ReplaceSelectElement { - expr: Expr::BinaryOp { - left: Box::new(Expr::Identifier(Ident::new("quantity"))), - op: BinaryOperator::Divide, - right: Box::new(Expr::Value(number("2"))), - }, - column_name: Ident::new("quantity"), - as_keyword: true, - }), - Box::new(ReplaceSelectElement { - expr: Expr::Value(number("3")), - column_name: Ident::new("order_id"), - as_keyword: true, - }), - ], - }), - ..Default::default() - }); - assert_eq!(expected, select.projection[0]); -} - #[test] fn parse_big_query_declare() { for (sql, expected_names, expected_data_type, expected_assigned_expr) in [ diff --git a/tests/sqlparser_clickhouse.rs b/tests/sqlparser_clickhouse.rs index a3fcc612..22396d06 100644 --- a/tests/sqlparser_clickhouse.rs +++ b/tests/sqlparser_clickhouse.rs @@ -382,11 +382,6 @@ fn parse_select_star_except_no_parens() { ); } -#[test] -fn parse_select_star_replace() { - clickhouse().verified_stmt("SELECT * REPLACE (i + 1 AS i) FROM columns_transformers"); -} - fn clickhouse() -> TestedDialects { TestedDialects { dialects: vec![Box::new(ClickHouseDialect {})], diff --git a/tests/sqlparser_common.rs b/tests/sqlparser_common.rs index c94bd377..6c95b6c5 100644 --- a/tests/sqlparser_common.rs +++ b/tests/sqlparser_common.rs @@ -8685,3 +8685,81 @@ fn parse_map_access_expr() { let _ = dialects.verified_expr(sql); } } + +#[test] +fn test_select_wildcard_with_replace() { + let sql = r#"SELECT * REPLACE (lower(city) AS city) FROM addresses"#; + let dialects = TestedDialects { + dialects: vec![ + Box::new(GenericDialect {}), + Box::new(BigQueryDialect {}), + Box::new(ClickHouseDialect {}), + Box::new(SnowflakeDialect {}), + Box::new(DuckDbDialect {}), + ], + options: None, + }; + let select = dialects.verified_only_select(sql); + let expected = SelectItem::Wildcard(WildcardAdditionalOptions { + opt_replace: Some(ReplaceSelectItem { + items: vec![Box::new(ReplaceSelectElement { + expr: Expr::Function(Function { + name: ObjectName(vec![Ident::new("lower")]), + args: vec![FunctionArg::Unnamed(FunctionArgExpr::Expr( + Expr::Identifier(Ident::new("city")), + ))], + filter: None, + null_treatment: None, + over: None, + distinct: false, + special: false, + order_by: vec![], + }), + column_name: Ident::new("city"), + as_keyword: true, + })], + }), + ..Default::default() + }); + assert_eq!(expected, select.projection[0]); + + let select = + dialects.verified_only_select(r#"SELECT * REPLACE ('widget' AS item_name) FROM orders"#); + let expected = SelectItem::Wildcard(WildcardAdditionalOptions { + opt_replace: Some(ReplaceSelectItem { + items: vec![Box::new(ReplaceSelectElement { + expr: Expr::Value(Value::SingleQuotedString("widget".to_owned())), + column_name: Ident::new("item_name"), + as_keyword: true, + })], + }), + ..Default::default() + }); + assert_eq!(expected, select.projection[0]); + + let select = dialects.verified_only_select( + r#"SELECT * REPLACE (quantity / 2 AS quantity, 3 AS order_id) FROM orders"#, + ); + let expected = SelectItem::Wildcard(WildcardAdditionalOptions { + opt_replace: Some(ReplaceSelectItem { + items: vec![ + Box::new(ReplaceSelectElement { + expr: Expr::BinaryOp { + left: Box::new(Expr::Identifier(Ident::new("quantity"))), + op: BinaryOperator::Divide, + right: Box::new(Expr::Value(number("2"))), + }, + column_name: Ident::new("quantity"), + as_keyword: true, + }), + Box::new(ReplaceSelectElement { + expr: Expr::Value(number("3")), + column_name: Ident::new("order_id"), + as_keyword: true, + }), + ], + }), + ..Default::default() + }); + assert_eq!(expected, select.projection[0]); +}