Support Unload statement (#1150)

Co-authored-by: Andrew Lamb <andrew@nerdnetworks.org>
This commit is contained in:
Jonathan Lehto 2024-02-29 14:55:46 -05:00 committed by GitHub
parent 4d1eecd0fc
commit e2ce324722
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 96 additions and 1 deletions

View file

@ -2547,6 +2547,16 @@ pub enum Statement {
/// ```
/// Note: this is a MySQL-specific statement. See <https://dev.mysql.com/doc/refman/8.0/en/lock-tables.html>
UnlockTables,
/// ```sql
/// UNLOAD(statement) TO <destination> [ WITH options ]
/// ```
/// See Redshift <https://docs.aws.amazon.com/redshift/latest/dg/r_UNLOAD.html> and
// Athena <https://docs.aws.amazon.com/athena/latest/ug/unload.html>
Unload {
query: Box<Query>,
to: Ident,
with: Vec<SqlOption>,
},
}
impl fmt::Display for Statement {
@ -4060,6 +4070,15 @@ impl fmt::Display for Statement {
Statement::UnlockTables => {
write!(f, "UNLOCK TABLES")
}
Statement::Unload { query, to, with } => {
write!(f, "UNLOAD({query}) TO {to}")?;
if !with.is_empty() {
write!(f, " WITH ({})", display_comma_separated(with))?;
}
Ok(())
}
}
}
}

View file

@ -689,6 +689,7 @@ define_keywords!(
UNION,
UNIQUE,
UNKNOWN,
UNLOAD,
UNLOCK,
UNLOGGED,
UNNEST,

View file

@ -516,6 +516,7 @@ impl<'a> Parser<'a> {
Keyword::MERGE => Ok(self.parse_merge()?),
// `PRAGMA` is sqlite specific https://www.sqlite.org/pragma.html
Keyword::PRAGMA => Ok(self.parse_pragma()?),
Keyword::UNLOAD => Ok(self.parse_unload()?),
// `INSTALL` is duckdb specific https://duckdb.org/docs/extensions/overview
Keyword::INSTALL if dialect_of!(self is DuckDbDialect | GenericDialect) => {
Ok(self.parse_install()?)
@ -524,7 +525,6 @@ impl<'a> Parser<'a> {
Keyword::LOAD if dialect_of!(self is DuckDbDialect | GenericDialect) => {
Ok(self.parse_load()?)
}
_ => self.expected("an SQL statement", next_token),
},
Token::LParen => {
@ -8947,6 +8947,23 @@ impl<'a> Parser<'a> {
})
}
pub fn parse_unload(&mut self) -> Result<Statement, ParserError> {
self.expect_token(&Token::LParen)?;
let query = self.parse_query()?;
self.expect_token(&Token::RParen)?;
self.expect_keyword(Keyword::TO)?;
let to = self.parse_identifier(false)?;
let with_options = self.parse_options(Keyword::WITH)?;
Ok(Statement::Unload {
query: Box::new(query),
to,
with: with_options,
})
}
pub fn parse_merge_clauses(&mut self) -> Result<Vec<MergeClause>, ParserError> {
let mut clauses: Vec<MergeClause> = vec![];
loop {