Skip to content

Commit 2af16ce

Browse files
Add PostgreSQL Collation DDL Support (apache#2249)
1 parent bced4f0 commit 2af16ce

6 files changed

Lines changed: 421 additions & 22 deletions

File tree

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: 52 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -60,26 +60,27 @@ pub use self::dcl::{
6060
SetConfigValue, Use,
6161
};
6262
pub use self::ddl::{
63-
Alignment, AlterColumnOperation, AlterConnectorOwner, AlterFunction, AlterFunctionAction,
64-
AlterFunctionKind, AlterFunctionOperation, AlterIndexOperation, AlterOperator,
65-
AlterOperatorClass, AlterOperatorClassOperation, AlterOperatorFamily,
66-
AlterOperatorFamilyOperation, AlterOperatorOperation, AlterPolicy, AlterPolicyOperation,
67-
AlterSchema, AlterSchemaOperation, AlterTable, AlterTableAlgorithm, AlterTableLock,
68-
AlterTableOperation, AlterTableType, AlterTextSearch, AlterTextSearchDictionaryOption,
69-
AlterTextSearchOperation, AlterType, AlterTypeAddValue, AlterTypeAddValuePosition,
70-
AlterTypeOperation, AlterTypeRename, AlterTypeRenameValue, ClusteredBy, ColumnDef,
71-
ColumnOption, ColumnOptionDef, ColumnOptions, ColumnPolicy, ColumnPolicyProperty,
72-
ConstraintCharacteristics, CreateConnector, CreateDomain, CreateExtension, CreateFunction,
73-
CreateIndex, CreateOperator, CreateOperatorClass, CreateOperatorFamily, CreatePolicy,
74-
CreatePolicyCommand, CreatePolicyType, CreateTable, CreateTextSearch, CreateTrigger,
75-
CreateView, Deduplicate, DeferrableInitial, DistStyle, DropBehavior, DropExtension,
76-
DropFunction, DropOperator, DropOperatorClass, DropOperatorFamily, DropOperatorSignature,
77-
DropPolicy, DropTrigger, ForValues, FunctionReturnType, GeneratedAs, GeneratedExpressionMode,
78-
IdentityParameters, IdentityProperty, IdentityPropertyFormatKind, IdentityPropertyKind,
79-
IdentityPropertyOrder, IndexColumn, IndexOption, IndexType, KeyOrIndexDisplay, Msck,
80-
NullsDistinctOption, OperatorArgTypes, OperatorClassItem, OperatorFamilyDropItem,
81-
OperatorFamilyItem, OperatorOption, OperatorPurpose, Owner, Partition, PartitionBoundValue,
82-
ProcedureParam, ReferentialAction, RenameTableNameKind, ReplicaIdentity, TagsColumnOption,
63+
Alignment, AlterCollation, AlterCollationOperation, AlterColumnOperation, AlterConnectorOwner,
64+
AlterFunction, AlterFunctionAction, AlterFunctionKind, AlterFunctionOperation,
65+
AlterIndexOperation, AlterOperator, AlterOperatorClass, AlterOperatorClassOperation,
66+
AlterOperatorFamily, AlterOperatorFamilyOperation, AlterOperatorOperation, AlterPolicy,
67+
AlterPolicyOperation, AlterSchema, AlterSchemaOperation, AlterTable, AlterTableAlgorithm,
68+
AlterTableLock, AlterTableOperation, AlterTableType, AlterTextSearch,
69+
AlterTextSearchDictionaryOption, AlterTextSearchOperation, AlterType, AlterTypeAddValue,
70+
AlterTypeAddValuePosition, AlterTypeOperation, AlterTypeRename, AlterTypeRenameValue,
71+
ClusteredBy, ColumnDef, ColumnOption, ColumnOptionDef, ColumnOptions, ColumnPolicy,
72+
ColumnPolicyProperty, ConstraintCharacteristics, CreateCollation, CreateCollationDefinition,
73+
CreateConnector, CreateDomain, CreateExtension, CreateFunction, CreateIndex, CreateOperator,
74+
CreateOperatorClass, CreateOperatorFamily, CreatePolicy, CreatePolicyCommand, CreatePolicyType,
75+
CreateTable, CreateTextSearch, CreateTrigger, CreateView, Deduplicate, DeferrableInitial,
76+
DistStyle, DropBehavior, DropExtension, DropFunction, DropOperator, DropOperatorClass,
77+
DropOperatorFamily, DropOperatorSignature, DropPolicy, DropTrigger, ForValues,
78+
FunctionReturnType, GeneratedAs, GeneratedExpressionMode, IdentityParameters,
79+
IdentityProperty, IdentityPropertyFormatKind, IdentityPropertyKind, IdentityPropertyOrder,
80+
IndexColumn, IndexOption, IndexType, KeyOrIndexDisplay, Msck, NullsDistinctOption,
81+
OperatorArgTypes, OperatorClassItem, OperatorFamilyDropItem, OperatorFamilyItem,
82+
OperatorOption, OperatorPurpose, Owner, Partition, PartitionBoundValue, ProcedureParam,
83+
ReferentialAction, RenameTableNameKind, ReplicaIdentity, TagsColumnOption,
8384
TextSearchObjectType, TriggerObjectKind, Truncate, UserDefinedTypeCompositeAttributeDef,
8485
UserDefinedTypeInternalLength, UserDefinedTypeRangeOption, UserDefinedTypeRepresentation,
8586
UserDefinedTypeSqlDefinitionOption, UserDefinedTypeStorage, ViewColumnDef,
@@ -2451,6 +2452,8 @@ impl fmt::Display for ShowCreateObject {
24512452
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
24522453
/// Objects that can be targeted by a `COMMENT` statement.
24532454
pub enum CommentObject {
2455+
/// A collation.
2456+
Collation,
24542457
/// A table column.
24552458
Column,
24562459
/// A database.
@@ -2486,6 +2489,7 @@ pub enum CommentObject {
24862489
impl fmt::Display for CommentObject {
24872490
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
24882491
match self {
2492+
CommentObject::Collation => f.write_str("COLLATION"),
24892493
CommentObject::Column => f.write_str("COLUMN"),
24902494
CommentObject::Database => f.write_str("DATABASE"),
24912495
CommentObject::Domain => f.write_str("DOMAIN"),
@@ -3770,6 +3774,11 @@ pub enum Statement {
37703774
/// ```
37713775
AlterType(AlterType),
37723776
/// ```sql
3777+
/// ALTER COLLATION
3778+
/// ```
3779+
/// See [PostgreSQL](https://www.postgresql.org/docs/current/sql-altercollation.html)
3780+
AlterCollation(AlterCollation),
3781+
/// ```sql
37733782
/// ALTER OPERATOR
37743783
/// ```
37753784
/// See [PostgreSQL](https://www.postgresql.org/docs/current/sql-alteroperator.html)
@@ -3971,6 +3980,12 @@ pub enum Statement {
39713980
/// Note: this is a PostgreSQL-specific statement,
39723981
CreateExtension(CreateExtension),
39733982
/// ```sql
3983+
/// CREATE COLLATION
3984+
/// ```
3985+
/// Note: this is a PostgreSQL-specific statement.
3986+
/// <https://www.postgresql.org/docs/current/sql-createcollation.html>
3987+
CreateCollation(CreateCollation),
3988+
/// ```sql
39743989
/// DROP EXTENSION [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ]
39753990
/// ```
39763991
/// Note: this is a PostgreSQL-specific statement.
@@ -5441,6 +5456,7 @@ impl fmt::Display for Statement {
54415456
}
54425457
Statement::CreateIndex(create_index) => create_index.fmt(f),
54435458
Statement::CreateExtension(create_extension) => write!(f, "{create_extension}"),
5459+
Statement::CreateCollation(create_collation) => write!(f, "{create_collation}"),
54445460
Statement::DropExtension(drop_extension) => write!(f, "{drop_extension}"),
54455461
Statement::DropOperator(drop_operator) => write!(f, "{drop_operator}"),
54465462
Statement::DropOperatorFamily(drop_operator_family) => {
@@ -5519,6 +5535,7 @@ impl fmt::Display for Statement {
55195535
Statement::AlterType(AlterType { name, operation }) => {
55205536
write!(f, "ALTER TYPE {name} {operation}")
55215537
}
5538+
Statement::AlterCollation(alter_collation) => write!(f, "{alter_collation}"),
55225539
Statement::AlterOperator(alter_operator) => write!(f, "{alter_operator}"),
55235540
Statement::AlterOperatorFamily(alter_operator_family) => {
55245541
write!(f, "{alter_operator_family}")
@@ -8393,6 +8410,8 @@ impl fmt::Display for HavingBoundKind {
83938410
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
83948411
/// Types of database objects referenced by DDL statements.
83958412
pub enum ObjectType {
8413+
/// A collation.
8414+
Collation,
83968415
/// A table.
83978416
Table,
83988417
/// A view.
@@ -8422,6 +8441,7 @@ pub enum ObjectType {
84228441
impl fmt::Display for ObjectType {
84238442
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
84248443
f.write_str(match self {
8444+
ObjectType::Collation => "COLLATION",
84258445
ObjectType::Table => "TABLE",
84268446
ObjectType::View => "VIEW",
84278447
ObjectType::MaterializedView => "MATERIALIZED VIEW",
@@ -12024,6 +12044,12 @@ impl From<CreateExtension> for Statement {
1202412044
}
1202512045
}
1202612046

12047+
impl From<CreateCollation> for Statement {
12048+
fn from(c: CreateCollation) -> Self {
12049+
Self::CreateCollation(c)
12050+
}
12051+
}
12052+
1202712053
impl From<DropExtension> for Statement {
1202812054
fn from(de: DropExtension) -> Self {
1202912055
Self::DropExtension(de)
@@ -12144,6 +12170,12 @@ impl From<AlterType> for Statement {
1214412170
}
1214512171
}
1214612172

12173+
impl From<AlterCollation> for Statement {
12174+
fn from(a: AlterCollation) -> Self {
12175+
Self::AlterCollation(a)
12176+
}
12177+
}
12178+
1214712179
impl From<AlterOperator> for Statement {
1214812180
fn from(a: AlterOperator) -> Self {
1214912181
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(),
@@ -406,6 +409,7 @@ impl Spanned for Statement {
406409
// These statements need to be implemented
407410
Statement::AlterFunction { .. } => Span::empty(),
408411
Statement::AlterType { .. } => Span::empty(),
412+
Statement::AlterCollation { .. } => Span::empty(),
409413
Statement::AlterOperator { .. } => Span::empty(),
410414
Statement::AlterOperatorFamily { .. } => Span::empty(),
411415
Statement::AlterOperatorClass { .. } => Span::empty(),

0 commit comments

Comments
 (0)