diff --git a/src/ast/mod.rs b/src/ast/mod.rs index 31171db7d..8a58207d7 100644 --- a/src/ast/mod.rs +++ b/src/ast/mod.rs @@ -558,7 +558,10 @@ pub enum Statement { /// `ROLLBACK [ TRANSACTION | WORK ] [ AND [ NO ] CHAIN ]` Rollback { chain: bool }, /// CREATE SCHEMA - CreateSchema { schema_name: ObjectName }, + CreateSchema { + schema_name: ObjectName, + if_not_exists: bool, + }, /// `ASSERT [AS ]` Assert { condition: Expr, @@ -829,7 +832,15 @@ impl fmt::Display for Statement { Statement::Rollback { chain } => { write!(f, "ROLLBACK{}", if *chain { " AND CHAIN" } else { "" },) } - Statement::CreateSchema { schema_name } => write!(f, "CREATE SCHEMA {}", schema_name), + Statement::CreateSchema { + schema_name, + if_not_exists, + } => write!( + f, + "CREATE SCHEMA {if_not_exists}{name}", + if_not_exists = if *if_not_exists { "IF NOT EXISTS " } else { "" }, + name = schema_name + ), Statement::Assert { condition, message } => { write!(f, "ASSERT {}", condition)?; if let Some(m) = message { diff --git a/src/parser.rs b/src/parser.rs index f7630b037..438c9f1ef 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -1078,8 +1078,12 @@ impl<'a> Parser<'a> { } pub fn parse_create_schema(&mut self) -> Result { + let if_not_exists = self.parse_keywords(&[Keyword::IF, Keyword::NOT, Keyword::EXISTS]); let schema_name = self.parse_object_name()?; - Ok(Statement::CreateSchema { schema_name }) + Ok(Statement::CreateSchema { + schema_name, + if_not_exists, + }) } pub fn parse_create_external_table( diff --git a/tests/sqlparser_common.rs b/tests/sqlparser_common.rs index 4050cdf0b..6b032d926 100644 --- a/tests/sqlparser_common.rs +++ b/tests/sqlparser_common.rs @@ -1204,7 +1204,7 @@ fn parse_create_schema() { let sql = "CREATE SCHEMA X"; match verified_stmt(sql) { - Statement::CreateSchema { schema_name } => { + Statement::CreateSchema { schema_name, .. } => { assert_eq!(schema_name.to_string(), "X".to_owned()) } _ => unreachable!(), diff --git a/tests/sqlparser_postgres.rs b/tests/sqlparser_postgres.rs index 1083e9971..ecc0e77e3 100644 --- a/tests/sqlparser_postgres.rs +++ b/tests/sqlparser_postgres.rs @@ -300,6 +300,33 @@ fn parse_bad_if_not_exists() { ); } +#[test] +fn parse_create_schema_if_not_exists() { + let sql = "CREATE SCHEMA IF NOT EXISTS schema_name"; + let ast = pg_and_generic().verified_stmt(sql); + match ast { + Statement::CreateSchema { + if_not_exists: true, + schema_name, + } => assert_eq!("schema_name", schema_name.to_string()), + _ => unreachable!(), + } +} + +#[test] +fn parse_drop_schema_if_exists() { + let sql = "DROP SCHEMA IF EXISTS schema_name"; + let ast = pg().verified_stmt(sql); + match ast { + Statement::Drop { + object_type, + if_exists: true, + .. + } => assert_eq!(object_type, ObjectType::Schema), + _ => unreachable!(), + } +} + #[test] fn parse_copy_example() { let sql = r#"COPY public.actor (actor_id, first_name, last_name, last_update, value) FROM stdin;