Skip to content

Commit

Permalink
fix(sqlparser): make LIMIT and OFFSET order flexible
Browse files Browse the repository at this point in the history
  • Loading branch information
takaebato committed Jan 5, 2025
1 parent d8f9d96 commit 4c98e8f
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 10 deletions.
20 changes: 10 additions & 10 deletions src/sqlparser/src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4248,17 +4248,17 @@ impl Parser<'_> {
vec![]
};

let limit = if self.parse_keyword(Keyword::LIMIT) {
self.parse_limit()?
} else {
None
};
let mut limit = None;
let mut offset = None;
for _x in 0..2 {
if limit.is_none() && self.parse_keyword(Keyword::LIMIT) {
limit = self.parse_limit()?
}

let offset = if self.parse_keyword(Keyword::OFFSET) {
Some(self.parse_offset()?)
} else {
None
};
if offset.is_none() && self.parse_keyword(Keyword::OFFSET) {
offset = Some(self.parse_offset()?)
}
}

let fetch = if self.parse_keyword(Keyword::FETCH) {
if limit.is_some() {
Expand Down
22 changes: 22 additions & 0 deletions src/sqlparser/tests/testdata/select.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -237,3 +237,25 @@
SELECT a0 + b0 FROM a_log, "B_log"
formatted_sql: WITH a_log AS changelog from a, "B_log" AS changelog from public."B" SELECT a0 + b0 FROM a_log, "B_log"
formatted_ast: 'Query(Query { with: Some(With { recursive: false, cte_tables: [Cte { alias: TableAlias { name: Ident { value: "a_log", quote_style: None }, columns: [] }, cte_inner: ChangeLog(ObjectName([Ident { value: "a", quote_style: None }])) }, Cte { alias: TableAlias { name: Ident { value: "B_log", quote_style: Some(''"'') }, columns: [] }, cte_inner: ChangeLog(ObjectName([Ident { value: "public", quote_style: None }, Ident { value: "B", quote_style: Some(''"'') }])) }] }), body: Select(Select { distinct: All, projection: [UnnamedExpr(BinaryOp { left: Identifier(Ident { value: "a0", quote_style: None }), op: Plus, right: Identifier(Ident { value: "b0", quote_style: None }) })], from: [TableWithJoins { relation: Table { name: ObjectName([Ident { value: "a_log", quote_style: None }]), alias: None, as_of: None }, joins: [] }, TableWithJoins { relation: Table { name: ObjectName([Ident { value: "B_log", quote_style: Some(''"'') }]), alias: None, as_of: None }, joins: [] }], lateral_views: [], selection: None, group_by: [], having: None }), order_by: [], limit: None, offset: None, fetch: None })'
- input: SELECT * FROM t LIMIT 1
formatted_sql: SELECT * FROM t LIMIT 1
formatted_ast: 'Query(Query { with: None, body: Select(Select { distinct: All, projection: [Wildcard(None)], from: [TableWithJoins { relation: Table { name: ObjectName([Ident { value: "t", quote_style: None }]), alias: None, as_of: None }, joins: [] }], lateral_views: [], selection: None, group_by: [], having: None }), order_by: [], limit: Some(Value(Number("1"))), offset: None, fetch: None })'
- input: SELECT * FROM t OFFSET 1
formatted_sql: SELECT * FROM t OFFSET 1
formatted_ast: 'Query(Query { with: None, body: Select(Select { distinct: All, projection: [Wildcard(None)], from: [TableWithJoins { relation: Table { name: ObjectName([Ident { value: "t", quote_style: None }]), alias: None, as_of: None }, joins: [] }], lateral_views: [], selection: None, group_by: [], having: None }), order_by: [], limit: None, offset: Some("1"), fetch: None })'
- input: SELECT * FROM t LIMIT 1 OFFSET 2
formatted_sql: SELECT * FROM t LIMIT 1 OFFSET 2
formatted_ast: 'Query(Query { with: None, body: Select(Select { distinct: All, projection: [Wildcard(None)], from: [TableWithJoins { relation: Table { name: ObjectName([Ident { value: "t", quote_style: None }]), alias: None, as_of: None }, joins: [] }], lateral_views: [], selection: None, group_by: [], having: None }), order_by: [], limit: Some(Value(Number("1"))), offset: Some("2"), fetch: None })'
- input: SELECT * FROM t OFFSET 2 LIMIT 1
formatted_sql: SELECT * FROM t LIMIT 1 OFFSET 2
formatted_ast: 'Query(Query { with: None, body: Select(Select { distinct: All, projection: [Wildcard(None)], from: [TableWithJoins { relation: Table { name: ObjectName([Ident { value: "t", quote_style: None }]), alias: None, as_of: None }, joins: [] }], lateral_views: [], selection: None, group_by: [], having: None }), order_by: [], limit: Some(Value(Number("1"))), offset: Some("2"), fetch: None })'
- input: SELECT * FROM t LIMIT 1 LIMIT 2
error_msg: |-
sql parser error: expected end of statement, found: LIMIT
LINE 1: SELECT * FROM t LIMIT 1 LIMIT 2
^
- input: SELECT * FROM t OFFSET 1 OFFSET 2
error_msg: |-
sql parser error: expected end of statement, found: OFFSET
LINE 1: SELECT * FROM t OFFSET 1 OFFSET 2
^

0 comments on commit 4c98e8f

Please sign in to comment.