Skip to content

Commit 1ced0f6

Browse files
authored
645 New schema name structure (#646)
1 parent 95464ec commit 1ced0f6

File tree

3 files changed

+109
-2
lines changed

3 files changed

+109
-2
lines changed

src/ast/mod.rs

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1300,7 +1300,8 @@ pub enum Statement {
13001300
Rollback { chain: bool },
13011301
/// CREATE SCHEMA
13021302
CreateSchema {
1303-
schema_name: ObjectName,
1303+
/// `<schema name> | AUTHORIZATION <schema authorization identifier> | <schema name> AUTHORIZATION <schema authorization identifier>`
1304+
schema_name: SchemaName,
13041305
if_not_exists: bool,
13051306
},
13061307
/// CREATE DATABASE
@@ -3275,6 +3276,36 @@ impl fmt::Display for CreateFunctionUsing {
32753276
}
32763277
}
32773278

3279+
/// Schema possible naming variants ([1]).
3280+
///
3281+
/// [1]: https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#schema-definition
3282+
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3283+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3284+
pub enum SchemaName {
3285+
/// Only schema name specified: `<schema name>`.
3286+
Simple(ObjectName),
3287+
/// Only authorization identifier specified: `AUTHORIZATION <schema authorization identifier>`.
3288+
UnnamedAuthorization(Ident),
3289+
/// Both schema name and authorization identifier specified: `<schema name> AUTHORIZATION <schema authorization identifier>`.
3290+
NamedAuthorization(ObjectName, Ident),
3291+
}
3292+
3293+
impl fmt::Display for SchemaName {
3294+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3295+
match self {
3296+
SchemaName::Simple(name) => {
3297+
write!(f, "{name}")
3298+
}
3299+
SchemaName::UnnamedAuthorization(authorization) => {
3300+
write!(f, "AUTHORIZATION {authorization}")
3301+
}
3302+
SchemaName::NamedAuthorization(name, authorization) => {
3303+
write!(f, "{name} AUTHORIZATION {authorization}")
3304+
}
3305+
}
3306+
}
3307+
}
3308+
32783309
#[cfg(test)]
32793310
mod tests {
32803311
use super::*;

src/parser.rs

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1896,13 +1896,32 @@ impl<'a> Parser<'a> {
18961896

18971897
pub fn parse_create_schema(&mut self) -> Result<Statement, ParserError> {
18981898
let if_not_exists = self.parse_keywords(&[Keyword::IF, Keyword::NOT, Keyword::EXISTS]);
1899-
let schema_name = self.parse_object_name()?;
1899+
1900+
let schema_name = self.parse_schema_name()?;
1901+
19001902
Ok(Statement::CreateSchema {
19011903
schema_name,
19021904
if_not_exists,
19031905
})
19041906
}
19051907

1908+
fn parse_schema_name(&mut self) -> Result<SchemaName, ParserError> {
1909+
if self.parse_keyword(Keyword::AUTHORIZATION) {
1910+
Ok(SchemaName::UnnamedAuthorization(self.parse_identifier()?))
1911+
} else {
1912+
let name = self.parse_object_name()?;
1913+
1914+
if self.parse_keyword(Keyword::AUTHORIZATION) {
1915+
Ok(SchemaName::NamedAuthorization(
1916+
name,
1917+
self.parse_identifier()?,
1918+
))
1919+
} else {
1920+
Ok(SchemaName::Simple(name))
1921+
}
1922+
}
1923+
}
1924+
19061925
pub fn parse_create_database(&mut self) -> Result<Statement, ParserError> {
19071926
let ine = self.parse_keywords(&[Keyword::IF, Keyword::NOT, Keyword::EXISTS]);
19081927
let db_name = self.parse_object_name()?;
@@ -5345,4 +5364,37 @@ mod tests {
53455364
});
53465365
}
53475366
}
5367+
5368+
#[test]
5369+
fn test_parse_schema_name() {
5370+
// The expected name should be identical as the input name, that's why I don't receive both
5371+
macro_rules! test_parse_schema_name {
5372+
($input:expr, $expected_name:expr $(,)?) => {{
5373+
all_dialects().run_parser_method(&*$input, |parser| {
5374+
let schema_name = parser.parse_schema_name().unwrap();
5375+
// Validate that the structure is the same as expected
5376+
assert_eq!(schema_name, $expected_name);
5377+
// Validate that the input and the expected structure serialization are the same
5378+
assert_eq!(schema_name.to_string(), $input.to_string());
5379+
});
5380+
}};
5381+
}
5382+
5383+
let dummy_name = ObjectName(vec![Ident::new("dummy_name")]);
5384+
let dummy_authorization = Ident::new("dummy_authorization");
5385+
5386+
test_parse_schema_name!(
5387+
format!("{dummy_name}"),
5388+
SchemaName::Simple(dummy_name.clone())
5389+
);
5390+
5391+
test_parse_schema_name!(
5392+
format!("AUTHORIZATION {dummy_authorization}"),
5393+
SchemaName::UnnamedAuthorization(dummy_authorization.clone()),
5394+
);
5395+
test_parse_schema_name!(
5396+
format!("{dummy_name} AUTHORIZATION {dummy_authorization}"),
5397+
SchemaName::NamedAuthorization(dummy_name.clone(), dummy_authorization.clone()),
5398+
);
5399+
}
53485400
}

tests/sqlparser_common.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2133,6 +2133,30 @@ fn parse_create_schema() {
21332133
}
21342134
}
21352135

2136+
#[test]
2137+
fn parse_create_schema_with_authorization() {
2138+
let sql = "CREATE SCHEMA AUTHORIZATION Y";
2139+
2140+
match verified_stmt(sql) {
2141+
Statement::CreateSchema { schema_name, .. } => {
2142+
assert_eq!(schema_name.to_string(), "AUTHORIZATION Y".to_owned())
2143+
}
2144+
_ => unreachable!(),
2145+
}
2146+
}
2147+
2148+
#[test]
2149+
fn parse_create_schema_with_name_and_authorization() {
2150+
let sql = "CREATE SCHEMA X AUTHORIZATION Y";
2151+
2152+
match verified_stmt(sql) {
2153+
Statement::CreateSchema { schema_name, .. } => {
2154+
assert_eq!(schema_name.to_string(), "X AUTHORIZATION Y".to_owned())
2155+
}
2156+
_ => unreachable!(),
2157+
}
2158+
}
2159+
21362160
#[test]
21372161
fn parse_drop_schema() {
21382162
let sql = "DROP SCHEMA X";

0 commit comments

Comments
 (0)