mirror of
https://github.com/apache/datafusion-sqlparser-rs.git
synced 2025-08-04 06:18:17 +00:00
Amend WindowFrame docs
The note about WindowFrameBound::Following being only valid "in WindowFrame::end_bound" was both - confusing, as it was based on the ANSI SQL syntax the parser doesn't adhere to -- though it sounded like a promise about the AST one could expect to get from the parser - and incomplete, as the reality is that the bounds validation the SQL engine might want to perform is more complex. For example Postgres documentation says <https://www.postgresql.org/docs/11/sql-expressions.html#SYNTAX-WINDOW-FUNCTIONS>: > Restrictions are that frame_start cannot be UNBOUNDED FOLLOWING, > frame_end cannot be UNBOUNDED PRECEDING, and the frame_end choice > cannot appear earlier in the above list of frame_start and frame_end > options than the frame_start choice does — for example RANGE BETWEEN > CURRENT ROW AND offset PRECEDING is not allowed. But, for example, > ROWS BETWEEN 7 PRECEDING AND 8 PRECEDING is allowed, even though it > would never select any rows.
This commit is contained in:
parent
f31636d339
commit
086ba1281c
2 changed files with 10 additions and 6 deletions
|
@ -292,11 +292,16 @@ impl fmt::Display for WindowSpec {
|
|||
|
||||
/// Specifies the data processed by a window function, e.g.
|
||||
/// `RANGE UNBOUNDED PRECEDING` or `ROWS BETWEEN 5 PRECEDING AND CURRENT ROW`.
|
||||
///
|
||||
/// Note: The parser does not validate the specified bounds; the caller should
|
||||
/// reject invalid bounds like `ROWS UNBOUNDED FOLLOWING` before execution.
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct WindowFrame {
|
||||
pub units: WindowFrameUnits,
|
||||
pub start_bound: WindowFrameBound,
|
||||
/// The right bound of the `BETWEEN .. AND` clause.
|
||||
/// The right bound of the `BETWEEN .. AND` clause. The end bound of `None`
|
||||
/// indicates the shorthand form (e.g. `ROWS 1 PRECEDING`), which must
|
||||
/// behave the same as `end_bound = WindowFrameBound::CurrentRow`.
|
||||
pub end_bound: Option<WindowFrameBound>,
|
||||
// TBD: EXCLUDE
|
||||
}
|
||||
|
@ -334,14 +339,14 @@ impl FromStr for WindowFrameUnits {
|
|||
}
|
||||
}
|
||||
|
||||
/// Specifies [WindowFrame]'s `start_bound` and `end_bound`
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub enum WindowFrameBound {
|
||||
/// `CURRENT ROW`
|
||||
CurrentRow,
|
||||
/// `<N> PRECEDING` or `UNBOUNDED PRECEDING`
|
||||
Preceding(Option<u64>),
|
||||
/// `<N> FOLLOWING` or `UNBOUNDED FOLLOWING`. This can only appear in
|
||||
/// [WindowFrame::end_bound].
|
||||
/// `<N> FOLLOWING` or `UNBOUNDED FOLLOWING`.
|
||||
Following(Option<u64>),
|
||||
}
|
||||
|
||||
|
|
|
@ -339,7 +339,7 @@ impl Parser {
|
|||
})
|
||||
}
|
||||
|
||||
/// "CURRENT ROW" | ( (<positive number> | "UNBOUNDED") ("PRECEDING" | FOLLOWING) )
|
||||
/// Parse `CURRENT ROW` or `{ <positive number> | UNBOUNDED } { PRECEDING | FOLLOWING }`
|
||||
pub fn parse_window_frame_bound(&mut self) -> Result<WindowFrameBound, ParserError> {
|
||||
if self.parse_keywords(vec!["CURRENT", "ROW"]) {
|
||||
Ok(WindowFrameBound::CurrentRow)
|
||||
|
@ -347,8 +347,7 @@ impl Parser {
|
|||
let rows = if self.parse_keyword("UNBOUNDED") {
|
||||
None
|
||||
} else {
|
||||
let rows = self.parse_literal_uint()?;
|
||||
Some(rows)
|
||||
Some(self.parse_literal_uint()?)
|
||||
};
|
||||
if self.parse_keyword("PRECEDING") {
|
||||
Ok(WindowFrameBound::Preceding(rows))
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue