diff --git a/src/ast/mod.rs b/src/ast/mod.rs index b1a81c769..9471c4d9a 100644 --- a/src/ast/mod.rs +++ b/src/ast/mod.rs @@ -4356,6 +4356,8 @@ pub enum Statement { CreateSchema { /// ` | AUTHORIZATION | AUTHORIZATION ` schema_name: SchemaName, + /// `true` when `OR REPLACE` was present. + or_replace: bool, /// `true` when `IF NOT EXISTS` was present. if_not_exists: bool, /// Schema properties. @@ -6026,6 +6028,7 @@ impl fmt::Display for Statement { } Statement::CreateSchema { schema_name, + or_replace, if_not_exists, with, options, @@ -6034,7 +6037,8 @@ impl fmt::Display for Statement { } => { write!( f, - "CREATE SCHEMA {if_not_exists}{name}", + "CREATE {or_replace}SCHEMA {if_not_exists}{name}", + or_replace = if *or_replace { "OR REPLACE " } else { "" }, if_not_exists = if *if_not_exists { "IF NOT EXISTS " } else { "" }, name = schema_name )?; diff --git a/src/parser/mod.rs b/src/parser/mod.rs index 6df5cf309..af2b727b2 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -5283,11 +5283,13 @@ impl<'a> Parser<'a> { self.parse_create_secret(or_replace, temporary, persistent) } else if self.parse_keyword(Keyword::USER) { self.parse_create_user(or_replace).map(Into::into) + } else if self.parse_keyword(Keyword::SCHEMA) { + self.parse_create_schema(or_replace) } else if self.parse_keyword(Keyword::WAREHOUSE) { self.parse_create_warehouse(or_replace).map(Into::into) } else if or_replace { self.expected_ref( - "[EXTERNAL] TABLE or [MATERIALIZED] VIEW or FUNCTION or WAREHOUSE after CREATE OR REPLACE", + "[EXTERNAL] TABLE or [MATERIALIZED] VIEW or FUNCTION or SCHEMA or WAREHOUSE after CREATE OR REPLACE", self.peek_token_ref(), ) } else if self.parse_keyword(Keyword::EXTENSION) { @@ -5298,8 +5300,6 @@ impl<'a> Parser<'a> { self.parse_create_index(true).map(Into::into) } else if self.parse_keyword(Keyword::VIRTUAL) { self.parse_create_virtual_table() - } else if self.parse_keyword(Keyword::SCHEMA) { - self.parse_create_schema() } else if self.parse_keyword(Keyword::DATABASE) { self.parse_create_database() } else if self.parse_keyword(Keyword::ROLE) { @@ -5629,7 +5629,7 @@ impl<'a> Parser<'a> { } /// Parse a `CREATE SCHEMA` statement. - pub fn parse_create_schema(&mut self) -> Result { + pub fn parse_create_schema(&mut self, or_replace: bool) -> Result { let if_not_exists = self.parse_keywords(&[Keyword::IF, Keyword::NOT, Keyword::EXISTS]); let schema_name = self.parse_schema_name()?; @@ -5660,6 +5660,7 @@ impl<'a> Parser<'a> { Ok(Statement::CreateSchema { schema_name, + or_replace, if_not_exists, with, options, diff --git a/tests/sqlparser_common.rs b/tests/sqlparser_common.rs index edd9a9e37..2a7cce1d3 100644 --- a/tests/sqlparser_common.rs +++ b/tests/sqlparser_common.rs @@ -4545,6 +4545,25 @@ fn parse_create_schema() { verified_stmt(r#"CREATE SCHEMA a CLONE b"#); } +#[test] +fn parse_create_or_replace_schema() { + match verified_stmt("CREATE OR REPLACE SCHEMA X") { + Statement::CreateSchema { + schema_name, + or_replace, + if_not_exists, + .. + } => { + assert_eq!(schema_name.to_string(), "X".to_owned()); + assert!(or_replace); + assert!(!if_not_exists); + } + _ => unreachable!(), + } + + verified_stmt("CREATE OR REPLACE SCHEMA IF NOT EXISTS X"); +} + #[test] fn parse_create_schema_with_authorization() { let sql = "CREATE SCHEMA AUTHORIZATION Y";