feat: Support FETCH (cursors) (#510)

This commit is contained in:
Dmitry Patsura 2022-06-04 21:24:36 +03:00 committed by GitHub
parent d19d955d9b
commit 66a3082cb6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 180 additions and 0 deletions

View file

@ -167,6 +167,7 @@ impl<'a> Parser<'a> {
Keyword::CREATE => Ok(self.parse_create()?),
Keyword::DROP => Ok(self.parse_drop()?),
Keyword::DISCARD => Ok(self.parse_discard()?),
Keyword::FETCH => Ok(self.parse_fetch_statement()?),
Keyword::DELETE => Ok(self.parse_delete()?),
Keyword::INSERT => Ok(self.parse_insert()?),
Keyword::UPDATE => Ok(self.parse_update()?),
@ -1824,6 +1825,67 @@ impl<'a> Parser<'a> {
})
}
// FETCH [ direction { FROM | IN } ] cursor INTO target;
pub fn parse_fetch_statement(&mut self) -> Result<Statement, ParserError> {
let direction = if self.parse_keyword(Keyword::NEXT) {
FetchDirection::Next
} else if self.parse_keyword(Keyword::PRIOR) {
FetchDirection::Prior
} else if self.parse_keyword(Keyword::FIRST) {
FetchDirection::First
} else if self.parse_keyword(Keyword::LAST) {
FetchDirection::Last
} else if self.parse_keyword(Keyword::ABSOLUTE) {
FetchDirection::Absolute {
limit: self.parse_number_value()?,
}
} else if self.parse_keyword(Keyword::RELATIVE) {
FetchDirection::Relative {
limit: self.parse_number_value()?,
}
} else if self.parse_keyword(Keyword::FORWARD) {
if self.parse_keyword(Keyword::ALL) {
FetchDirection::ForwardAll
} else {
FetchDirection::Forward {
// TODO: Support optional
limit: Some(self.parse_number_value()?),
}
}
} else if self.parse_keyword(Keyword::BACKWARD) {
if self.parse_keyword(Keyword::ALL) {
FetchDirection::BackwardAll
} else {
FetchDirection::Backward {
// TODO: Support optional
limit: Some(self.parse_number_value()?),
}
}
} else if self.parse_keyword(Keyword::ALL) {
FetchDirection::All
} else {
FetchDirection::Count {
limit: self.parse_number_value()?,
}
};
self.expect_one_of_keywords(&[Keyword::FROM, Keyword::IN])?;
let name = self.parse_identifier()?;
let into = if self.parse_keyword(Keyword::INTO) {
Some(self.parse_object_name()?)
} else {
None
};
Ok(Statement::Fetch {
name,
direction,
into,
})
}
pub fn parse_discard(&mut self) -> Result<Statement, ParserError> {
let object_type = if self.parse_keyword(Keyword::ALL) {
DiscardObject::ALL