Support OFFSET LIMIT as well as LIMIT OFFSET (#413)

* Inital support in current_timestamp

* Support time functions

* Add Test

* Fix order of offset

* Merge from main

* Fix PR

* Update Test

* Do not allow repeated LIMIT or OFFSET

Co-authored-by: Yuval Shkolar <yuval@illumex.ai>
This commit is contained in:
Andrew Lamb 2022-02-05 07:46:53 -05:00 committed by GitHub
parent 87509f1dec
commit 33d4f27bfc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 45 additions and 10 deletions

View file

@ -2499,17 +2499,18 @@ impl<'a> Parser<'a> {
vec![] vec![]
}; };
let limit = if self.parse_keyword(Keyword::LIMIT) { let mut limit = None;
self.parse_limit()? let mut offset = None;
} else {
None
};
let offset = if self.parse_keyword(Keyword::OFFSET) { for _x in 0..2 {
Some(self.parse_offset()?) if limit.is_none() && self.parse_keyword(Keyword::LIMIT) {
} else { limit = self.parse_limit()?
None }
};
if offset.is_none() && self.parse_keyword(Keyword::OFFSET) {
offset = Some(self.parse_offset()?)
}
}
let fetch = if self.parse_keyword(Keyword::FETCH) { let fetch = if self.parse_keyword(Keyword::FETCH) {
Some(self.parse_fetch()?) Some(self.parse_fetch()?)

View file

@ -4076,6 +4076,40 @@ fn verified_expr(query: &str) -> Expr {
all_dialects().verified_expr(query) all_dialects().verified_expr(query)
} }
#[test]
fn parse_offset_and_limit() {
let sql = "SELECT foo FROM bar LIMIT 2 OFFSET 2";
let expect = Some(Offset {
value: Expr::Value(number("2")),
rows: OffsetRows::None,
});
let ast = verified_query(sql);
assert_eq!(ast.offset, expect);
assert_eq!(ast.limit, Some(Expr::Value(number("2"))));
// different order is OK
one_statement_parses_to("SELECT foo FROM bar OFFSET 2 LIMIT 2", sql);
// Can't repeat OFFSET / LIMIT
let res = parse_sql_statements("SELECT foo FROM bar OFFSET 2 OFFSET 2");
assert_eq!(
ParserError::ParserError("Expected end of statement, found: OFFSET".to_string()),
res.unwrap_err()
);
let res = parse_sql_statements("SELECT foo FROM bar LIMIT 2 LIMIT 2");
assert_eq!(
ParserError::ParserError("Expected end of statement, found: LIMIT".to_string()),
res.unwrap_err()
);
let res = parse_sql_statements("SELECT foo FROM bar OFFSET 2 LIMIT 2 OFFSET 2");
assert_eq!(
ParserError::ParserError("Expected end of statement, found: OFFSET".to_string()),
res.unwrap_err()
);
}
#[test] #[test]
fn parse_time_functions() { fn parse_time_functions() {
let sql = "SELECT CURRENT_TIMESTAMP()"; let sql = "SELECT CURRENT_TIMESTAMP()";