645 New schema name structure (#646)

This commit is contained in:
AugustoFKL 2022-10-03 09:38:01 -03:00 committed by GitHub
parent 95464ec72c
commit 1ced0f6304
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 109 additions and 2 deletions

View file

@ -1300,7 +1300,8 @@ pub enum Statement {
Rollback { chain: bool },
/// CREATE SCHEMA
CreateSchema {
schema_name: ObjectName,
/// `<schema name> | AUTHORIZATION <schema authorization identifier> | <schema name> AUTHORIZATION <schema authorization identifier>`
schema_name: SchemaName,
if_not_exists: bool,
},
/// CREATE DATABASE
@ -3275,6 +3276,36 @@ impl fmt::Display for CreateFunctionUsing {
}
}
/// Schema possible naming variants ([1]).
///
/// [1]: https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#schema-definition
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum SchemaName {
/// Only schema name specified: `<schema name>`.
Simple(ObjectName),
/// Only authorization identifier specified: `AUTHORIZATION <schema authorization identifier>`.
UnnamedAuthorization(Ident),
/// Both schema name and authorization identifier specified: `<schema name> AUTHORIZATION <schema authorization identifier>`.
NamedAuthorization(ObjectName, Ident),
}
impl fmt::Display for SchemaName {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
SchemaName::Simple(name) => {
write!(f, "{name}")
}
SchemaName::UnnamedAuthorization(authorization) => {
write!(f, "AUTHORIZATION {authorization}")
}
SchemaName::NamedAuthorization(name, authorization) => {
write!(f, "{name} AUTHORIZATION {authorization}")
}
}
}
}
#[cfg(test)]
mod tests {
use super::*;

View file

@ -1896,13 +1896,32 @@ impl<'a> Parser<'a> {
pub fn parse_create_schema(&mut self) -> Result<Statement, ParserError> {
let if_not_exists = self.parse_keywords(&[Keyword::IF, Keyword::NOT, Keyword::EXISTS]);
let schema_name = self.parse_object_name()?;
let schema_name = self.parse_schema_name()?;
Ok(Statement::CreateSchema {
schema_name,
if_not_exists,
})
}
fn parse_schema_name(&mut self) -> Result<SchemaName, ParserError> {
if self.parse_keyword(Keyword::AUTHORIZATION) {
Ok(SchemaName::UnnamedAuthorization(self.parse_identifier()?))
} else {
let name = self.parse_object_name()?;
if self.parse_keyword(Keyword::AUTHORIZATION) {
Ok(SchemaName::NamedAuthorization(
name,
self.parse_identifier()?,
))
} else {
Ok(SchemaName::Simple(name))
}
}
}
pub fn parse_create_database(&mut self) -> Result<Statement, ParserError> {
let ine = self.parse_keywords(&[Keyword::IF, Keyword::NOT, Keyword::EXISTS]);
let db_name = self.parse_object_name()?;
@ -5345,4 +5364,37 @@ mod tests {
});
}
}
#[test]
fn test_parse_schema_name() {
// The expected name should be identical as the input name, that's why I don't receive both
macro_rules! test_parse_schema_name {
($input:expr, $expected_name:expr $(,)?) => {{
all_dialects().run_parser_method(&*$input, |parser| {
let schema_name = parser.parse_schema_name().unwrap();
// Validate that the structure is the same as expected
assert_eq!(schema_name, $expected_name);
// Validate that the input and the expected structure serialization are the same
assert_eq!(schema_name.to_string(), $input.to_string());
});
}};
}
let dummy_name = ObjectName(vec![Ident::new("dummy_name")]);
let dummy_authorization = Ident::new("dummy_authorization");
test_parse_schema_name!(
format!("{dummy_name}"),
SchemaName::Simple(dummy_name.clone())
);
test_parse_schema_name!(
format!("AUTHORIZATION {dummy_authorization}"),
SchemaName::UnnamedAuthorization(dummy_authorization.clone()),
);
test_parse_schema_name!(
format!("{dummy_name} AUTHORIZATION {dummy_authorization}"),
SchemaName::NamedAuthorization(dummy_name.clone(), dummy_authorization.clone()),
);
}
}

View file

@ -2133,6 +2133,30 @@ fn parse_create_schema() {
}
}
#[test]
fn parse_create_schema_with_authorization() {
let sql = "CREATE SCHEMA AUTHORIZATION Y";
match verified_stmt(sql) {
Statement::CreateSchema { schema_name, .. } => {
assert_eq!(schema_name.to_string(), "AUTHORIZATION Y".to_owned())
}
_ => unreachable!(),
}
}
#[test]
fn parse_create_schema_with_name_and_authorization() {
let sql = "CREATE SCHEMA X AUTHORIZATION Y";
match verified_stmt(sql) {
Statement::CreateSchema { schema_name, .. } => {
assert_eq!(schema_name.to_string(), "X AUTHORIZATION Y".to_owned())
}
_ => unreachable!(),
}
}
#[test]
fn parse_drop_schema() {
let sql = "DROP SCHEMA X";