@@ -898,6 +898,9 @@ impl<'a> Parser<'a> {
898898 let token = self.next_token();
899899
900900 let (object_type, object_name) = match token.token {
901+ Token::Word(w) if w.keyword == Keyword::COLLATION => {
902+ (CommentObject::Collation, self.parse_object_name(false)?)
903+ }
901904 Token::Word(w) if w.keyword == Keyword::COLUMN => {
902905 (CommentObject::Column, self.parse_object_name(false)?)
903906 }
@@ -5151,6 +5154,8 @@ impl<'a> Parser<'a> {
51515154 self.parse_create_role().map(Into::into)
51525155 } else if self.parse_keyword(Keyword::SEQUENCE) {
51535156 self.parse_create_sequence(temporary)
5157+ } else if self.parse_keyword(Keyword::COLLATION) {
5158+ self.parse_create_collation().map(Into::into)
51545159 } else if self.parse_keyword(Keyword::TYPE) {
51555160 self.parse_create_type()
51565161 } else if self.parse_keyword(Keyword::PROCEDURE) {
@@ -7200,6 +7205,8 @@ impl<'a> Parser<'a> {
72007205
72017206 let object_type = if self.parse_keyword(Keyword::TABLE) {
72027207 ObjectType::Table
7208+ } else if self.parse_keyword(Keyword::COLLATION) {
7209+ ObjectType::Collation
72037210 } else if self.parse_keyword(Keyword::VIEW) {
72047211 ObjectType::View
72057212 } else if self.parse_keywords(&[Keyword::MATERIALIZED, Keyword::VIEW]) {
@@ -7249,7 +7256,7 @@ impl<'a> Parser<'a> {
72497256 };
72507257 } else {
72517258 return self.expected_ref(
7252- "CONNECTOR, DATABASE, EXTENSION, FUNCTION, INDEX, OPERATOR, POLICY, PROCEDURE, ROLE, SCHEMA, SECRET, SEQUENCE, STAGE, TABLE, TRIGGER, TYPE, VIEW, MATERIALIZED VIEW or USER after DROP",
7259+ "COLLATION, CONNECTOR, DATABASE, EXTENSION, FUNCTION, INDEX, OPERATOR, POLICY, PROCEDURE, ROLE, SCHEMA, SECRET, SEQUENCE, STAGE, TABLE, TRIGGER, TYPE, VIEW, MATERIALIZED VIEW or USER after DROP",
72537260 self.peek_token_ref(),
72547261 );
72557262 };
@@ -7990,6 +7997,31 @@ impl<'a> Parser<'a> {
79907997 })
79917998 }
79927999
8000+ /// Parse a PostgreSQL-specific [Statement::CreateCollation] statement.
8001+ pub fn parse_create_collation(&mut self) -> Result<CreateCollation, ParserError> {
8002+ let if_not_exists = self.parse_keywords(&[Keyword::IF, Keyword::NOT, Keyword::EXISTS]);
8003+ let name = self.parse_object_name(false)?;
8004+
8005+ let definition = if self.parse_keyword(Keyword::FROM) {
8006+ CreateCollationDefinition::From(self.parse_object_name(false)?)
8007+ } else if self.consume_token(&Token::LParen) {
8008+ let options = self.parse_comma_separated(Parser::parse_sql_option)?;
8009+ self.expect_token(&Token::RParen)?;
8010+ CreateCollationDefinition::Options(options)
8011+ } else {
8012+ return self.expected_ref(
8013+ "FROM or parenthesized option list after CREATE COLLATION name",
8014+ self.peek_token_ref(),
8015+ );
8016+ };
8017+
8018+ Ok(CreateCollation {
8019+ if_not_exists,
8020+ name,
8021+ definition,
8022+ })
8023+ }
8024+
79938025 /// Parse a PostgreSQL-specific [Statement::DropExtension] statement.
79948026 pub fn parse_drop_extension(&mut self) -> Result<Statement, ParserError> {
79958027 let if_exists = self.parse_keywords(&[Keyword::IF, Keyword::EXISTS]);
@@ -10431,6 +10463,7 @@ impl<'a> Parser<'a> {
1043110463 let object_type = self.expect_one_of_keywords(&[
1043210464 Keyword::VIEW,
1043310465 Keyword::TYPE,
10466+ Keyword::COLLATION,
1043410467 Keyword::TABLE,
1043510468 Keyword::INDEX,
1043610469 Keyword::ROLE,
@@ -10449,6 +10482,7 @@ impl<'a> Parser<'a> {
1044910482 }
1045010483 Keyword::VIEW => self.parse_alter_view(),
1045110484 Keyword::TYPE => self.parse_alter_type(),
10485+ Keyword::COLLATION => self.parse_alter_collation().map(Into::into),
1045210486 Keyword::TABLE => self.parse_alter_table(false),
1045310487 Keyword::ICEBERG => {
1045410488 self.expect_keyword(Keyword::TABLE)?;
@@ -10487,7 +10521,7 @@ impl<'a> Parser<'a> {
1048710521 Keyword::USER => self.parse_alter_user().map(Into::into),
1048810522 // unreachable because expect_one_of_keywords used above
1048910523 unexpected_keyword => Err(ParserError::ParserError(
10490- format!("Internal parser error: expected any of {{VIEW, TYPE, TABLE, INDEX, ROLE, POLICY, CONNECTOR, ICEBERG, SCHEMA, USER, OPERATOR}}, got {unexpected_keyword:?}"),
10524+ format!("Internal parser error: expected any of {{VIEW, TYPE, COLLATION, TABLE, INDEX, ROLE, POLICY, CONNECTOR, ICEBERG, SCHEMA, USER, OPERATOR}}, got {unexpected_keyword:?}"),
1049110525 )),
1049210526 }
1049310527 }
@@ -10603,6 +10637,33 @@ impl<'a> Parser<'a> {
1060310637 }
1060410638 }
1060510639
10640+ /// Parse a [Statement::AlterCollation].
10641+ ///
10642+ /// [PostgreSQL Documentation](https://www.postgresql.org/docs/current/sql-altercollation.html)
10643+ pub fn parse_alter_collation(&mut self) -> Result<AlterCollation, ParserError> {
10644+ let name = self.parse_object_name(false)?;
10645+ let operation = if self.parse_keywords(&[Keyword::RENAME, Keyword::TO]) {
10646+ AlterCollationOperation::RenameTo {
10647+ new_name: self.parse_identifier()?,
10648+ }
10649+ } else if self.parse_keywords(&[Keyword::OWNER, Keyword::TO]) {
10650+ AlterCollationOperation::OwnerTo(self.parse_owner()?)
10651+ } else if self.parse_keywords(&[Keyword::SET, Keyword::SCHEMA]) {
10652+ AlterCollationOperation::SetSchema {
10653+ schema_name: self.parse_object_name(false)?,
10654+ }
10655+ } else if self.parse_keywords(&[Keyword::REFRESH, Keyword::VERSION]) {
10656+ AlterCollationOperation::RefreshVersion
10657+ } else {
10658+ return self.expected_ref(
10659+ "RENAME TO, OWNER TO, SET SCHEMA, or REFRESH VERSION after ALTER COLLATION",
10660+ self.peek_token_ref(),
10661+ );
10662+ };
10663+
10664+ Ok(AlterCollation { name, operation })
10665+ }
10666+
1060610667 /// Parse a [Statement::AlterOperator]
1060710668 ///
1060810669 /// [PostgreSQL Documentation](https://www.postgresql.org/docs/current/sql-alteroperator.html)
0 commit comments