mirror of
https://github.com/apache/datafusion-sqlparser-rs.git
synced 2025-08-22 23:14:07 +00:00
Implement CREATE TABLE IF NOT EXISTS (#163)
A non-standard feature supported at least by Postgres https://www.postgresql.org/docs/12/sql-createtable.html
This commit is contained in:
parent
06865113d7
commit
5ad578e3e5
4 changed files with 62 additions and 1 deletions
|
@ -471,6 +471,7 @@ pub enum Statement {
|
||||||
columns: Vec<ColumnDef>,
|
columns: Vec<ColumnDef>,
|
||||||
constraints: Vec<TableConstraint>,
|
constraints: Vec<TableConstraint>,
|
||||||
with_options: Vec<SqlOption>,
|
with_options: Vec<SqlOption>,
|
||||||
|
if_not_exists: bool,
|
||||||
external: bool,
|
external: bool,
|
||||||
file_format: Option<FileFormat>,
|
file_format: Option<FileFormat>,
|
||||||
location: Option<String>,
|
location: Option<String>,
|
||||||
|
@ -623,14 +624,16 @@ impl fmt::Display for Statement {
|
||||||
columns,
|
columns,
|
||||||
constraints,
|
constraints,
|
||||||
with_options,
|
with_options,
|
||||||
|
if_not_exists,
|
||||||
external,
|
external,
|
||||||
file_format,
|
file_format,
|
||||||
location,
|
location,
|
||||||
} => {
|
} => {
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
"CREATE {}TABLE {} ({}",
|
"CREATE {}TABLE {}{} ({}",
|
||||||
if *external { "EXTERNAL " } else { "" },
|
if *external { "EXTERNAL " } else { "" },
|
||||||
|
if *if_not_exists { "IF NOT EXISTS " } else { "" },
|
||||||
name,
|
name,
|
||||||
display_comma_separated(columns)
|
display_comma_separated(columns)
|
||||||
)?;
|
)?;
|
||||||
|
|
|
@ -880,6 +880,7 @@ impl Parser {
|
||||||
columns,
|
columns,
|
||||||
constraints,
|
constraints,
|
||||||
with_options: vec![],
|
with_options: vec![],
|
||||||
|
if_not_exists: false,
|
||||||
external: true,
|
external: true,
|
||||||
file_format: Some(file_format),
|
file_format: Some(file_format),
|
||||||
location: Some(location),
|
location: Some(location),
|
||||||
|
@ -932,6 +933,7 @@ impl Parser {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse_create_table(&mut self) -> Result<Statement, ParserError> {
|
pub fn parse_create_table(&mut self) -> Result<Statement, ParserError> {
|
||||||
|
let if_not_exists = self.parse_keywords(vec!["IF", "NOT", "EXISTS"]);
|
||||||
let table_name = self.parse_object_name()?;
|
let table_name = self.parse_object_name()?;
|
||||||
// parse optional column list (schema)
|
// parse optional column list (schema)
|
||||||
let (columns, constraints) = self.parse_columns()?;
|
let (columns, constraints) = self.parse_columns()?;
|
||||||
|
@ -942,6 +944,7 @@ impl Parser {
|
||||||
columns,
|
columns,
|
||||||
constraints,
|
constraints,
|
||||||
with_options,
|
with_options,
|
||||||
|
if_not_exists,
|
||||||
external: false,
|
external: false,
|
||||||
file_format: None,
|
file_format: None,
|
||||||
location: None,
|
location: None,
|
||||||
|
|
|
@ -909,6 +909,7 @@ fn parse_create_table() {
|
||||||
columns,
|
columns,
|
||||||
constraints,
|
constraints,
|
||||||
with_options,
|
with_options,
|
||||||
|
if_not_exists: false,
|
||||||
external: false,
|
external: false,
|
||||||
file_format: None,
|
file_format: None,
|
||||||
location: None,
|
location: None,
|
||||||
|
@ -1045,6 +1046,7 @@ fn parse_create_external_table() {
|
||||||
columns,
|
columns,
|
||||||
constraints,
|
constraints,
|
||||||
with_options,
|
with_options,
|
||||||
|
if_not_exists,
|
||||||
external,
|
external,
|
||||||
file_format,
|
file_format,
|
||||||
location,
|
location,
|
||||||
|
@ -1086,6 +1088,7 @@ fn parse_create_external_table() {
|
||||||
assert_eq!("/tmp/example.csv", location.unwrap());
|
assert_eq!("/tmp/example.csv", location.unwrap());
|
||||||
|
|
||||||
assert_eq!(with_options, vec![]);
|
assert_eq!(with_options, vec![]);
|
||||||
|
assert!(!if_not_exists);
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,6 +39,7 @@ fn parse_create_table_with_defaults() {
|
||||||
columns,
|
columns,
|
||||||
constraints,
|
constraints,
|
||||||
with_options,
|
with_options,
|
||||||
|
if_not_exists: false,
|
||||||
external: false,
|
external: false,
|
||||||
file_format: None,
|
file_format: None,
|
||||||
location: None,
|
location: None,
|
||||||
|
@ -225,6 +226,57 @@ fn parse_create_table_with_inherit() {
|
||||||
pg().verified_stmt(sql);
|
pg().verified_stmt(sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn parse_create_table_if_not_exists() {
|
||||||
|
let sql = "CREATE TABLE IF NOT EXISTS uk_cities ()";
|
||||||
|
let ast =
|
||||||
|
pg_and_generic().one_statement_parses_to(sql, "CREATE TABLE IF NOT EXISTS uk_cities ()");
|
||||||
|
match ast {
|
||||||
|
Statement::CreateTable {
|
||||||
|
name,
|
||||||
|
columns: _columns,
|
||||||
|
constraints,
|
||||||
|
with_options,
|
||||||
|
if_not_exists: true,
|
||||||
|
external: false,
|
||||||
|
file_format: None,
|
||||||
|
location: None,
|
||||||
|
} => {
|
||||||
|
assert_eq!("uk_cities", name.to_string());
|
||||||
|
assert!(constraints.is_empty());
|
||||||
|
assert_eq!(with_options, vec![]);
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn parse_bad_if_not_exists() {
|
||||||
|
let res = pg().parse_sql_statements("CREATE TABLE NOT EXISTS uk_cities ()");
|
||||||
|
assert_eq!(
|
||||||
|
ParserError::ParserError("Expected end of statement, found: EXISTS".to_string()),
|
||||||
|
res.unwrap_err()
|
||||||
|
);
|
||||||
|
|
||||||
|
let res = pg().parse_sql_statements("CREATE TABLE IF EXISTS uk_cities ()");
|
||||||
|
assert_eq!(
|
||||||
|
ParserError::ParserError("Expected end of statement, found: EXISTS".to_string()),
|
||||||
|
res.unwrap_err()
|
||||||
|
);
|
||||||
|
|
||||||
|
let res = pg().parse_sql_statements("CREATE TABLE IF uk_cities ()");
|
||||||
|
assert_eq!(
|
||||||
|
ParserError::ParserError("Expected end of statement, found: uk_cities".to_string()),
|
||||||
|
res.unwrap_err()
|
||||||
|
);
|
||||||
|
|
||||||
|
let res = pg().parse_sql_statements("CREATE TABLE IF NOT uk_cities ()");
|
||||||
|
assert_eq!(
|
||||||
|
ParserError::ParserError("Expected end of statement, found: NOT".to_string()),
|
||||||
|
res.unwrap_err()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn parse_copy_example() {
|
fn parse_copy_example() {
|
||||||
let sql = r#"COPY public.actor (actor_id, first_name, last_name, last_update, value) FROM stdin;
|
let sql = r#"COPY public.actor (actor_id, first_name, last_name, last_update, value) FROM stdin;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue