Skip to content

Commit c78237d

Browse files
feat(postgres): implement ALTER FUNCTION/AGGREGATE parsing parity
Add ALTER FUNCTION/ALTER AGGREGATE support through AST and parser dispatch, including action parsing and aggregate signature handling. Tighten PostgreSQL parity semantics in parser branches (function-only DEPENDS ON EXTENSION, stricter aggregate signature argument rules) and add VARIADIC function argument mode support.
1 parent 531ebdf commit c78237d

File tree

5 files changed

+544
-8
lines changed

5 files changed

+544
-8
lines changed

src/ast/ddl.rs

Lines changed: 211 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,9 @@ 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,
50+
OrderByExpr, ProjectionSelect, Query, RefreshModeKind, ResetConfig, RowAccessPolicy,
51+
SequenceOptions, Spanned, SqlOption, StorageLifecyclePolicy, StorageSerializationPolicy,
52+
TableVersion, Tag,
5253
TriggerEvent, TriggerExecBody, TriggerObject, TriggerPeriod, TriggerReferencing, Value,
5354
ValueWithSpan, WrappedCollection,
5455
};
@@ -5222,6 +5223,214 @@ impl Spanned for AlterOperatorClass {
52225223
}
52235224
}
52245225

5226+
/// `ALTER FUNCTION` / `ALTER AGGREGATE` statement.
5227+
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
5228+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
5229+
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
5230+
pub struct AlterFunction {
5231+
/// Object type being altered.
5232+
pub kind: AlterFunctionKind,
5233+
/// Function or aggregate signature.
5234+
pub function: FunctionDesc,
5235+
/// `ORDER BY` argument list for aggregate signatures.
5236+
///
5237+
/// This is only used for `ALTER AGGREGATE`.
5238+
pub aggregate_order_by: Option<Vec<OperateFunctionArg>>,
5239+
/// Whether the aggregate signature uses `*`.
5240+
///
5241+
/// This is only used for `ALTER AGGREGATE`.
5242+
pub aggregate_star: bool,
5243+
/// Operation applied to the object.
5244+
pub operation: AlterFunctionOperation,
5245+
}
5246+
5247+
/// Function-like object type used by [`AlterFunction`].
5248+
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
5249+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
5250+
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
5251+
pub enum AlterFunctionKind {
5252+
/// `FUNCTION`
5253+
Function,
5254+
/// `AGGREGATE`
5255+
Aggregate,
5256+
}
5257+
5258+
impl fmt::Display for AlterFunctionKind {
5259+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
5260+
match self {
5261+
Self::Function => write!(f, "FUNCTION"),
5262+
Self::Aggregate => write!(f, "AGGREGATE"),
5263+
}
5264+
}
5265+
}
5266+
5267+
/// Operation for `ALTER FUNCTION` / `ALTER AGGREGATE`.
5268+
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
5269+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
5270+
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
5271+
pub enum AlterFunctionOperation {
5272+
/// `RENAME TO new_name`
5273+
RenameTo {
5274+
/// New unqualified function or aggregate name.
5275+
new_name: Ident,
5276+
},
5277+
/// `OWNER TO { new_owner | CURRENT_ROLE | CURRENT_USER | SESSION_USER }`
5278+
OwnerTo(Owner),
5279+
/// `SET SCHEMA schema_name`
5280+
SetSchema {
5281+
/// The target schema name.
5282+
schema_name: ObjectName,
5283+
},
5284+
/// `[ NO ] DEPENDS ON EXTENSION extension_name`
5285+
DependsOnExtension {
5286+
/// `true` when `NO DEPENDS ON EXTENSION`.
5287+
no: bool,
5288+
/// Extension name.
5289+
extension_name: ObjectName,
5290+
},
5291+
/// `action [ ... ] [ RESTRICT ]` (function only).
5292+
Actions {
5293+
/// One or more function actions.
5294+
actions: Vec<AlterFunctionAction>,
5295+
/// Whether `RESTRICT` is present.
5296+
restrict: bool,
5297+
},
5298+
}
5299+
5300+
/// Function action in `ALTER FUNCTION ... action [ ... ] [ RESTRICT ]`.
5301+
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
5302+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
5303+
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
5304+
pub enum AlterFunctionAction {
5305+
/// `CALLED ON NULL INPUT` / `RETURNS NULL ON NULL INPUT` / `STRICT`
5306+
CalledOnNull(FunctionCalledOnNull),
5307+
/// `IMMUTABLE` / `STABLE` / `VOLATILE`
5308+
Behavior(FunctionBehavior),
5309+
/// `[ NOT ] LEAKPROOF`
5310+
Leakproof(bool),
5311+
/// `[ EXTERNAL ] SECURITY { DEFINER | INVOKER }`
5312+
Security {
5313+
/// Whether the optional `EXTERNAL` keyword was present.
5314+
external: bool,
5315+
/// Security mode.
5316+
security: FunctionSecurity,
5317+
},
5318+
/// `PARALLEL { UNSAFE | RESTRICTED | SAFE }`
5319+
Parallel(FunctionParallel),
5320+
/// `COST execution_cost`
5321+
Cost(Expr),
5322+
/// `ROWS result_rows`
5323+
Rows(Expr),
5324+
/// `SUPPORT support_function`
5325+
Support(ObjectName),
5326+
/// `SET configuration_parameter { TO | = } { value | DEFAULT }`
5327+
/// or `SET configuration_parameter FROM CURRENT`
5328+
Set(FunctionDefinitionSetParam),
5329+
/// `RESET configuration_parameter` or `RESET ALL`
5330+
Reset(ResetConfig),
5331+
}
5332+
5333+
impl fmt::Display for AlterFunction {
5334+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
5335+
write!(f, "ALTER {} ", self.kind)?;
5336+
match self.kind {
5337+
AlterFunctionKind::Function => {
5338+
write!(f, "{} ", self.function)?;
5339+
}
5340+
AlterFunctionKind::Aggregate => {
5341+
write!(f, "{}(", self.function.name)?;
5342+
if self.aggregate_star {
5343+
write!(f, "*")?;
5344+
} else {
5345+
if let Some(args) = &self.function.args {
5346+
write!(f, "{}", display_comma_separated(args))?;
5347+
}
5348+
if let Some(order_by_args) = &self.aggregate_order_by {
5349+
if self
5350+
.function
5351+
.args
5352+
.as_ref()
5353+
.is_some_and(|args| !args.is_empty())
5354+
{
5355+
write!(f, " ")?;
5356+
}
5357+
write!(f, "ORDER BY {}", display_comma_separated(order_by_args))?;
5358+
}
5359+
}
5360+
write!(f, ") ")?;
5361+
}
5362+
}
5363+
write!(f, "{}", self.operation)
5364+
}
5365+
}
5366+
5367+
impl fmt::Display for AlterFunctionOperation {
5368+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
5369+
match self {
5370+
AlterFunctionOperation::RenameTo { new_name } => {
5371+
write!(f, "RENAME TO {new_name}")
5372+
}
5373+
AlterFunctionOperation::OwnerTo(owner) => write!(f, "OWNER TO {owner}"),
5374+
AlterFunctionOperation::SetSchema { schema_name } => {
5375+
write!(f, "SET SCHEMA {schema_name}")
5376+
}
5377+
AlterFunctionOperation::DependsOnExtension { no, extension_name } => {
5378+
if *no {
5379+
write!(f, "NO DEPENDS ON EXTENSION {extension_name}")
5380+
} else {
5381+
write!(f, "DEPENDS ON EXTENSION {extension_name}")
5382+
}
5383+
}
5384+
AlterFunctionOperation::Actions { actions, restrict } => {
5385+
write!(f, "{}", display_separated(actions, " "))?;
5386+
if *restrict {
5387+
write!(f, " RESTRICT")?;
5388+
}
5389+
Ok(())
5390+
}
5391+
}
5392+
}
5393+
}
5394+
5395+
impl fmt::Display for AlterFunctionAction {
5396+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
5397+
match self {
5398+
AlterFunctionAction::CalledOnNull(called_on_null) => write!(f, "{called_on_null}"),
5399+
AlterFunctionAction::Behavior(behavior) => write!(f, "{behavior}"),
5400+
AlterFunctionAction::Leakproof(leakproof) => {
5401+
if *leakproof {
5402+
write!(f, "LEAKPROOF")
5403+
} else {
5404+
write!(f, "NOT LEAKPROOF")
5405+
}
5406+
}
5407+
AlterFunctionAction::Security { external, security } => {
5408+
if *external {
5409+
write!(f, "EXTERNAL ")?;
5410+
}
5411+
write!(f, "{security}")
5412+
}
5413+
AlterFunctionAction::Parallel(parallel) => write!(f, "{parallel}"),
5414+
AlterFunctionAction::Cost(execution_cost) => write!(f, "COST {execution_cost}"),
5415+
AlterFunctionAction::Rows(result_rows) => write!(f, "ROWS {result_rows}"),
5416+
AlterFunctionAction::Support(support_function) => {
5417+
write!(f, "SUPPORT {support_function}")
5418+
}
5419+
AlterFunctionAction::Set(set_param) => write!(f, "{set_param}"),
5420+
AlterFunctionAction::Reset(reset_config) => match reset_config {
5421+
ResetConfig::ALL => write!(f, "RESET ALL"),
5422+
ResetConfig::ConfigName(name) => write!(f, "RESET {name}"),
5423+
},
5424+
}
5425+
}
5426+
}
5427+
5428+
impl Spanned for AlterFunction {
5429+
fn span(&self) -> Span {
5430+
Span::empty()
5431+
}
5432+
}
5433+
52255434
/// CREATE POLICY statement.
52265435
///
52275436
/// See [PostgreSQL](https://www.postgresql.org/docs/current/sql-createpolicy.html)

