Skip to content

Commit 7727c64

Browse files
committed
Adds support for pg CREATE EXTENSION
1 parent c62ecb1 commit 7727c64

File tree

4 files changed

+96
-0
lines changed

4 files changed

+96
-0
lines changed

src/ast/mod.rs

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1763,6 +1763,21 @@ pub enum Statement {
17631763
query: Box<Query>,
17641764
},
17651765
/// ```sql
1766+
/// CREATE EXTENSION [ IF NOT EXISTS ] extension_name
1767+
/// [ WITH ] [ SCHEMA schema_name ]
1768+
/// [ VERSION version ]
1769+
/// [ CASCADE ]
1770+
/// ```
1771+
///
1772+
/// Note: this is a PostgreSQL-specific statement,
1773+
CreateExtension {
1774+
name: Ident,
1775+
if_not_exists: bool,
1776+
cascade: bool,
1777+
schema: Option<Ident>,
1778+
version: Option<Ident>,
1779+
},
1780+
/// ```sql
17661781
/// FETCH
17671782
/// ```
17681783
/// Retrieve rows from a query using a cursor
@@ -2960,6 +2975,34 @@ impl fmt::Display for Statement {
29602975
}
29612976
Ok(())
29622977
}
2978+
Statement::CreateExtension {
2979+
name,
2980+
if_not_exists,
2981+
cascade,
2982+
schema,
2983+
version,
2984+
} => {
2985+
write!(
2986+
f,
2987+
"CREATE EXTENSION {if_not_exists}{name}",
2988+
if_not_exists = if *if_not_exists { "IF NOT EXISTS " } else { "" }
2989+
)?;
2990+
if *cascade || schema.is_some() || version.is_some() {
2991+
write!(f, " WITH")?;
2992+
2993+
if let Some(name) = schema {
2994+
write!(f, " SCHEMA {name}")?;
2995+
}
2996+
if let Some(version) = version {
2997+
write!(f, " VERSION {version}")?;
2998+
}
2999+
if *cascade {
3000+
write!(f, " CASCADE")?;
3001+
}
3002+
}
3003+
3004+
Ok(())
3005+
}
29633006
Statement::CreateRole {
29643007
names,
29653008
if_not_exists,

src/keywords.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,7 @@ define_keywords!(
266266
EXPLAIN,
267267
EXPLICIT,
268268
EXTENDED,
269+
EXTENSION,
269270
EXTERNAL,
270271
EXTRACT,
271272
FAIL,
@@ -688,6 +689,7 @@ define_keywords!(
688689
VAR_POP,
689690
VAR_SAMP,
690691
VERBOSE,
692+
VERSION,
691693
VERSIONING,
692694
VIEW,
693695
VIRTUAL,

src/parser/mod.rs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2882,6 +2882,8 @@ impl<'a> Parser<'a> {
28822882
"[EXTERNAL] TABLE or [MATERIALIZED] VIEW or FUNCTION after CREATE OR REPLACE",
28832883
self.peek_token(),
28842884
)
2885+
} else if self.parse_keyword(Keyword::EXTENSION) {
2886+
self.parse_create_extension()
28852887
} else if self.parse_keyword(Keyword::INDEX) {
28862888
self.parse_create_index(false)
28872889
} else if self.parse_keywords(&[Keyword::UNIQUE, Keyword::INDEX]) {
@@ -3900,6 +3902,39 @@ impl<'a> Parser<'a> {
39003902
})
39013903
}
39023904

3905+
pub fn parse_create_extension(&mut self) -> Result<Statement, ParserError> {
3906+
let if_not_exists = self.parse_keywords(&[Keyword::IF, Keyword::NOT, Keyword::EXISTS]);
3907+
let name = self.parse_identifier()?;
3908+
3909+
let (schema, version, cascade) = if self.parse_keyword(Keyword::WITH) {
3910+
let schema = if self.parse_keyword(Keyword::SCHEMA) {
3911+
Some(self.parse_identifier()?)
3912+
} else {
3913+
None
3914+
};
3915+
3916+
let version = if self.parse_keyword(Keyword::VERSION) {
3917+
Some(self.parse_identifier()?)
3918+
} else {
3919+
None
3920+
};
3921+
3922+
let cascade = self.parse_keyword(Keyword::CASCADE);
3923+
3924+
(schema, version, cascade)
3925+
} else {
3926+
(None, None, false)
3927+
};
3928+
3929+
Ok(Statement::CreateExtension {
3930+
name,
3931+
if_not_exists,
3932+
schema,
3933+
version,
3934+
cascade,
3935+
})
3936+
}
3937+
39033938
//TODO: Implement parsing for Skewed and Clustered
39043939
pub fn parse_hive_distribution(&mut self) -> Result<HiveDistributionStyle, ParserError> {
39053940
if self.parse_keywords(&[Keyword::PARTITIONED, Keyword::BY]) {

tests/sqlparser_postgres.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -563,6 +563,22 @@ fn parse_alter_table_constraints_rename() {
563563
}
564564
}
565565

566+
#[test]
567+
fn parse_create_extension() {
568+
pg_and_generic().verified_stmt("CREATE EXTENSION extension_name");
569+
pg_and_generic().verified_stmt("CREATE EXTENSION extension_name WITH SCHEMA schema_name");
570+
pg_and_generic().verified_stmt("CREATE EXTENSION extension_name WITH VERSION version");
571+
pg_and_generic().verified_stmt("CREATE EXTENSION extension_name WITH CASCADE");
572+
pg_and_generic().verified_stmt(
573+
"CREATE EXTENSION extension_name WITH SCHEMA schema_name VERSION version CASCADE",
574+
);
575+
pg_and_generic()
576+
.verified_stmt("CREATE EXTENSION extension_name WITH SCHEMA schema_name CASCADE");
577+
pg_and_generic().verified_stmt("CREATE EXTENSION extension_name WITH VERSION version CASCADE");
578+
pg_and_generic()
579+
.verified_stmt("CREATE EXTENSION extension_name WITH SCHEMA schema_name VERSION version");
580+
}
581+
566582
#[test]
567583
fn parse_alter_table_alter_column() {
568584
pg().one_statement_parses_to(

0 commit comments

Comments
 (0)