mirror of
https://github.com/apache/datafusion-sqlparser-rs.git
synced 2025-07-16 13:04:58 +00:00
Support global
,local
, on commit
for create temporary table
(#456)
* feat: add global,local / on commit for create temp tables * chore: minor refactor * chore: clippy fix
This commit is contained in:
parent
278345d21a
commit
0924870d11
4 changed files with 81 additions and 2 deletions
|
@ -831,6 +831,7 @@ pub enum Statement {
|
|||
or_replace: bool,
|
||||
temporary: bool,
|
||||
external: bool,
|
||||
global: Option<bool>,
|
||||
if_not_exists: bool,
|
||||
/// Table name
|
||||
name: ObjectName,
|
||||
|
@ -849,6 +850,7 @@ pub enum Statement {
|
|||
engine: Option<String>,
|
||||
default_charset: Option<String>,
|
||||
collation: Option<String>,
|
||||
on_commit: Option<OnCommit>,
|
||||
},
|
||||
/// SQLite's `CREATE VIRTUAL TABLE .. USING <module_name> (<module_args>)`
|
||||
CreateVirtualTable {
|
||||
|
@ -1313,6 +1315,7 @@ impl fmt::Display for Statement {
|
|||
hive_distribution,
|
||||
hive_formats,
|
||||
external,
|
||||
global,
|
||||
temporary,
|
||||
file_format,
|
||||
location,
|
||||
|
@ -1322,6 +1325,7 @@ impl fmt::Display for Statement {
|
|||
default_charset,
|
||||
engine,
|
||||
collation,
|
||||
on_commit,
|
||||
} => {
|
||||
// We want to allow the following options
|
||||
// Empty column list, allowed by PostgreSQL:
|
||||
|
@ -1332,9 +1336,18 @@ impl fmt::Display for Statement {
|
|||
// `CREATE TABLE t (a INT) AS SELECT a from t2`
|
||||
write!(
|
||||
f,
|
||||
"CREATE {or_replace}{external}{temporary}TABLE {if_not_exists}{name}",
|
||||
"CREATE {or_replace}{external}{global}{temporary}TABLE {if_not_exists}{name}",
|
||||
or_replace = if *or_replace { "OR REPLACE " } else { "" },
|
||||
external = if *external { "EXTERNAL " } else { "" },
|
||||
global = global
|
||||
.map(|global| {
|
||||
if global {
|
||||
"GLOBAL "
|
||||
} else {
|
||||
"LOCAL "
|
||||
}
|
||||
})
|
||||
.unwrap_or(""),
|
||||
if_not_exists = if *if_not_exists { "IF NOT EXISTS " } else { "" },
|
||||
temporary = if *temporary { "TEMPORARY " } else { "" },
|
||||
name = name,
|
||||
|
@ -1456,6 +1469,17 @@ impl fmt::Display for Statement {
|
|||
if let Some(collation) = collation {
|
||||
write!(f, " COLLATE={}", collation)?;
|
||||
}
|
||||
|
||||
if on_commit.is_some() {
|
||||
let on_commit = match on_commit {
|
||||
Some(OnCommit::DeleteRows) => "ON COMMIT DELETE ROWS",
|
||||
Some(OnCommit::PreserveRows) => "ON COMMIT PRESERVE ROWS",
|
||||
Some(OnCommit::Drop) => "ON COMMIT DROP",
|
||||
None => "",
|
||||
};
|
||||
write!(f, " {}", on_commit)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
Statement::CreateVirtualTable {
|
||||
|
@ -2276,6 +2300,14 @@ impl fmt::Display for CopyTarget {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
pub enum OnCommit {
|
||||
DeleteRows,
|
||||
PreserveRows,
|
||||
Drop,
|
||||
}
|
||||
|
||||
/// An option in `COPY` statement.
|
||||
///
|
||||
/// <https://www.postgresql.org/docs/14/sql-copy.html>
|
||||
|
|
|
@ -376,6 +376,7 @@ define_keywords!(
|
|||
PRECEDING,
|
||||
PRECISION,
|
||||
PREPARE,
|
||||
PRESERVE,
|
||||
PRIMARY,
|
||||
PRIVILEGES,
|
||||
PROCEDURE,
|
||||
|
|
|
@ -1519,11 +1519,20 @@ impl<'a> Parser<'a> {
|
|||
/// Parse a SQL CREATE statement
|
||||
pub fn parse_create(&mut self) -> Result<Statement, ParserError> {
|
||||
let or_replace = self.parse_keywords(&[Keyword::OR, Keyword::REPLACE]);
|
||||
let local = self.parse_one_of_keywords(&[Keyword::LOCAL]).is_some();
|
||||
let global = self.parse_one_of_keywords(&[Keyword::GLOBAL]).is_some();
|
||||
let global: Option<bool> = if global {
|
||||
Some(true)
|
||||
} else if local {
|
||||
Some(false)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let temporary = self
|
||||
.parse_one_of_keywords(&[Keyword::TEMP, Keyword::TEMPORARY])
|
||||
.is_some();
|
||||
if self.parse_keyword(Keyword::TABLE) {
|
||||
self.parse_create_table(or_replace, temporary)
|
||||
self.parse_create_table(or_replace, temporary, global)
|
||||
} else if self.parse_keyword(Keyword::MATERIALIZED) || self.parse_keyword(Keyword::VIEW) {
|
||||
self.prev_token();
|
||||
self.parse_create_view(or_replace)
|
||||
|
@ -1633,6 +1642,7 @@ impl<'a> Parser<'a> {
|
|||
or_replace,
|
||||
if_not_exists,
|
||||
external: true,
|
||||
global: None,
|
||||
temporary: false,
|
||||
file_format,
|
||||
location,
|
||||
|
@ -1642,6 +1652,7 @@ impl<'a> Parser<'a> {
|
|||
default_charset: None,
|
||||
engine: None,
|
||||
collation: None,
|
||||
on_commit: None,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -1790,6 +1801,7 @@ impl<'a> Parser<'a> {
|
|||
&mut self,
|
||||
or_replace: bool,
|
||||
temporary: bool,
|
||||
global: Option<bool>,
|
||||
) -> Result<Statement, ParserError> {
|
||||
let if_not_exists = self.parse_keywords(&[Keyword::IF, Keyword::NOT, Keyword::EXISTS]);
|
||||
let table_name = self.parse_object_name()?;
|
||||
|
@ -1846,6 +1858,23 @@ impl<'a> Parser<'a> {
|
|||
None
|
||||
};
|
||||
|
||||
let on_commit: Option<OnCommit> =
|
||||
if self.parse_keywords(&[Keyword::ON, Keyword::COMMIT, Keyword::DELETE, Keyword::ROWS])
|
||||
{
|
||||
Some(OnCommit::DeleteRows)
|
||||
} else if self.parse_keywords(&[
|
||||
Keyword::ON,
|
||||
Keyword::COMMIT,
|
||||
Keyword::PRESERVE,
|
||||
Keyword::ROWS,
|
||||
]) {
|
||||
Some(OnCommit::PreserveRows)
|
||||
} else if self.parse_keywords(&[Keyword::ON, Keyword::COMMIT, Keyword::DROP]) {
|
||||
Some(OnCommit::Drop)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
Ok(Statement::CreateTable {
|
||||
name: table_name,
|
||||
temporary,
|
||||
|
@ -1858,6 +1887,7 @@ impl<'a> Parser<'a> {
|
|||
hive_distribution,
|
||||
hive_formats: Some(hive_formats),
|
||||
external: false,
|
||||
global,
|
||||
file_format: None,
|
||||
location: None,
|
||||
query,
|
||||
|
@ -1866,6 +1896,7 @@ impl<'a> Parser<'a> {
|
|||
engine,
|
||||
default_charset,
|
||||
collation,
|
||||
on_commit,
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -1347,6 +1347,21 @@ fn parse_quoted_identifier() {
|
|||
pg_and_generic().verified_stmt(r#"SELECT "quoted "" ident""#);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_local_and_global() {
|
||||
pg_and_generic().verified_stmt("CREATE LOCAL TEMPORARY TABLE table (COL INT)");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_on_commit() {
|
||||
pg_and_generic()
|
||||
.verified_stmt("CREATE TEMPORARY TABLE table (COL INT) ON COMMIT PRESERVE ROWS");
|
||||
|
||||
pg_and_generic().verified_stmt("CREATE TEMPORARY TABLE table (COL INT) ON COMMIT DELETE ROWS");
|
||||
|
||||
pg_and_generic().verified_stmt("CREATE TEMPORARY TABLE table (COL INT) ON COMMIT DROP");
|
||||
}
|
||||
|
||||
fn pg() -> TestedDialects {
|
||||
TestedDialects {
|
||||
dialects: vec![Box::new(PostgreSqlDialect {})],
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue