Skip to content

Commit 8721780

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 bd7f70e commit 8721780

File tree

3 files changed

+184
-12
lines changed

3 files changed

+184
-12
lines changed

src/ast/ddl.rs

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4402,6 +4402,142 @@ impl Spanned for DropExtension {
44024402
}
44034403
}
44044404

4405+
/// CREATE COLLATION statement.
4406+
/// Note: this is a PostgreSQL-specific statement.
4407+
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
4408+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
4409+
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
4410+
pub struct CreateCollation {
4411+
/// Whether `IF NOT EXISTS` was specified.
4412+
pub if_not_exists: bool,
4413+
/// Name of the collation being created.
4414+
pub name: ObjectName,
4415+
/// Source definition for the collation.
4416+
pub definition: CreateCollationDefinition,
4417+
}
4418+
4419+
/// Definition forms supported by `CREATE COLLATION`.
4420+
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
4421+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
4422+
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
4423+
pub enum CreateCollationDefinition {
4424+
/// Create from an existing collation.
4425+
///
4426+
/// ```sql
4427+
/// CREATE COLLATION name FROM existing_collation
4428+
/// ```
4429+
From(ObjectName),
4430+
/// Create with an option list.
4431+
///
4432+
/// ```sql
4433+
/// CREATE COLLATION name (key = value, ...)
4434+
/// ```
4435+
Options(Vec<SqlOption>),
4436+
}
4437+
4438+
impl fmt::Display for CreateCollation {
4439+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
4440+
write!(
4441+
f,
4442+
"CREATE COLLATION {if_not_exists}{name}",
4443+
if_not_exists = if self.if_not_exists {
4444+
"IF NOT EXISTS "
4445+
} else {
4446+
""
4447+
},
4448+
name = self.name
4449+
)?;
4450+
match &self.definition {
4451+
CreateCollationDefinition::From(existing_collation) => {
4452+
write!(f, " FROM {existing_collation}")
4453+
}
4454+
CreateCollationDefinition::Options(options) => {
4455+
write!(f, " ({})", display_comma_separated(options))
4456+
}
4457+
}
4458+
}
4459+
}
4460+
4461+
impl Spanned for CreateCollation {
4462+
fn span(&self) -> Span {
4463+
Span::empty()
4464+
}
4465+
}
4466+
4467+
/// ALTER COLLATION statement.
4468+
/// Note: this is a PostgreSQL-specific statement.
4469+
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
4470+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
4471+
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
4472+
pub struct AlterCollation {
4473+
/// Name of the collation being altered.
4474+
pub name: ObjectName,
4475+
/// The operation to perform on the collation.
4476+
pub operation: AlterCollationOperation,
4477+
}
4478+
4479+
/// Operations supported by `ALTER COLLATION`.
4480+
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
4481+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
4482+
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
4483+
pub enum AlterCollationOperation {
4484+
/// Rename the collation.
4485+
///
4486+
/// ```sql
4487+
/// ALTER COLLATION name RENAME TO new_name
4488+
/// ```
4489+
RenameTo {
4490+
/// New collation name.
4491+
new_name: Ident,
4492+
},
4493+
/// Change the collation owner.
4494+
///
4495+
/// ```sql
4496+
/// ALTER COLLATION name OWNER TO role_name
4497+
/// ```
4498+
OwnerTo(Owner),
4499+
/// Move the collation to another schema.
4500+
///
4501+
/// ```sql
4502+
/// ALTER COLLATION name SET SCHEMA new_schema
4503+
/// ```
4504+
SetSchema {
4505+
/// Target schema name.
4506+
schema_name: ObjectName,
4507+
},
4508+
/// Refresh collation version metadata.
4509+
///
4510+
/// ```sql
4511+
/// ALTER COLLATION name REFRESH VERSION
4512+
/// ```
4513+
RefreshVersion,
4514+
}
4515+
4516+
impl fmt::Display for AlterCollationOperation {
4517+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
4518+
match self {
4519+
AlterCollationOperation::RenameTo { new_name } => write!(f, "RENAME TO {new_name}"),
4520+
AlterCollationOperation::OwnerTo(owner) => write!(f, "OWNER TO {owner}"),
4521+
AlterCollationOperation::SetSchema { schema_name } => {
4522+
write!(f, "SET SCHEMA {schema_name}")
4523+
}
4524+
AlterCollationOperation::RefreshVersion => write!(f, "REFRESH VERSION"),
4525+
}
4526+
}
4527+
}
4528+
4529+
impl fmt::Display for AlterCollation {
4530+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
4531+
write!(f, "ALTER COLLATION {} {}", self.name, self.operation)
4532+
}
4533+
}
4534+
4535+
impl Spanned for AlterCollation {
4536+
fn span(&self) -> Span {
4537+
Span::empty()
4538+
}
4539+
}
4540+
44054541
/// Table type for ALTER TABLE statements.
44064542
/// Used to distinguish between regular tables, Iceberg tables, and Dynamic tables.
44074543
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]

src/ast/mod.rs

Lines changed: 44 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -60,18 +60,19 @@ pub use self::dcl::{
6060
SetConfigValue, Use,
6161
};
6262
pub use self::ddl::{
63-
Alignment, AlterColumnOperation, AlterConnectorOwner, AlterIndexOperation, AlterOperator,
64-
AlterOperatorClass, AlterOperatorClassOperation, AlterOperatorFamily,
65-
AlterOperatorFamilyOperation, AlterOperatorOperation, AlterPolicy, AlterPolicyOperation,
66-
AlterSchema, AlterSchemaOperation, AlterTable, AlterTableAlgorithm, AlterTableLock,
67-
AlterTableOperation, AlterTableType, AlterType, AlterTypeAddValue, AlterTypeAddValuePosition,
68-
AlterTypeOperation, AlterTypeRename, AlterTypeRenameValue, ClusteredBy, ColumnDef,
69-
ColumnOption, ColumnOptionDef, ColumnOptions, ColumnPolicy, ColumnPolicyProperty,
70-
ConstraintCharacteristics, CreateConnector, CreateDomain, CreateExtension, CreateFunction,
71-
CreateIndex, CreateOperator, CreateOperatorClass, CreateOperatorFamily, CreatePolicy,
72-
CreatePolicyCommand, CreatePolicyType, CreateTable, CreateTrigger, CreateView, Deduplicate,
73-
DeferrableInitial, DropBehavior, DropExtension, DropFunction, DropOperator, DropOperatorClass,
74-
DropOperatorFamily, DropOperatorSignature, DropPolicy, DropTrigger, ForValues, GeneratedAs,
63+
Alignment, AlterCollation, AlterCollationOperation, AlterColumnOperation, AlterConnectorOwner,
64+
AlterIndexOperation, AlterOperator, AlterOperatorClass, AlterOperatorClassOperation,
65+
AlterOperatorFamily, AlterOperatorFamilyOperation, AlterOperatorOperation, AlterPolicy,
66+
AlterPolicyOperation, AlterSchema, AlterSchemaOperation, AlterTable, AlterTableAlgorithm,
67+
AlterTableLock, AlterTableOperation, AlterTableType, AlterType, AlterTypeAddValue,
68+
AlterTypeAddValuePosition, AlterTypeOperation, AlterTypeRename, AlterTypeRenameValue,
69+
ClusteredBy, ColumnDef, ColumnOption, ColumnOptionDef, ColumnOptions, ColumnPolicy,
70+
ColumnPolicyProperty, ConstraintCharacteristics, CreateCollation, CreateCollationDefinition,
71+
CreateConnector, CreateDomain, CreateExtension, CreateFunction, CreateIndex, CreateOperator,
72+
CreateOperatorClass, CreateOperatorFamily, CreatePolicy, CreatePolicyCommand, CreatePolicyType,
73+
CreateTable, CreateTrigger, CreateView, Deduplicate, DeferrableInitial, DropBehavior,
74+
DropExtension, DropFunction, DropOperator, DropOperatorClass, DropOperatorFamily,
75+
DropOperatorSignature, DropPolicy, DropTrigger, ForValues, GeneratedAs,
7576
GeneratedExpressionMode, IdentityParameters, IdentityProperty, IdentityPropertyFormatKind,
7677
IdentityPropertyKind, IdentityPropertyOrder, IndexColumn, IndexOption, IndexType,
7778
KeyOrIndexDisplay, Msck, NullsDistinctOption, OperatorArgTypes, OperatorClassItem,
@@ -2437,6 +2438,8 @@ impl fmt::Display for ShowCreateObject {
24372438
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
24382439
/// Objects that can be targeted by a `COMMENT` statement.
24392440
pub enum CommentObject {
2441+
/// A collation.
2442+
Collation,
24402443
/// A table column.
24412444
Column,
24422445
/// A database.
@@ -2472,6 +2475,7 @@ pub enum CommentObject {
24722475
impl fmt::Display for CommentObject {
24732476
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
24742477
match self {
2478+
CommentObject::Collation => f.write_str("COLLATION"),
24752479
CommentObject::Column => f.write_str("COLUMN"),
24762480
CommentObject::Database => f.write_str("DATABASE"),
24772481
CommentObject::Domain => f.write_str("DOMAIN"),
@@ -3744,6 +3748,11 @@ pub enum Statement {
37443748
/// ```
37453749
AlterType(AlterType),
37463750
/// ```sql
3751+
/// ALTER COLLATION
3752+
/// ```
3753+
/// See [PostgreSQL](https://www.postgresql.org/docs/current/sql-altercollation.html)
3754+
AlterCollation(AlterCollation),
3755+
/// ```sql
37473756
/// ALTER OPERATOR
37483757
/// ```
37493758
/// See [PostgreSQL](https://www.postgresql.org/docs/current/sql-alteroperator.html)
@@ -3940,6 +3949,12 @@ pub enum Statement {
39403949
/// Note: this is a PostgreSQL-specific statement,
39413950
CreateExtension(CreateExtension),
39423951
/// ```sql
3952+
/// CREATE COLLATION
3953+
/// ```
3954+
/// Note: this is a PostgreSQL-specific statement.
3955+
/// <https://www.postgresql.org/docs/current/sql-createcollation.html>
3956+
CreateCollation(CreateCollation),
3957+
/// ```sql
39433958
/// DROP EXTENSION [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ]
39443959
/// ```
39453960
/// Note: this is a PostgreSQL-specific statement.
@@ -5389,6 +5404,7 @@ impl fmt::Display for Statement {
53895404
}
53905405
Statement::CreateIndex(create_index) => create_index.fmt(f),
53915406
Statement::CreateExtension(create_extension) => write!(f, "{create_extension}"),
5407+
Statement::CreateCollation(create_collation) => write!(f, "{create_collation}"),
53925408
Statement::DropExtension(drop_extension) => write!(f, "{drop_extension}"),
53935409
Statement::DropOperator(drop_operator) => write!(f, "{drop_operator}"),
53945410
Statement::DropOperatorFamily(drop_operator_family) => {
@@ -5465,6 +5481,7 @@ impl fmt::Display for Statement {
54655481
Statement::AlterType(AlterType { name, operation }) => {
54665482
write!(f, "ALTER TYPE {name} {operation}")
54675483
}
5484+
Statement::AlterCollation(alter_collation) => write!(f, "{alter_collation}"),
54685485
Statement::AlterOperator(alter_operator) => write!(f, "{alter_operator}"),
54695486
Statement::AlterOperatorFamily(alter_operator_family) => {
54705487
write!(f, "{alter_operator_family}")
@@ -8230,6 +8247,8 @@ impl fmt::Display for HavingBoundKind {
82308247
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
82318248
/// Types of database objects referenced by DDL statements.
82328249
pub enum ObjectType {
8250+
/// A collation.
8251+
Collation,
82338252
/// A table.
82348253
Table,
82358254
/// A view.
@@ -8259,6 +8278,7 @@ pub enum ObjectType {
82598278
impl fmt::Display for ObjectType {
82608279
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
82618280
f.write_str(match self {
8281+
ObjectType::Collation => "COLLATION",
82628282
ObjectType::Table => "TABLE",
82638283
ObjectType::View => "VIEW",
82648284
ObjectType::MaterializedView => "MATERIALIZED VIEW",
@@ -11816,6 +11836,12 @@ impl From<CreateExtension> for Statement {
1181611836
}
1181711837
}
1181811838

11839+
impl From<CreateCollation> for Statement {
11840+
fn from(c: CreateCollation) -> Self {
11841+
Self::CreateCollation(c)
11842+
}
11843+
}
11844+
1181911845
impl From<DropExtension> for Statement {
1182011846
fn from(de: DropExtension) -> Self {
1182111847
Self::DropExtension(de)
@@ -11924,6 +11950,12 @@ impl From<AlterType> for Statement {
1192411950
}
1192511951
}
1192611952

11953+
impl From<AlterCollation> for Statement {
11954+
fn from(a: AlterCollation) -> Self {
11955+
Self::AlterCollation(a)
11956+
}
11957+
}
11958+
1192711959
impl From<AlterOperator> for Statement {
1192811960
fn from(a: AlterOperator) -> Self {
1192911961
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]
@@ -376,6 +378,7 @@ impl Spanned for Statement {
376378
Statement::CreateIndex(create_index) => create_index.span(),
377379
Statement::CreateRole(create_role) => create_role.span(),
378380
Statement::CreateExtension(create_extension) => create_extension.span(),
381+
Statement::CreateCollation(create_collation) => create_collation.span(),
379382
Statement::DropExtension(drop_extension) => drop_extension.span(),
380383
Statement::DropOperator(drop_operator) => drop_operator.span(),
381384
Statement::DropOperatorFamily(drop_operator_family) => drop_operator_family.span(),
@@ -403,6 +406,7 @@ impl Spanned for Statement {
403406
),
404407
// These statements need to be implemented
405408
Statement::AlterType { .. } => Span::empty(),
409+
Statement::AlterCollation { .. } => Span::empty(),
406410
Statement::AlterOperator { .. } => Span::empty(),
407411
Statement::AlterOperatorFamily { .. } => Span::empty(),
408412
Statement::AlterOperatorClass { .. } => Span::empty(),

0 commit comments

Comments
 (0)