src/ast/mod.rs

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,8 @@ pub use self::dcl::{
6060
SetConfigValue, Use,
6161
};
6262
pub use self::ddl::{
63-
Alignment, AlterColumnOperation, AlterConnectorOwner, AlterIndexOperation, AlterOperator,
63+
Alignment, AlterColumnOperation, AlterConnectorOwner, AlterFunction, AlterFunctionAction,
64+
AlterFunctionKind, AlterFunctionOperation, AlterIndexOperation, AlterOperator,
6465
AlterOperatorClass, AlterOperatorClassOperation, AlterOperatorFamily,
6566
AlterOperatorFamilyOperation, AlterOperatorOperation, AlterPolicy, AlterPolicyOperation,
6667
AlterSchema, AlterSchemaOperation, AlterTable, AlterTableAlgorithm, AlterTableLock,
@@ -3751,6 +3752,13 @@ pub enum Statement {
37513752
with_options: Vec<SqlOption>,
37523753
},
37533754
/// ```sql
3755+
/// ALTER FUNCTION
3756+
/// ALTER AGGREGATE
3757+
/// ```
3758+
/// See [PostgreSQL](https://www.postgresql.org/docs/current/sql-alterfunction.html)
3759+
/// and [PostgreSQL](https://www.postgresql.org/docs/current/sql-alteraggregate.html)
3760+
AlterFunction(AlterFunction),
3761+
/// ```sql
37543762
/// ALTER TYPE
37553763
/// See [PostgreSQL](https://www.postgresql.org/docs/current/sql-altertype.html)
37563764
/// ```
@@ -5486,6 +5494,7 @@ impl fmt::Display for Statement {
54865494
}
54875495
write!(f, " AS {query}")
54885496
}
5497+
Statement::AlterFunction(alter_function) => write!(f, "{alter_function}"),
54895498
Statement::AlterType(AlterType { name, operation }) => {
54905499
write!(f, "ALTER TYPE {name} {operation}")
54915500
}
@@ -9815,6 +9824,8 @@ pub enum ArgMode {
98159824
Out,
98169825
/// `INOUT` mode.
98179826
InOut,
9827+
/// `VARIADIC` mode.
9828+
Variadic,
98189829
}
98199830

98209831
impl fmt::Display for ArgMode {
@@ -9823,6 +9834,7 @@ impl fmt::Display for ArgMode {
98239834
ArgMode::In => write!(f, "IN"),
98249835
ArgMode::Out => write!(f, "OUT"),
98259836
ArgMode::InOut => write!(f, "INOUT"),
9837+
ArgMode::Variadic => write!(f, "VARIADIC"),
98269838
}
98279839
}
98289840
}
@@ -9879,6 +9891,8 @@ impl fmt::Display for FunctionSecurity {
98799891
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
98809892
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
98819893
pub enum FunctionSetValue {
9894+
/// SET param = DEFAULT / SET param TO DEFAULT
9895+
Default,
98829896
/// SET param = value1, value2, ...
98839897
Values(Vec<Expr>),
98849898
/// SET param FROM CURRENT
@@ -9893,7 +9907,7 @@ pub enum FunctionSetValue {
98939907
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
98949908
pub struct FunctionDefinitionSetParam {
98959909
/// The name of the configuration parameter.
9896-
pub name: Ident,
9910+
pub name: ObjectName,
98979911
/// The value to set for the parameter.
98989912
pub value: FunctionSetValue,
98999913
}
@@ -9902,6 +9916,7 @@ impl fmt::Display for FunctionDefinitionSetParam {
99029916
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
99039917
write!(f, "SET {} ", self.name)?;
99049918
match &self.value {
9919+
FunctionSetValue::Default => write!(f, "= DEFAULT"),
99059920
FunctionSetValue::Values(values) => {
99069921
write!(f, "= {}", display_comma_separated(values))
99079922
}
@@ -12081,6 +12096,12 @@ impl From<AlterSchema> for Statement {
1208112096
}
1208212097
}
1208312098

12099+
impl From<AlterFunction> for Statement {
12100+
fn from(a: AlterFunction) -> Self {
12101+
Self::AlterFunction(a)
12102+
}
12103+
}
12104+
1208412105
impl From<AlterType> for Statement {
1208512106
fn from(a: AlterType) -> Self {
1208612107
Self::AlterType(a)

src/ast/spans.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,7 @@ impl Spanned for Statement {
403403
.chain(with_options.iter().map(|i| i.span())),
404404
),
405405
// These statements need to be implemented
406+
Statement::AlterFunction { .. } => Span::empty(),
406407
Statement::AlterType { .. } => Span::empty(),
407408
Statement::AlterOperator { .. } => Span::empty(),
408409
Statement::AlterOperatorFamily { .. } => Span::empty(),

src/keywords.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1135,6 +1135,7 @@ define_keywords!(
11351135
VARCHAR2,
11361136
VARIABLE,
11371137
VARIABLES,
1138+
VARIADIC,
11381139
VARYING,
11391140
VAR_POP,
11401141
VAR_SAMP,

0 commit comments

Comments
 (0)