Skip to content

Commit 55af6f1

Browse files
author
Roman Borschel
committed
Merge branch 'main' into collate-after-compound-expr
2 parents bcfbda6 + 1421b87 commit 55af6f1

22 files changed

+1667
-111
lines changed

src/ast/ddl.rs

Lines changed: 348 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,10 @@ use crate::ast::{
4747
FunctionDeterminismSpecifier, FunctionParallel, FunctionSecurity, HiveDistributionStyle,
4848
HiveFormat, HiveIOFormat, HiveRowFormat, HiveSetLocation, Ident, InitializeKind,
4949
MySQLColumnPosition, ObjectName, OnCommit, OneOrManyWithParens, OperateFunctionArg,
50-
OrderByExpr, ProjectionSelect, Query, RefreshModeKind, RowAccessPolicy, SequenceOptions,
51-
Spanned, SqlOption, StorageLifecyclePolicy, StorageSerializationPolicy, TableVersion, Tag,
52-
TriggerEvent, TriggerExecBody, TriggerObject, TriggerPeriod, TriggerReferencing, Value,
53-
ValueWithSpan, WrappedCollection,
50+
OrderByExpr, ProjectionSelect, Query, RefreshModeKind, ResetConfig, RowAccessPolicy,
51+
SequenceOptions, Spanned, SqlOption, StorageLifecyclePolicy, StorageSerializationPolicy,
52+
TableVersion, Tag, TriggerEvent, TriggerExecBody, TriggerObject, TriggerPeriod,
53+
TriggerReferencing, Value, ValueWithSpan, WrappedCollection,
5454
};
5555
use crate::display_utils::{DisplayCommaSeparated, Indent, NewLine, SpaceOrNewline};
5656
use crate::keywords::Keyword;
@@ -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)]
@@ -5222,6 +5358,214 @@ impl Spanned for AlterOperatorClass {
52225358
}
52235359
}
52245360

