mirror of
https://github.com/apache/datafusion-sqlparser-rs.git
synced 2025-09-20 04:39:49 +00:00
feat: Support CLOSE (cursors) (#515)
This commit is contained in:
parent
3f1c6426f0
commit
d361c3a3a1
3 changed files with 61 additions and 0 deletions
|
@ -804,6 +804,11 @@ pub enum Statement {
|
||||||
/// VALUES a vector of values to be copied
|
/// VALUES a vector of values to be copied
|
||||||
values: Vec<Option<String>>,
|
values: Vec<Option<String>>,
|
||||||
},
|
},
|
||||||
|
/// Close - closes the portal underlying an open cursor.
|
||||||
|
Close {
|
||||||
|
/// Cursor name
|
||||||
|
cursor: CloseCursor,
|
||||||
|
},
|
||||||
/// UPDATE
|
/// UPDATE
|
||||||
Update {
|
Update {
|
||||||
/// TABLE
|
/// TABLE
|
||||||
|
@ -1393,6 +1398,11 @@ impl fmt::Display for Statement {
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
Statement::Close { cursor } => {
|
||||||
|
write!(f, "CLOSE {}", cursor)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
Statement::CreateDatabase {
|
Statement::CreateDatabase {
|
||||||
db_name,
|
db_name,
|
||||||
if_not_exists,
|
if_not_exists,
|
||||||
|
@ -2158,6 +2168,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
|
/// A function call
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
|
|
@ -174,6 +174,7 @@ impl<'a> Parser<'a> {
|
||||||
Keyword::UPDATE => Ok(self.parse_update()?),
|
Keyword::UPDATE => Ok(self.parse_update()?),
|
||||||
Keyword::ALTER => Ok(self.parse_alter()?),
|
Keyword::ALTER => Ok(self.parse_alter()?),
|
||||||
Keyword::COPY => Ok(self.parse_copy()?),
|
Keyword::COPY => Ok(self.parse_copy()?),
|
||||||
|
Keyword::CLOSE => Ok(self.parse_close()?),
|
||||||
Keyword::SET => Ok(self.parse_set()?),
|
Keyword::SET => Ok(self.parse_set()?),
|
||||||
Keyword::SHOW => Ok(self.parse_show()?),
|
Keyword::SHOW => Ok(self.parse_show()?),
|
||||||
Keyword::GRANT => Ok(self.parse_grant()?),
|
Keyword::GRANT => Ok(self.parse_grant()?),
|
||||||
|
@ -2563,6 +2564,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> {
|
fn parse_copy_option(&mut self) -> Result<CopyOption, ParserError> {
|
||||||
let ret = match self.parse_one_of_keywords(&[
|
let ret = match self.parse_one_of_keywords(&[
|
||||||
Keyword::FORMAT,
|
Keyword::FORMAT,
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
mod test_utils;
|
mod test_utils;
|
||||||
|
|
||||||
use matches::assert_matches;
|
use matches::assert_matches;
|
||||||
use sqlparser::ast::*;
|
use sqlparser::ast::*;
|
||||||
use sqlparser::dialect::{
|
use sqlparser::dialect::{
|
||||||
|
@ -28,6 +29,7 @@ use sqlparser::dialect::{
|
||||||
};
|
};
|
||||||
use sqlparser::keywords::ALL_KEYWORDS;
|
use sqlparser::keywords::ALL_KEYWORDS;
|
||||||
use sqlparser::parser::{Parser, ParserError};
|
use sqlparser::parser::{Parser, ParserError};
|
||||||
|
|
||||||
use test_utils::{
|
use test_utils::{
|
||||||
all_dialects, expr_from_projection, join, number, only, table, table_alias, TestedDialects,
|
all_dialects, expr_from_projection, join, number, only, table, table_alias, TestedDialects,
|
||||||
};
|
};
|
||||||
|
@ -4944,3 +4946,23 @@ fn parse_discard() {
|
||||||
_ => unreachable!(),
|
_ => 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!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue