mirror of
https://github.com/apache/datafusion-sqlparser-rs.git
synced 2025-08-21 22:44:08 +00:00
snowflake: add qualify expression (#465)
Signed-off-by: Maciej Obuchowski <obuchowski.maciej@gmail.com>
This commit is contained in:
parent
edad20cbb8
commit
525ba527bb
7 changed files with 60 additions and 2 deletions
|
@ -154,6 +154,8 @@ pub struct Select {
|
||||||
pub sort_by: Vec<Expr>,
|
pub sort_by: Vec<Expr>,
|
||||||
/// HAVING
|
/// HAVING
|
||||||
pub having: Option<Expr>,
|
pub having: Option<Expr>,
|
||||||
|
/// QUALIFY (Snowflake)
|
||||||
|
pub qualify: Option<Expr>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for Select {
|
impl fmt::Display for Select {
|
||||||
|
@ -202,6 +204,9 @@ impl fmt::Display for Select {
|
||||||
if let Some(ref having) = self.having {
|
if let Some(ref having) = self.having {
|
||||||
write!(f, " HAVING {}", having)?;
|
write!(f, " HAVING {}", having)?;
|
||||||
}
|
}
|
||||||
|
if let Some(ref qualify) = self.qualify {
|
||||||
|
write!(f, " QUALIFY {}", qualify)?;
|
||||||
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -382,6 +382,7 @@ define_keywords!(
|
||||||
PROCEDURE,
|
PROCEDURE,
|
||||||
PROGRAM,
|
PROGRAM,
|
||||||
PURGE,
|
PURGE,
|
||||||
|
QUALIFY,
|
||||||
QUARTER,
|
QUARTER,
|
||||||
QUOTE,
|
QUOTE,
|
||||||
RANGE,
|
RANGE,
|
||||||
|
@ -584,6 +585,7 @@ pub const RESERVED_FOR_TABLE_ALIAS: &[Keyword] = &[
|
||||||
// for MSSQL-specific OUTER APPLY (seems reserved in most dialects)
|
// for MSSQL-specific OUTER APPLY (seems reserved in most dialects)
|
||||||
Keyword::OUTER,
|
Keyword::OUTER,
|
||||||
Keyword::SET,
|
Keyword::SET,
|
||||||
|
Keyword::QUALIFY,
|
||||||
];
|
];
|
||||||
|
|
||||||
/// Can't be used as a column alias, so that `SELECT <expr> alias`
|
/// Can't be used as a column alias, so that `SELECT <expr> alias`
|
||||||
|
|
|
@ -3167,6 +3167,12 @@ impl<'a> Parser<'a> {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let qualify = if self.parse_keyword(Keyword::QUALIFY) {
|
||||||
|
Some(self.parse_expr()?)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
Ok(Select {
|
Ok(Select {
|
||||||
distinct,
|
distinct,
|
||||||
top,
|
top,
|
||||||
|
@ -3180,6 +3186,7 @@ impl<'a> Parser<'a> {
|
||||||
distribute_by,
|
distribute_by,
|
||||||
sort_by,
|
sort_by,
|
||||||
having,
|
having,
|
||||||
|
qualify,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1322,6 +1322,45 @@ fn parse_select_having() {
|
||||||
assert!(select.having.is_some());
|
assert!(select.having.is_some());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "bigdecimal")]
|
||||||
|
#[test]
|
||||||
|
fn parse_select_qualify() {
|
||||||
|
let sql = "SELECT i, p, o FROM qt QUALIFY ROW_NUMBER() OVER (PARTITION BY p ORDER BY o) = 1";
|
||||||
|
let select = verified_only_select(sql);
|
||||||
|
assert_eq!(
|
||||||
|
Some(Expr::BinaryOp {
|
||||||
|
left: Box::new(Expr::Function(Function {
|
||||||
|
name: ObjectName(vec![Ident::new("ROW_NUMBER")]),
|
||||||
|
args: vec![],
|
||||||
|
over: Some(WindowSpec {
|
||||||
|
partition_by: vec![Expr::Identifier(Ident::new("p"))],
|
||||||
|
order_by: vec![OrderByExpr {
|
||||||
|
expr: Expr::Identifier(Ident::new("o")),
|
||||||
|
asc: None,
|
||||||
|
nulls_first: None
|
||||||
|
}],
|
||||||
|
window_frame: None
|
||||||
|
}),
|
||||||
|
distinct: false
|
||||||
|
})),
|
||||||
|
op: BinaryOperator::Eq,
|
||||||
|
right: Box::new(Expr::Value(number("1")))
|
||||||
|
}),
|
||||||
|
select.qualify
|
||||||
|
);
|
||||||
|
|
||||||
|
let sql = "SELECT i, p, o, ROW_NUMBER() OVER (PARTITION BY p ORDER BY o) AS row_num FROM qt QUALIFY row_num = 1";
|
||||||
|
let select = verified_only_select(sql);
|
||||||
|
assert_eq!(
|
||||||
|
Some(Expr::BinaryOp {
|
||||||
|
left: Box::new(Expr::Identifier(Ident::new("row_num"))),
|
||||||
|
op: BinaryOperator::Eq,
|
||||||
|
right: Box::new(Expr::Value(number("1")))
|
||||||
|
}),
|
||||||
|
select.qualify
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn parse_limit_accepts_all() {
|
fn parse_limit_accepts_all() {
|
||||||
one_statement_parses_to(
|
one_statement_parses_to(
|
||||||
|
@ -4336,7 +4375,8 @@ fn parse_merge() {
|
||||||
cluster_by: vec![],
|
cluster_by: vec![],
|
||||||
distribute_by: vec![],
|
distribute_by: vec![],
|
||||||
sort_by: vec![],
|
sort_by: vec![],
|
||||||
having: None
|
having: None,
|
||||||
|
qualify: None
|
||||||
})),
|
})),
|
||||||
order_by: vec![],
|
order_by: vec![],
|
||||||
limit: None,
|
limit: None,
|
||||||
|
|
|
@ -314,6 +314,7 @@ fn parse_quote_identifiers_2() {
|
||||||
distribute_by: vec![],
|
distribute_by: vec![],
|
||||||
sort_by: vec![],
|
sort_by: vec![],
|
||||||
having: None,
|
having: None,
|
||||||
|
qualify: None
|
||||||
})),
|
})),
|
||||||
order_by: vec![],
|
order_by: vec![],
|
||||||
limit: None,
|
limit: None,
|
||||||
|
@ -754,6 +755,7 @@ fn parse_substring_in_select() {
|
||||||
distribute_by: vec![],
|
distribute_by: vec![],
|
||||||
sort_by: vec![],
|
sort_by: vec![],
|
||||||
having: None,
|
having: None,
|
||||||
|
qualify: None
|
||||||
})),
|
})),
|
||||||
order_by: vec![],
|
order_by: vec![],
|
||||||
limit: None,
|
limit: None,
|
||||||
|
|
|
@ -450,6 +450,7 @@ fn parse_update_set_from() {
|
||||||
distribute_by: vec![],
|
distribute_by: vec![],
|
||||||
sort_by: vec![],
|
sort_by: vec![],
|
||||||
having: None,
|
having: None,
|
||||||
|
qualify: None
|
||||||
})),
|
})),
|
||||||
order_by: vec![],
|
order_by: vec![],
|
||||||
limit: None,
|
limit: None,
|
||||||
|
|
|
@ -96,7 +96,8 @@ fn parse_map_access_expr() {
|
||||||
cluster_by: vec![],
|
cluster_by: vec![],
|
||||||
distribute_by: vec![],
|
distribute_by: vec![],
|
||||||
sort_by: vec![],
|
sort_by: vec![],
|
||||||
having: None
|
having: None,
|
||||||
|
qualify: None
|
||||||
},
|
},
|
||||||
select
|
select
|
||||||
);
|
);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue