Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions src/dialect/redshift.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,14 @@
// specific language governing permissions and limitations
// under the License.

#[cfg(not(feature = "std"))]
use alloc::boxed::Box;

use crate::ast::Expr;
use crate::dialect::Dialect;
use crate::keywords::Keyword;
use crate::parser::{Parser, ParserError};
use crate::tokenizer::Token;
use core::iter::Peekable;
use core::str::Chars;

Expand All @@ -35,6 +41,28 @@ pub struct RedshiftSqlDialect {}
// in the Postgres dialect, the query will be parsed as an array, while in the Redshift dialect it will
// be a json path
impl Dialect for RedshiftSqlDialect {
fn parse_prefix(&self, parser: &mut Parser) -> Option<Result<Expr, ParserError>> {
if matches!(&parser.peek_token_ref().token, Token::Word(word) if word.value.eq_ignore_ascii_case("approximate"))

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm this doesnt look like the correct place for this functionality, we already have function parsers in the parser and support other percentile_disc variants. so that I think we likely just need to adjust that logic to accept redshifts' syntax

&& matches!(&parser.peek_nth_token_ref(1).token, Token::Word(word) if word.value.eq_ignore_ascii_case("percentile_disc"))
{
parser.next_token();
let function_name = match parser.parse_object_name(false) {
Ok(name) => name,
Err(error) => return Some(Err(error)),
};
return Some(
parser
.parse_function(function_name)
.map(|function| Expr::Prefixed {
prefix: "APPROXIMATE".into(),
value: Box::new(function),
}),
);
}

None
}

/// Determine if a character starts a potential nested quoted identifier.
/// Example: RedShift supports the following quote styles to all mean the same thing:
/// ```sql
Expand Down
14 changes: 14 additions & 0 deletions tests/sqlparser_redshift.rs
Original file line number Diff line number Diff line change
Expand Up @@ -557,3 +557,17 @@ 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() {
redshift().one_statement_parses_to(
r#"SELECT TOP 10 date.caldate,
COUNT(totalprice), SUM(totalprice),
APPROXIMATE PERCENTILE_DISC(0.5) WITHIN GROUP (ORDER BY totalprice)
FROM listing
JOIN date ON listing.dateid = date.dateid
GROUP BY date.caldate
ORDER BY 3 DESC"#,
"SELECT TOP 10 date.caldate, COUNT(totalprice), SUM(totalprice), APPROXIMATE PERCENTILE_DISC(0.5) WITHIN GROUP (ORDER BY totalprice) FROM listing JOIN date ON listing.dateid = date.dateid GROUP BY date.caldate ORDER BY 3 DESC",
Comment on lines +564 to +571

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lets simplify this test input so that its clear what's being tested. also we should use verified_stmt

);
}
Loading