Skip to content
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
feat: Support CLOSE (cursors)
  • Loading branch information
ovr committed Jun 6, 2022
commit 56acaa3b6b4325b354e05ae81d824b666798d0ca
26 changes: 26 additions & 0 deletions src/ast/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -770,6 +770,11 @@ pub enum Statement {
/// VALUES a vector of values to be copied
values: Vec<Option<String>>,
},
/// Close - closes the portal underlying an open cursor.
Close {
/// Cursor name
cursor: CloseCursor,
},
/// UPDATE
Update {
/// TABLE
Expand Down Expand Up @@ -1363,6 +1368,11 @@ impl fmt::Display for Statement {
}
Ok(())
}
Statement::Close { cursor } => {
write!(f, "CLOSE {}", cursor)?;

Ok(())
}
Statement::CreateDatabase {
db_name,
if_not_exists,
Expand Down Expand Up @@ -2178,6 +2188,22 @@ impl fmt::Display for FunctionArg {
}
}

#[derive(Debug, Clone, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum CloseCursor {
All,
Specific { name: Ident },
}

impl fmt::Display for CloseCursor {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
CloseCursor::All => write!(f, "ALL"),
CloseCursor::Specific { name } => write!(f, "{}", name),
}
}
}

/// A function call
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
Expand Down
13 changes: 13 additions & 0 deletions src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ impl<'a> Parser<'a> {
Keyword::UPDATE => Ok(self.parse_update()?),
Keyword::ALTER => Ok(self.parse_alter()?),
Keyword::COPY => Ok(self.parse_copy()?),
Keyword::CLOSE => Ok(self.parse_close()?),
Keyword::SET => Ok(self.parse_set()?),
Keyword::SHOW => Ok(self.parse_show()?),
Keyword::GRANT => Ok(self.parse_grant()?),
Expand Down Expand Up @@ -2522,6 +2523,18 @@ impl<'a> Parser<'a> {
})
}

pub fn parse_close(&mut self) -> Result<Statement, ParserError> {
let cursor = if self.parse_keyword(Keyword::ALL) {
CloseCursor::All
} else {
let name = self.parse_identifier()?;

CloseCursor::Specific { name }
};

Ok(Statement::Close { cursor })
}

fn parse_copy_option(&mut self) -> Result<CopyOption, ParserError> {
let ret = match self.parse_one_of_keywords(&[
Keyword::FORMAT,
Expand Down
22 changes: 22 additions & 0 deletions tests/sqlparser_common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,15 @@

#[macro_use]
mod test_utils;

use matches::assert_matches;
use sqlparser::ast::*;
use sqlparser::dialect::{
AnsiDialect, GenericDialect, MsSqlDialect, PostgreSqlDialect, SQLiteDialect, SnowflakeDialect,
};
use sqlparser::keywords::ALL_KEYWORDS;
use sqlparser::parser::{Parser, ParserError};

use test_utils::{
all_dialects, expr_from_projection, join, number, only, table, table_alias, TestedDialects,
};
Expand Down Expand Up @@ -4779,3 +4781,23 @@ fn parse_discard() {
_ => unreachable!(),
}
}

#[test]
fn parse_cursor() {
let sql = r#"CLOSE my_cursor"#;
match verified_stmt(sql) {
Statement::Close { cursor } => assert_eq!(
cursor,
CloseCursor::Specific {
name: Ident::new("my_cursor"),
}
),
_ => unreachable!(),
}

let sql = r#"CLOSE ALL"#;
match verified_stmt(sql) {
Statement::Close { cursor } => assert_eq!(cursor, CloseCursor::All),
_ => unreachable!(),
}
}