Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support expressions in LIMIT/OFFSET #567

Merged
merged 1 commit into from Aug 11, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/parser.rs
Expand Up @@ -4402,13 +4402,13 @@ impl<'a> Parser<'a> {
if self.parse_keyword(Keyword::ALL) {
Ok(None)
} else {
Ok(Some(Expr::Value(self.parse_number_value()?)))
Ok(Some(self.parse_expr()?))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

}
}

/// Parse an OFFSET clause
pub fn parse_offset(&mut self) -> Result<Offset, ParserError> {
let value = Expr::Value(self.parse_number_value()?);
let value = self.parse_expr()?;
let rows = if self.parse_keyword(Keyword::ROW) {
OffsetRows::Row
} else if self.parse_keyword(Keyword::ROWS) {
Expand Down
37 changes: 37 additions & 0 deletions tests/sqlparser_common.rs
Expand Up @@ -5010,6 +5010,20 @@ fn test_placeholder() {
right: Box::new(Expr::Value(Value::Placeholder("$Id1".into())))
})
);

let sql = "SELECT * FROM student LIMIT $1 OFFSET $2";
let ast = dialects.verified_query(sql);
assert_eq!(
ast.limit,
Some(Expr::Value(Value::Placeholder("$1".into())))
);
assert_eq!(
ast.offset,
Some(Offset {
value: Expr::Value(Value::Placeholder("$2".into())),
rows: OffsetRows::None,
}),
);
}

#[test]
Expand Down Expand Up @@ -5058,6 +5072,29 @@ fn parse_offset_and_limit() {
// different order is OK
one_statement_parses_to("SELECT foo FROM bar OFFSET 2 LIMIT 2", sql);

// expressions are allowed
let sql = "SELECT foo FROM bar LIMIT 1 + 2 OFFSET 3 * 4";
let ast = verified_query(sql);
assert_eq!(
ast.limit,
Some(Expr::BinaryOp {
left: Box::new(Expr::Value(number("1"))),
op: BinaryOperator::Plus,
right: Box::new(Expr::Value(number("2"))),
}),
);
assert_eq!(
ast.offset,
Some(Offset {
value: Expr::BinaryOp {
left: Box::new(Expr::Value(number("3"))),
op: BinaryOperator::Multiply,
right: Box::new(Expr::Value(number("4"))),
},
rows: OffsetRows::None,
}),
);

// Can't repeat OFFSET / LIMIT
let res = parse_sql_statements("SELECT foo FROM bar OFFSET 2 OFFSET 2");
assert_eq!(
Expand Down