mirror of
https://github.com/apache/datafusion-sqlparser-rs.git
synced 2025-12-10 06:19:36 +00:00
Merge pull request #158 from mjibson/offset-rows
Add support for OFFSET without the ROWS keyword (a MySQL quirk, documented at https://dev.mysql.com/doc/refman/8.0/en/select.html) Teach the parser to remember which variant it saw (ROWS/ROW/none).
This commit is contained in:
commit
af852e78f6
4 changed files with 96 additions and 25 deletions
|
|
@ -26,8 +26,8 @@ pub use self::ddl::{
|
|||
};
|
||||
pub use self::operator::{BinaryOperator, UnaryOperator};
|
||||
pub use self::query::{
|
||||
Cte, Fetch, Join, JoinConstraint, JoinOperator, OrderByExpr, Query, Select, SelectItem,
|
||||
SetExpr, SetOperator, TableAlias, TableFactor, TableWithJoins, Top, Values,
|
||||
Cte, Fetch, Join, JoinConstraint, JoinOperator, Offset, OffsetRows, OrderByExpr, Query, Select,
|
||||
SelectItem, SetExpr, SetOperator, TableAlias, TableFactor, TableWithJoins, Top, Values,
|
||||
};
|
||||
pub use self::value::{DateTimeField, Value};
|
||||
|
||||
|
|
|
|||
|
|
@ -24,8 +24,8 @@ pub struct Query {
|
|||
pub order_by: Vec<OrderByExpr>,
|
||||
/// `LIMIT { <N> | ALL }`
|
||||
pub limit: Option<Expr>,
|
||||
/// `OFFSET <N> { ROW | ROWS }`
|
||||
pub offset: Option<Expr>,
|
||||
/// `OFFSET <N> [ { ROW | ROWS } ]`
|
||||
pub offset: Option<Offset>,
|
||||
/// `FETCH { FIRST | NEXT } <N> [ PERCENT ] { ROW | ROWS } | { ONLY | WITH TIES }`
|
||||
pub fetch: Option<Fetch>,
|
||||
}
|
||||
|
|
@ -43,7 +43,7 @@ impl fmt::Display for Query {
|
|||
write!(f, " LIMIT {}", limit)?;
|
||||
}
|
||||
if let Some(ref offset) = self.offset {
|
||||
write!(f, " OFFSET {} ROWS", offset)?;
|
||||
write!(f, " {}", offset)?;
|
||||
}
|
||||
if let Some(ref fetch) = self.fetch {
|
||||
write!(f, " {}", fetch)?;
|
||||
|
|
@ -391,6 +391,35 @@ impl fmt::Display for OrderByExpr {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct Offset {
|
||||
pub value: Expr,
|
||||
pub rows: OffsetRows,
|
||||
}
|
||||
|
||||
impl fmt::Display for Offset {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "OFFSET {}{}", self.value, self.rows)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub enum OffsetRows {
|
||||
None,
|
||||
Row,
|
||||
Rows,
|
||||
}
|
||||
|
||||
impl fmt::Display for OffsetRows {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
OffsetRows::None => Ok(()),
|
||||
OffsetRows::Row => write!(f, " ROW"),
|
||||
OffsetRows::Rows => write!(f, " ROWS"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct Fetch {
|
||||
pub with_ties: bool,
|
||||
|
|
|
|||
|
|
@ -1970,10 +1970,16 @@ impl Parser {
|
|||
}
|
||||
|
||||
/// Parse an OFFSET clause
|
||||
pub fn parse_offset(&mut self) -> Result<Expr, ParserError> {
|
||||
pub fn parse_offset(&mut self) -> Result<Offset, ParserError> {
|
||||
let value = Expr::Value(self.parse_number_value()?);
|
||||
self.expect_one_of_keywords(&["ROW", "ROWS"])?;
|
||||
Ok(value)
|
||||
let rows = if self.parse_keyword("ROW") {
|
||||
OffsetRows::Row
|
||||
} else if self.parse_keyword("ROWS") {
|
||||
OffsetRows::Rows
|
||||
} else {
|
||||
OffsetRows::None
|
||||
};
|
||||
Ok(Offset { value, rows })
|
||||
}
|
||||
|
||||
/// Parse a FETCH clause
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue