Skip to content

Commit 28de160

Browse files
feat(ast): model PostgreSQL collation DDL
Add AST support for PostgreSQL collation statements and related object kinds.\n\n- introduce CreateCollation and AlterCollation structures\n- add CreateCollationDefinition and AlterCollationOperation enums\n- extend Statement with CreateCollation/AlterCollation variants\n- add ObjectType::Collation and CommentObject::Collation\n- wire display/from conversions and span matching hooks
1 parent 6fa3614 commit 28de160

File tree

3 files changed

+172
-0
lines changed

3 files changed

+172
-0
lines changed

src/ast/ddl.rs

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4503,6 +4503,142 @@ impl Spanned for DropExtension {
45034503
}
45044504
}
45054505

4506+
/// CREATE COLLATION statement.
4507+
/// Note: this is a PostgreSQL-specific statement.
4508+
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
4509+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
4510+
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
4511+
pub struct CreateCollation {
4512+
/// Whether `IF NOT EXISTS` was specified.
4513+
pub if_not_exists: bool,
4514+
/// Name of the collation being created.
4515+
pub name: ObjectName,
4516+
/// Source definition for the collation.
4517+
pub definition: CreateCollationDefinition,
4518+
}
4519+
4520+
/// Definition forms supported by `CREATE COLLATION`.
4521+
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
4522+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
4523+
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
4524+
pub enum CreateCollationDefinition {
4525+
/// Create from an existing collation.
4526+
///
4527+
/// ```sql
4528+
/// CREATE COLLATION name FROM existing_collation
4529+
/// ```
4530+
From(ObjectName),
4531+
/// Create with an option list.
4532+
///
4533+
/// ```sql
4534+
/// CREATE COLLATION name (key = value, ...)
4535+
/// ```
4536+
Options(Vec<SqlOption>),
4537+
}
4538+
4539+
impl fmt::Display for CreateCollation {
4540+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
4541+
write!(
4542+
f,
4543+
"CREATE COLLATION {if_not_exists}{name}",
4544+
if_not_exists = if self.if_not_exists {
4545+
"IF NOT EXISTS "
4546+
} else {
4547+
""
4548+
},
4549+
name = self.name
4550+
)?;
4551+
match &self.definition {
4552+
CreateCollationDefinition::From(existing_collation) => {
4553+
write!(f, " FROM {existing_collation}")
4554+
}
4555+
CreateCollationDefinition::Options(options) => {
4556+
write!(f, " ({})", display_comma_separated(options))
4557+
}
4558+
}
4559+
}
4560+
}
4561+
4562+
impl Spanned for CreateCollation {
4563+
fn span(&self) -> Span {
4564+
Span::empty()
4565+
}
4566+
}
4567+
4568+
/// ALTER COLLATION statement.
4569+
/// Note: this is a PostgreSQL-specific statement.
4570+
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
4571+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
4572+
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
4573+
pub struct AlterCollation {
4574+
/// Name of the collation being altered.
4575+
pub name: ObjectName,
4576+
/// The operation to perform on the collation.
4577+
pub operation: AlterCollationOperation,
4578+
}
4579+
4580+
/// Operations supported by `ALTER COLLATION`.
4581+
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
4582+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
4583+
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
4584+
pub enum AlterCollationOperation {
4585+
/// Rename the collation.
4586+
///
4587+
/// ```sql
4588+
/// ALTER COLLATION name RENAME TO new_name
4589+
/// ```
4590+
RenameTo {
4591+
/// New collation name.
4592+
new_name: Ident,
4593+
},
4594+
/// Change the collation owner.
4595+
///
4596+
/// ```sql
4597+
/// ALTER COLLATION name OWNER TO role_name
4598+
/// ```
4599+
OwnerTo(Owner),
4600+
/// Move the collation to another schema.
4601+
///
4602+
/// ```sql
4603+
/// ALTER COLLATION name SET SCHEMA new_schema
4604+
/// ```
4605+
SetSchema {
4606+
/// Target schema name.
4607+
schema_name: ObjectName,
4608+
},
4609+
/// Refresh collation version metadata.
4610+
///
4611+
/// ```sql
4612+
/// ALTER COLLATION name REFRESH VERSION
4613+
/// ```
4614+
RefreshVersion,
4615+
}
4616+
4617+
impl fmt::Display for AlterCollationOperation {
4618+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
4619+
match self {
4620+
AlterCollationOperation::RenameTo { new_name } => write!(f, "RENAME TO {new_name}"),
4621+
AlterCollationOperation::OwnerTo(owner) => write!(f, "OWNER TO {owner}"),
4622+
AlterCollationOperation::SetSchema { schema_name } => {
4623+
write!(f, "SET SCHEMA {schema_name}")
4624+
}
4625+
AlterCollationOperation::RefreshVersion => write!(f, "REFRESH VERSION"),
4626+
}
4627+
}
4628+
}
4629+
4630+
impl fmt::Display for AlterCollation {
4631+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
4632+
write!(f, "ALTER COLLATION {} {}", self.name, self.operation)
4633+
}
4634+
}
4635+
4636+
impl Spanned for AlterCollation {
4637+
fn span(&self) -> Span {
4638+
Span::empty()
4639+
}
4640+
}
4641+
45064642
/// Table type for ALTER TABLE statements.
45074643
/// Used to distinguish between regular tables, Iceberg tables, and Dynamic tables.
45084644
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]

src/ast/mod.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ pub use self::ddl::{
8282
Truncate, UserDefinedTypeCompositeAttributeDef, UserDefinedTypeInternalLength,
8383
UserDefinedTypeRangeOption, UserDefinedTypeRepresentation, UserDefinedTypeSqlDefinitionOption,
8484
UserDefinedTypeStorage, ViewColumnDef,
85+
AlterCollation, AlterCollationOperation, CreateCollation, CreateCollationDefinition,
8586
};
8687
pub use self::dml::{
8788
Delete, Insert, Merge, MergeAction, MergeClause, MergeClauseKind, MergeInsertExpr,
@@ -2450,6 +2451,8 @@ impl fmt::Display for ShowCreateObject {
24502451
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
24512452
/// Objects that can be targeted by a `COMMENT` statement.
24522453
pub enum CommentObject {
2454+
/// A collation.
2455+
Collation,
24532456
/// A table column.
24542457
Column,
24552458
/// A database.
@@ -2485,6 +2488,7 @@ pub enum CommentObject {
24852488
impl fmt::Display for CommentObject {
24862489
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
24872490
match self {
2491+
CommentObject::Collation => f.write_str("COLLATION"),
24882492
CommentObject::Column => f.write_str("COLUMN"),
24892493
CommentObject::Database => f.write_str("DATABASE"),
24902494
CommentObject::Domain => f.write_str("DOMAIN"),
@@ -3764,6 +3768,11 @@ pub enum Statement {
37643768
/// ```
37653769
AlterType(AlterType),
37663770
/// ```sql
3771+
/// ALTER COLLATION
3772+
/// ```
3773+
/// See [PostgreSQL](https://www.postgresql.org/docs/current/sql-altercollation.html)
3774+
AlterCollation(AlterCollation),
3775+
/// ```sql
37673776
/// ALTER OPERATOR
37683777
/// ```
37693778
/// See [PostgreSQL](https://www.postgresql.org/docs/current/sql-alteroperator.html)
@@ -3960,6 +3969,12 @@ pub enum Statement {
39603969
/// Note: this is a PostgreSQL-specific statement,
39613970
CreateExtension(CreateExtension),
39623971
/// ```sql
3972+
/// CREATE COLLATION
3973+
/// ```
3974+
/// Note: this is a PostgreSQL-specific statement.
3975+
/// <https://www.postgresql.org/docs/current/sql-createcollation.html>
3976+
CreateCollation(CreateCollation),
3977+
/// ```sql
39633978
/// DROP EXTENSION [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ]
39643979
/// ```
39653980
/// Note: this is a PostgreSQL-specific statement.
@@ -5430,6 +5445,7 @@ impl fmt::Display for Statement {
54305445
}
54315446
Statement::CreateIndex(create_index) => create_index.fmt(f),
54325447
Statement::CreateExtension(create_extension) => write!(f, "{create_extension}"),
5448+
Statement::CreateCollation(create_collation) => write!(f, "{create_collation}"),
54335449
Statement::DropExtension(drop_extension) => write!(f, "{drop_extension}"),
54345450
Statement::DropOperator(drop_operator) => write!(f, "{drop_operator}"),
54355451
Statement::DropOperatorFamily(drop_operator_family) => {
@@ -5507,6 +5523,7 @@ impl fmt::Display for Statement {
55075523
Statement::AlterType(AlterType { name, operation }) => {
55085524
write!(f, "ALTER TYPE {name} {operation}")
55095525
}
5526+
Statement::AlterCollation(alter_collation) => write!(f, "{alter_collation}"),
55105527
Statement::AlterOperator(alter_operator) => write!(f, "{alter_operator}"),
55115528
Statement::AlterOperatorFamily(alter_operator_family) => {
55125529
write!(f, "{alter_operator_family}")
@@ -8380,6 +8397,8 @@ impl fmt::Display for HavingBoundKind {
83808397
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
83818398
/// Types of database objects referenced by DDL statements.
83828399
pub enum ObjectType {
8400+
/// A collation.
8401+
Collation,
83838402
/// A table.
83848403
Table,
83858404
/// A view.
@@ -8409,6 +8428,7 @@ pub enum ObjectType {
84098428
impl fmt::Display for ObjectType {
84108429
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
84118430
f.write_str(match self {
8431+
ObjectType::Collation => "COLLATION",
84128432
ObjectType::Table => "TABLE",
84138433
ObjectType::View => "VIEW",
84148434
ObjectType::MaterializedView => "MATERIALIZED VIEW",
@@ -12011,6 +12031,12 @@ impl From<CreateExtension> for Statement {
1201112031
}
1201212032
}
1201312033

12034+
impl From<CreateCollation> for Statement {
12035+
fn from(c: CreateCollation) -> Self {
12036+
Self::CreateCollation(c)
12037+
}
12038+
}
12039+
1201412040
impl From<DropExtension> for Statement {
1201512041
fn from(de: DropExtension) -> Self {
1201612042
Self::DropExtension(de)
@@ -12125,6 +12151,12 @@ impl From<AlterType> for Statement {
1212512151
}
1212612152
}
1212712153

12154+
impl From<AlterCollation> for Statement {
12155+
fn from(a: AlterCollation) -> Self {
12156+
Self::AlterCollation(a)
12157+
}
12158+
}
12159+
1212812160
impl From<AlterOperator> for Statement {
1212912161
fn from(a: AlterOperator) -> Self {
1213012162
Self::AlterOperator(a)

src/ast/spans.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,8 @@ impl Spanned for Values {
264264
/// - [Statement::DropSecret]
265265
/// - [Statement::Declare]
266266
/// - [Statement::CreateExtension]
267+
/// - [Statement::CreateCollation]
268+
/// - [Statement::AlterCollation]
267269
/// - [Statement::Fetch]
268270
/// - [Statement::Flush]
269271
/// - [Statement::Discard]
@@ -377,6 +379,7 @@ impl Spanned for Statement {
377379
Statement::CreateIndex(create_index) => create_index.span(),
378380
Statement::CreateRole(create_role) => create_role.span(),
379381
Statement::CreateExtension(create_extension) => create_extension.span(),
382+
Statement::CreateCollation(create_collation) => create_collation.span(),
380383
Statement::DropExtension(drop_extension) => drop_extension.span(),
381384
Statement::DropOperator(drop_operator) => drop_operator.span(),
382385
Statement::DropOperatorFamily(drop_operator_family) => drop_operator_family.span(),
@@ -405,6 +408,7 @@ impl Spanned for Statement {
405408
// These statements need to be implemented
406409
Statement::AlterFunction { .. } => Span::empty(),
407410
Statement::AlterType { .. } => Span::empty(),
411+
Statement::AlterCollation { .. } => Span::empty(),
408412
Statement::AlterOperator { .. } => Span::empty(),
409413
Statement::AlterOperatorFamily { .. } => Span::empty(),
410414
Statement::AlterOperatorClass { .. } => Span::empty(),

0 commit comments

Comments
 (0)