diff --git a/src/dialect/mod.rs b/src/dialect/mod.rs index ff83a4da61..7c4744c5a7 100644 --- a/src/dialect/mod.rs +++ b/src/dialect/mod.rs @@ -598,6 +598,12 @@ pub trait Dialect: Debug + Any { None } + /// Does the dialect support the `APPROXIMATE PERCENTILE_DISC` function syntax? + /// See + fn supports_approximate_percentile_disc(&self) -> bool { + false + } + /// Does the dialect support trailing commas around the query? fn supports_trailing_commas(&self) -> bool { false diff --git a/src/dialect/redshift.rs b/src/dialect/redshift.rs index aa403618fb..f3dab66ffa 100644 --- a/src/dialect/redshift.rs +++ b/src/dialect/redshift.rs @@ -128,6 +128,11 @@ impl Dialect for RedshiftSqlDialect { true } + /// See + fn supports_approximate_percentile_disc(&self) -> bool { + true + } + fn supports_geometric_types(&self) -> bool { true } diff --git a/src/keywords.rs b/src/keywords.rs index 0c50703c3f..7b91eecba0 100644 --- a/src/keywords.rs +++ b/src/keywords.rs @@ -121,6 +121,7 @@ define_keywords!( APPLICATION, APPLY, APPLYBUDGET, + APPROXIMATE, ARCHIVE, ARE, ARRAY, diff --git a/src/parser/mod.rs b/src/parser/mod.rs index 5edc437145..2171548f91 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -1635,6 +1635,18 @@ impl<'a> Parser<'a> { Keyword::MAP if *self.peek_token_ref() == Token::LBrace && self.dialect.support_map_literal_syntax() => { Ok(Some(self.parse_duckdb_map_literal()?)) } + Keyword::APPROXIMATE + if self.dialect.supports_approximate_percentile_disc() + && self.peek_keyword(Keyword::PERCENTILE_DISC) => + { + self.maybe_parse(|parser| { + let function_name = parser.parse_object_name(false)?; + parser.parse_function(function_name).map(|function| Expr::Prefixed { + prefix: w.to_ident(w_span), + value: Box::new(function), + }) + }) + } Keyword::LAMBDA if self.dialect.supports_lambda_functions() => { Ok(Some(self.parse_lambda_expr()?)) } diff --git a/tests/sqlparser_redshift.rs b/tests/sqlparser_redshift.rs index 31cc4fe583..9e1c8f8703 100644 --- a/tests/sqlparser_redshift.rs +++ b/tests/sqlparser_redshift.rs @@ -557,3 +557,19 @@ fn parse_unpivot_expression() { fn test_interval_as_column_name() { redshift().verified_stmt("SELECT * FROM table_name WHERE interval = 78"); } + +#[test] +fn parse_approximate_percentile_disc() { + let supporting = all_dialects_where(|d| d.supports_approximate_percentile_disc()); + supporting.verified_stmt( + "SELECT APPROXIMATE PERCENTILE_DISC(0.5) WITHIN GROUP (ORDER BY totalprice)", + ); + + // Without dialect support, `APPROXIMATE` is just a column name and + // `PERCENTILE_DISC` its implicit alias. + let non_supporting = all_dialects_where(|d| !d.supports_approximate_percentile_disc()); + non_supporting.one_statement_parses_to( + "SELECT APPROXIMATE PERCENTILE_DISC FROM t", + "SELECT APPROXIMATE AS PERCENTILE_DISC FROM t", + ); +}