5361+
/// `ALTER FUNCTION` / `ALTER AGGREGATE` statement.
5362+
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
5363+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
5364+
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
5365+
pub struct AlterFunction {
5366+
/// Object type being altered.
5367+
pub kind: AlterFunctionKind,
5368+
/// Function or aggregate signature.
5369+
pub function: FunctionDesc,
5370+
/// `ORDER BY` argument list for aggregate signatures.
5371+
///
5372+
/// This is only used for `ALTER AGGREGATE`.
5373+
pub aggregate_order_by: Option<Vec<OperateFunctionArg>>,
5374+
/// Whether the aggregate signature uses `*`.
5375+
///
5376+
/// This is only used for `ALTER AGGREGATE`.
5377+
pub aggregate_star: bool,
5378+
/// Operation applied to the object.
5379+
pub operation: AlterFunctionOperation,
5380+
}
5381+
5382+
/// Function-like object type used by [`AlterFunction`].
5383+
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
5384+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
5385+
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
5386+
pub enum AlterFunctionKind {
5387+
/// `FUNCTION`
5388+
Function,
5389+
/// `AGGREGATE`
5390+
Aggregate,
5391+
}
5392+
5393+
impl fmt::Display for AlterFunctionKind {
5394+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
5395+
match self {
5396+
Self::Function => write!(f, "FUNCTION"),
5397+
Self::Aggregate => write!(f, "AGGREGATE"),
5398+
}
5399+
}
5400+
}
5401+
5402+
/// Operation for `ALTER FUNCTION` / `ALTER AGGREGATE`.
5403+
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
5404+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
5405+
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
5406+
pub enum AlterFunctionOperation {
5407+
/// `RENAME TO new_name`
5408+
RenameTo {
5409+
/// New unqualified function or aggregate name.
5410+
new_name: Ident,
5411+
},
5412+
/// `OWNER TO { new_owner | CURRENT_ROLE | CURRENT_USER | SESSION_USER }`
5413+
OwnerTo(Owner),
5414+
/// `SET SCHEMA schema_name`
5415+
SetSchema {
5416+
/// The target schema name.
5417+
schema_name: ObjectName,
5418+
},
5419+
/// `[ NO ] DEPENDS ON EXTENSION extension_name`
5420+
DependsOnExtension {
5421+
/// `true` when `NO DEPENDS ON EXTENSION`.
5422+
no: bool,
5423+
/// Extension name.
5424+
extension_name: ObjectName,
5425+
},
5426+
/// `action [ ... ] [ RESTRICT ]` (function only).
5427+
Actions {
5428+
/// One or more function actions.
5429+
actions: Vec<AlterFunctionAction>,
5430+
/// Whether `RESTRICT` is present.
5431+
restrict: bool,
5432+
},
5433+
}
5434+
5435+
/// Function action in `ALTER FUNCTION ... action [ ... ] [ RESTRICT ]`.
5436+
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
5437+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
5438+
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
5439+
pub enum AlterFunctionAction {
5440+
/// `CALLED ON NULL INPUT` / `RETURNS NULL ON NULL INPUT` / `STRICT`
5441+
CalledOnNull(FunctionCalledOnNull),
5442+
/// `IMMUTABLE` / `STABLE` / `VOLATILE`
5443+
Behavior(FunctionBehavior),
5444+
/// `[ NOT ] LEAKPROOF`
5445+
Leakproof(bool),
5446+
/// `[ EXTERNAL ] SECURITY { DEFINER | INVOKER }`
5447+
Security {
5448+
/// Whether the optional `EXTERNAL` keyword was present.
5449+
external: bool,
5450+
/// Security mode.
5451+
security: FunctionSecurity,
5452+
},
5453+
/// `PARALLEL { UNSAFE | RESTRICTED | SAFE }`
5454+
Parallel(FunctionParallel),
5455+
/// `COST execution_cost`
5456+
Cost(Expr),
5457+
/// `ROWS result_rows`
5458+
Rows(Expr),
5459+
/// `SUPPORT support_function`
5460+
Support(ObjectName),
5461+
/// `SET configuration_parameter { TO | = } { value | DEFAULT }`
5462+
/// or `SET configuration_parameter FROM CURRENT`
5463+
Set(FunctionDefinitionSetParam),
5464+
/// `RESET configuration_parameter` or `RESET ALL`
5465+
Reset(ResetConfig),
5466+
}
5467+
5468+
impl fmt::Display for AlterFunction {
5469+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
5470+
write!(f, "ALTER {} ", self.kind)?;
5471+
match self.kind {
5472+
AlterFunctionKind::Function => {
5473+
write!(f, "{} ", self.function)?;
5474+
}
5475+
AlterFunctionKind::Aggregate => {
5476+
write!(f, "{}(", self.function.name)?;
5477+
if self.aggregate_star {
5478+
write!(f, "*")?;
5479+
} else {
5480+
if let Some(args) = &self.function.args {
5481+
write!(f, "{}", display_comma_separated(args))?;
5482+
}
5483+
if let Some(order_by_args) = &self.aggregate_order_by {
5484+
if self
5485+
.function
5486+
.args
5487+
.as_ref()
5488+
.is_some_and(|args| !args.is_empty())
5489+
{
5490+
write!(f, " ")?;
5491+
}
5492+
write!(f, "ORDER BY {}", display_comma_separated(order_by_args))?;
5493+
}
5494+
}
5495+
write!(f, ") ")?;
5496+
}
5497+
}
5498+
write!(f, "{}", self.operation)
5499+
}
5500+
}
5501+
5502+
impl fmt::Display for AlterFunctionOperation {
5503+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
5504+
match self {
5505+
AlterFunctionOperation::RenameTo { new_name } => {
5506+
write!(f, "RENAME TO {new_name}")
5507+
}
5508+
AlterFunctionOperation::OwnerTo(owner) => write!(f, "OWNER TO {owner}"),
5509+
AlterFunctionOperation::SetSchema { schema_name } => {
5510+
write!(f, "SET SCHEMA {schema_name}")
5511+
}
5512+
AlterFunctionOperation::DependsOnExtension { no, extension_name } => {
5513+
if *no {
5514+
write!(f, "NO DEPENDS ON EXTENSION {extension_name}")
5515+
} else {
5516+
write!(f, "DEPENDS ON EXTENSION {extension_name}")
5517+
}
5518+
}
5519+
AlterFunctionOperation::Actions { actions, restrict } => {
5520+
write!(f, "{}", display_separated(actions, " "))?;
5521+
if *restrict {
5522+
write!(f, " RESTRICT")?;
5523+
}
5524+
Ok(())
5525+
}
5526+
}
5527+
}
5528+
}
5529+
5530+
impl fmt::Display for AlterFunctionAction {
5531+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
5532+
match self {
5533+
AlterFunctionAction::CalledOnNull(called_on_null) => write!(f, "{called_on_null}"),
5534+
AlterFunctionAction::Behavior(behavior) => write!(f, "{behavior}"),
5535+
AlterFunctionAction::Leakproof(leakproof) => {
5536+
if *leakproof {
5537+
write!(f, "LEAKPROOF")
5538+
} else {
5539+
write!(f, "NOT LEAKPROOF")
5540+
}
5541+
}
5542+
AlterFunctionAction::Security { external, security } => {
5543+
if *external {
5544+
write!(f, "EXTERNAL ")?;
5545+
}
5546+
write!(f, "{security}")
5547+
}
5548+
AlterFunctionAction::Parallel(parallel) => write!(f, "{parallel}"),
5549+
AlterFunctionAction::Cost(execution_cost) => write!(f, "COST {execution_cost}"),
5550+
AlterFunctionAction::Rows(result_rows) => write!(f, "ROWS {result_rows}"),
5551+
AlterFunctionAction::Support(support_function) => {
5552+
write!(f, "SUPPORT {support_function}")
5553+
}
5554+
AlterFunctionAction::Set(set_param) => write!(f, "{set_param}"),
5555+
AlterFunctionAction::Reset(reset_config) => match reset_config {
5556+
ResetConfig::ALL => write!(f, "RESET ALL"),
5557+
ResetConfig::ConfigName(name) => write!(f, "RESET {name}"),
5558+
},
5559+
}
5560+
}
5561+
}
5562+
5563+
impl Spanned for AlterFunction {
5564+
fn span(&self) -> Span {
5565+
Span::empty()
5566+
}
5567+
}
5568+
52255569
/// CREATE POLICY statement.
52265570
///
52275571
/// See [PostgreSQL](https://www.postgresql.org/docs/current/sql-createpolicy.html)

src/ast/dml.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,9 @@ pub struct Update {
387387
pub output: Option<OutputClause>,
388388
/// SQLite-specific conflict resolution clause
389389
pub or: Option<SqliteOnConflict>,
390+
/// ORDER BY (MySQL extension for single-table UPDATE)
391+
/// See <https://dev.mysql.com/doc/refman/8.4/en/update.html>
392+
pub order_by: Vec<OrderByExpr>,
390393
/// LIMIT
391394
pub limit: Option<Expr>,
392395
}
@@ -434,6 +437,11 @@ impl Display for Update {
434437
f.write_str("RETURNING")?;
435438
indented_list(f, returning)?;
436439
}
440+
if !self.order_by.is_empty() {
441+
SpaceOrNewline.fmt(f)?;
442+
f.write_str("ORDER BY")?;
443+
indented_list(f, &self.order_by)?;
444+
}
437445
if let Some(limit) = &self.limit {
438446
SpaceOrNewline.fmt(f)?;
439447
write!(f, "LIMIT {limit}")?;

0 commit comments

Comments
 (0)