mirror of
https://github.com/apache/datafusion-sqlparser-rs.git
synced 2025-08-23 07:24:10 +00:00
Add support for VACUUM in Redshift (#2005)
Some checks are pending
license / Release Audit Tool (RAT) (push) Waiting to run
Rust / codestyle (push) Waiting to run
Rust / lint (push) Waiting to run
Rust / benchmark-lint (push) Waiting to run
Rust / compile (push) Waiting to run
Rust / docs (push) Waiting to run
Rust / compile-no-std (push) Waiting to run
Rust / test (beta) (push) Waiting to run
Rust / test (nightly) (push) Waiting to run
Rust / test (stable) (push) Waiting to run
Some checks are pending
license / Release Audit Tool (RAT) (push) Waiting to run
Rust / codestyle (push) Waiting to run
Rust / lint (push) Waiting to run
Rust / benchmark-lint (push) Waiting to run
Rust / compile (push) Waiting to run
Rust / docs (push) Waiting to run
Rust / compile-no-std (push) Waiting to run
Rust / test (beta) (push) Waiting to run
Rust / test (nightly) (push) Waiting to run
Rust / test (stable) (push) Waiting to run
This commit is contained in:
parent
cb7a51e85f
commit
e9eee00ed9
5 changed files with 138 additions and 0 deletions
|
@ -4409,6 +4409,13 @@ pub enum Statement {
|
||||||
/// ```
|
/// ```
|
||||||
/// [Snowflake](https://docs.snowflake.com/en/sql-reference/sql/create-user)
|
/// [Snowflake](https://docs.snowflake.com/en/sql-reference/sql/create-user)
|
||||||
CreateUser(CreateUser),
|
CreateUser(CreateUser),
|
||||||
|
/// Re-sorts rows and reclaims space in either a specified table or all tables in the current database
|
||||||
|
///
|
||||||
|
/// ```sql
|
||||||
|
/// VACUUM tbl
|
||||||
|
/// ```
|
||||||
|
/// [Redshift](https://docs.aws.amazon.com/redshift/latest/dg/r_VACUUM_command.html)
|
||||||
|
Vacuum(VacuumStatement),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ```sql
|
/// ```sql
|
||||||
|
@ -6343,6 +6350,7 @@ impl fmt::Display for Statement {
|
||||||
Statement::ExportData(e) => write!(f, "{e}"),
|
Statement::ExportData(e) => write!(f, "{e}"),
|
||||||
Statement::CreateUser(s) => write!(f, "{s}"),
|
Statement::CreateUser(s) => write!(f, "{s}"),
|
||||||
Statement::AlterSchema(s) => write!(f, "{s}"),
|
Statement::AlterSchema(s) => write!(f, "{s}"),
|
||||||
|
Statement::Vacuum(s) => write!(f, "{s}"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10604,6 +10612,50 @@ impl fmt::Display for InitializeKind {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Re-sorts rows and reclaims space in either a specified table or all tables in the current database
|
||||||
|
///
|
||||||
|
/// '''sql
|
||||||
|
/// VACUUM [ FULL | SORT ONLY | DELETE ONLY | REINDEX | RECLUSTER ] [ \[ table_name \] [ TO threshold PERCENT ] \[ BOOST \] ]
|
||||||
|
/// '''
|
||||||
|
/// [Redshift](https://docs.aws.amazon.com/redshift/latest/dg/r_VACUUM_command.html)
|
||||||
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
|
||||||
|
pub struct VacuumStatement {
|
||||||
|
pub full: bool,
|
||||||
|
pub sort_only: bool,
|
||||||
|
pub delete_only: bool,
|
||||||
|
pub reindex: bool,
|
||||||
|
pub recluster: bool,
|
||||||
|
pub table_name: Option<ObjectName>,
|
||||||
|
pub threshold: Option<Value>,
|
||||||
|
pub boost: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for VacuumStatement {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
write!(
|
||||||
|
f,
|
||||||
|
"VACUUM{}{}{}{}{}",
|
||||||
|
if self.full { " FULL" } else { "" },
|
||||||
|
if self.sort_only { " SORT ONLY" } else { "" },
|
||||||
|
if self.delete_only { " DELETE ONLY" } else { "" },
|
||||||
|
if self.reindex { " REINDEX" } else { "" },
|
||||||
|
if self.recluster { " RECLUSTER" } else { "" },
|
||||||
|
)?;
|
||||||
|
if let Some(table_name) = &self.table_name {
|
||||||
|
write!(f, " {table_name}")?;
|
||||||
|
}
|
||||||
|
if let Some(threshold) = &self.threshold {
|
||||||
|
write!(f, " TO {threshold} PERCENT")?;
|
||||||
|
}
|
||||||
|
if self.boost {
|
||||||
|
write!(f, " BOOST")?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::tokenizer::Location;
|
use crate::tokenizer::Location;
|
||||||
|
|
|
@ -552,6 +552,7 @@ impl Spanned for Statement {
|
||||||
),
|
),
|
||||||
Statement::CreateUser(..) => Span::empty(),
|
Statement::CreateUser(..) => Span::empty(),
|
||||||
Statement::AlterSchema(s) => s.span(),
|
Statement::AlterSchema(s) => s.span(),
|
||||||
|
Statement::Vacuum(..) => Span::empty(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -144,6 +144,7 @@ define_keywords!(
|
||||||
BLOOMFILTER,
|
BLOOMFILTER,
|
||||||
BOOL,
|
BOOL,
|
||||||
BOOLEAN,
|
BOOLEAN,
|
||||||
|
BOOST,
|
||||||
BOTH,
|
BOTH,
|
||||||
BOX,
|
BOX,
|
||||||
BRIN,
|
BRIN,
|
||||||
|
@ -761,6 +762,7 @@ define_keywords!(
|
||||||
REGR_SXX,
|
REGR_SXX,
|
||||||
REGR_SXY,
|
REGR_SXY,
|
||||||
REGR_SYY,
|
REGR_SYY,
|
||||||
|
REINDEX,
|
||||||
RELATIVE,
|
RELATIVE,
|
||||||
RELAY,
|
RELAY,
|
||||||
RELEASE,
|
RELEASE,
|
||||||
|
|
|
@ -649,6 +649,10 @@ impl<'a> Parser<'a> {
|
||||||
self.prev_token();
|
self.prev_token();
|
||||||
self.parse_export_data()
|
self.parse_export_data()
|
||||||
}
|
}
|
||||||
|
Keyword::VACUUM => {
|
||||||
|
self.prev_token();
|
||||||
|
self.parse_vacuum()
|
||||||
|
}
|
||||||
_ => self.expected("an SQL statement", next_token),
|
_ => self.expected("an SQL statement", next_token),
|
||||||
},
|
},
|
||||||
Token::LParen => {
|
Token::LParen => {
|
||||||
|
@ -16932,6 +16936,40 @@ impl<'a> Parser<'a> {
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn parse_vacuum(&mut self) -> Result<Statement, ParserError> {
|
||||||
|
self.expect_keyword(Keyword::VACUUM)?;
|
||||||
|
let full = self.parse_keyword(Keyword::FULL);
|
||||||
|
let sort_only = self.parse_keywords(&[Keyword::SORT, Keyword::ONLY]);
|
||||||
|
let delete_only = self.parse_keywords(&[Keyword::DELETE, Keyword::ONLY]);
|
||||||
|
let reindex = self.parse_keyword(Keyword::REINDEX);
|
||||||
|
let recluster = self.parse_keyword(Keyword::RECLUSTER);
|
||||||
|
let (table_name, threshold, boost) =
|
||||||
|
match self.maybe_parse(|p| p.parse_object_name(false))? {
|
||||||
|
Some(table_name) => {
|
||||||
|
let threshold = if self.parse_keyword(Keyword::TO) {
|
||||||
|
let value = self.parse_value()?;
|
||||||
|
self.expect_keyword(Keyword::PERCENT)?;
|
||||||
|
Some(value.value)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
let boost = self.parse_keyword(Keyword::BOOST);
|
||||||
|
(Some(table_name), threshold, boost)
|
||||||
|
}
|
||||||
|
_ => (None, None, false),
|
||||||
|
};
|
||||||
|
Ok(Statement::Vacuum(VacuumStatement {
|
||||||
|
full,
|
||||||
|
sort_only,
|
||||||
|
delete_only,
|
||||||
|
reindex,
|
||||||
|
recluster,
|
||||||
|
table_name,
|
||||||
|
threshold,
|
||||||
|
boost,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
/// Consume the parser and return its underlying token buffer
|
/// Consume the parser and return its underlying token buffer
|
||||||
pub fn into_tokens(self) -> Vec<TokenWithSpan> {
|
pub fn into_tokens(self) -> Vec<TokenWithSpan> {
|
||||||
self.tokens
|
self.tokens
|
||||||
|
|
|
@ -407,3 +407,48 @@ fn parse_string_literal_backslash_escape() {
|
||||||
fn parse_utf8_multibyte_idents() {
|
fn parse_utf8_multibyte_idents() {
|
||||||
redshift().verified_stmt("SELECT 🚀.city AS 🎸 FROM customers AS 🚀");
|
redshift().verified_stmt("SELECT 🚀.city AS 🎸 FROM customers AS 🚀");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn parse_vacuum() {
|
||||||
|
let stmt = redshift().verified_stmt("VACUUM FULL");
|
||||||
|
match stmt {
|
||||||
|
Statement::Vacuum(v) => {
|
||||||
|
assert!(v.full);
|
||||||
|
assert_eq!(v.table_name, None);
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
let stmt = redshift().verified_stmt("VACUUM tbl");
|
||||||
|
match stmt {
|
||||||
|
Statement::Vacuum(v) => {
|
||||||
|
assert_eq!(
|
||||||
|
v.table_name,
|
||||||
|
Some(ObjectName::from(vec![Ident::new("tbl"),]))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
let stmt = redshift().verified_stmt(
|
||||||
|
"VACUUM FULL SORT ONLY DELETE ONLY REINDEX RECLUSTER db1.sc1.tbl1 TO 20 PERCENT BOOST",
|
||||||
|
);
|
||||||
|
match stmt {
|
||||||
|
Statement::Vacuum(v) => {
|
||||||
|
assert!(v.full);
|
||||||
|
assert!(v.sort_only);
|
||||||
|
assert!(v.delete_only);
|
||||||
|
assert!(v.reindex);
|
||||||
|
assert!(v.recluster);
|
||||||
|
assert_eq!(
|
||||||
|
v.table_name,
|
||||||
|
Some(ObjectName::from(vec![
|
||||||
|
Ident::new("db1"),
|
||||||
|
Ident::new("sc1"),
|
||||||
|
Ident::new("tbl1"),
|
||||||
|
]))
|
||||||
|
);
|
||||||
|
assert_eq!(v.threshold, Some(number("20")));
|
||||||
|
assert!(v.boost);
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue