Skip to content

Commit

Permalink
645 New schema name structure (#646)
Browse files Browse the repository at this point in the history
  • Loading branch information
AugustoFKL committed Oct 3, 2022
1 parent 95464ec commit 1ced0f6
Show file tree
Hide file tree
Showing 3 changed files with 109 additions and 2 deletions.
33 changes: 32 additions & 1 deletion src/ast/mod.rs
Expand Up @@ -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
Expand Down Expand Up @@ -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::*;
Expand Down
54 changes: 53 additions & 1 deletion src/parser.rs
Expand Up @@ -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()?;
Expand Down Expand Up @@ -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()),
);
}
}
24 changes: 24 additions & 0 deletions tests/sqlparser_common.rs
Expand Up @@ -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";
Expand Down

0 comments on commit 1ced0f6

Please sign in to comment.