Skip to content

Commit 0a4263c

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 bd7f70e commit 0a4263c

File tree

5 files changed

+545
-10
lines changed

5 files changed

+545
-10
lines changed

src/ast/ddl.rs

Lines changed: 212 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, StorageSerializationPolicy, TableVersion, Tag, TriggerEvent,
52-
TriggerExecBody, TriggerObject, TriggerPeriod, TriggerReferencing, Value, ValueWithSpan,
53-
WrappedCollection,
50+
OrderByExpr, ProjectionSelect, Query, RefreshModeKind, ResetConfig, RowAccessPolicy,
51+
SequenceOptions, Spanned, SqlOption, StorageSerializationPolicy, TableVersion, Tag,
52+
TriggerEvent, TriggerExecBody, TriggerObject, TriggerPeriod, TriggerReferencing, Value,
53+
ValueWithSpan, WrappedCollection,
5454
};
5555
use crate::display_utils::{DisplayCommaSeparated, Indent, NewLine, SpaceOrNewline};
5656
use crate::keywords::Keyword;
@@ -5121,6 +5121,214 @@ impl Spanned for AlterOperatorClass {
51215121
}
51225122
}
51235123

5124+
/// `ALTER FUNCTION` / `ALTER AGGREGATE` statement.
5125+
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
5126+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
5127+
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
5128+
pub struct AlterFunction {
5129+
/// Object type being altered.
5130+
pub kind: AlterFunctionKind,
5131+
/// Function or aggregate signature.
5132+
pub function: FunctionDesc,
5133+
/// `ORDER BY` argument list for aggregate signatures.
5134+
///
5135+
/// This is only used for `ALTER AGGREGATE`.
5136+
pub aggregate_order_by: Option<Vec<OperateFunctionArg>>,
5137+
/// Whether the aggregate signature uses `*`.
5138+
///
5139+
/// This is only used for `ALTER AGGREGATE`.
5140+
pub aggregate_star: bool,
5141+
/// Operation applied to the object.
5142+
pub operation: AlterFunctionOperation,
5143+
}
5144+
5145+
/// Function-like object type used by [`AlterFunction`].
5146+
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
5147+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
5148+
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
5149+
pub enum AlterFunctionKind {
5150+
/// `FUNCTION`
5151+
Function,
5152+
/// `AGGREGATE`
5153+
Aggregate,
5154+
}
5155+
5156+
impl fmt::Display for AlterFunctionKind {
5157+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
5158+
match self {
5159+
Self::Function => write!(f, "FUNCTION"),
5160+
Self::Aggregate => write!(f, "AGGREGATE"),
5161+
}
5162+
}
5163+
}
5164+
5165+
/// Operation for `ALTER FUNCTION` / `ALTER AGGREGATE`.
5166+
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
5167+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
5168+
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
5169+
pub enum AlterFunctionOperation {
5170+
/// `RENAME TO new_name`
5171+
RenameTo {
5172+
/// New unqualified function or aggregate name.
5173+
new_name: Ident,
5174+
},
5175+
/// `OWNER TO { new_owner | CURRENT_ROLE | CURRENT_USER | SESSION_USER }`
5176+
OwnerTo(Owner),
5177+
/// `SET SCHEMA schema_name`
5178+
SetSchema {
5179+
/// The target schema name.
5180+
schema_name: ObjectName,
5181+
},
5182+
/// `[ NO ] DEPENDS ON EXTENSION extension_name`
5183+
DependsOnExtension {
5184+
/// `true` when `NO DEPENDS ON EXTENSION`.
5185+
no: bool,
5186+
/// Extension name.
5187+
extension_name: ObjectName,
5188+
},
5189+
/// `action [ ... ] [ RESTRICT ]` (function only).
5190+
Actions {
5191+
/// One or more function actions.
5192+
actions: Vec<AlterFunctionAction>,
5193+
/// Whether `RESTRICT` is present.
5194+
restrict: bool,
5195+
},
5196+
}
5197+
5198+
/// Function action in `ALTER FUNCTION ... action [ ... ] [ RESTRICT ]`.
5199+
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
5200+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
5201+
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
5202+
pub enum AlterFunctionAction {
5203+
/// `CALLED ON NULL INPUT` / `RETURNS NULL ON NULL INPUT` / `STRICT`
5204+
CalledOnNull(FunctionCalledOnNull),
5205+
/// `IMMUTABLE` / `STABLE` / `VOLATILE`
5206+
Behavior(FunctionBehavior),
5207+
/// `[ NOT ] LEAKPROOF`
5208+
Leakproof(bool),
5209+
/// `[ EXTERNAL ] SECURITY { DEFINER | INVOKER }`
5210+
Security {
5211+
/// Whether the optional `EXTERNAL` keyword was present.
5212+
external: bool,
5213+
/// Security mode.
5214+
security: FunctionSecurity,
5215+
},
5216+
/// `PARALLEL { UNSAFE | RESTRICTED | SAFE }`
5217+
Parallel(FunctionParallel),
5218+
/// `COST execution_cost`
5219+
Cost(Expr),
5220+
/// `ROWS result_rows`
5221+
Rows(Expr),
5222+
/// `SUPPORT support_function`
5223+
Support(ObjectName),
5224+
/// `SET configuration_parameter { TO | = } { value | DEFAULT }`
5225+
/// or `SET configuration_parameter FROM CURRENT`
5226+
Set(FunctionDefinitionSetParam),
5227+
/// `RESET configuration_parameter` or `RESET ALL`
5228+
Reset(ResetConfig),
5229+
}
5230+
5231+
impl fmt::Display for AlterFunction {
5232+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
5233+
write!(f, "ALTER {} ", self.kind)?;
5234+
match self.kind {
5235+
AlterFunctionKind::Function => {
5236+
write!(f, "{} ", self.function)?;
5237+
}
5238+
AlterFunctionKind::Aggregate => {
5239+
write!(f, "{}(", self.function.name)?;
5240+
if self.aggregate_star {
5241+
write!(f, "*")?;
5242+
} else {
5243+
if let Some(args) = &self.function.args {
5244+
write!(f, "{}", display_comma_separated(args))?;
5245+
}
5246+
if let Some(order_by_args) = &self.aggregate_order_by {
5247+
if self
5248+
.function
5249+
.args
5250+
.as_ref()
5251+
.is_some_and(|args| !args.is_empty())
5252+
{
5253+
write!(f, " ")?;
5254+
}
5255+
write!(f, "ORDER BY {}", display_comma_separated(order_by_args))?;
5256+
}
5257+
}
5258+
write!(f, ") ")?;
5259+
}
5260+
}
5261+
write!(f, "{}", self.operation)
5262+
}
5263+
}
5264+
5265+
impl fmt::Display for AlterFunctionOperation {
5266+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
5267+
match self {
5268+
AlterFunctionOperation::RenameTo { new_name } => {
5269+
write!(f, "RENAME TO {new_name}")
5270+
}
5271+
AlterFunctionOperation::OwnerTo(owner) => write!(f, "OWNER TO {owner}"),
5272+
AlterFunctionOperation::SetSchema { schema_name } => {
5273+
write!(f, "SET SCHEMA {schema_name}")
5274+
}
5275+
AlterFunctionOperation::DependsOnExtension { no, extension_name } => {
5276+
if *no {
5277+
write!(f, "NO DEPENDS ON EXTENSION {extension_name}")
5278+
} else {
5279+
write!(f, "DEPENDS ON EXTENSION {extension_name}")
5280+
}
5281+
}
5282+
AlterFunctionOperation::Actions { actions, restrict } => {
5283+
write!(f, "{}", display_separated(actions, " "))?;
5284+
if *restrict {
5285+
write!(f, " RESTRICT")?;
5286+
}
5287+
Ok(())
5288+
}
5289+
}
5290+
}
5291+
}
5292+
5293+
impl fmt::Display for AlterFunctionAction {
5294+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
5295+
match self {
5296+
AlterFunctionAction::CalledOnNull(called_on_null) => write!(f, "{called_on_null}"),
5297+
AlterFunctionAction::Behavior(behavior) => write!(f, "{behavior}"),
5298+
AlterFunctionAction::Leakproof(leakproof) => {
5299+
if *leakproof {
5300+
write!(f, "LEAKPROOF")
5301+
} else {
5302+
write!(f, "NOT LEAKPROOF")
5303+
}
5304+
}
5305+
AlterFunctionAction::Security { external, security } => {
5306+
if *external {
5307+
write!(f, "EXTERNAL ")?;
5308+
}
5309+
write!(f, "{security}")
5310+
}
5311+
AlterFunctionAction::Parallel(parallel) => write!(f, "{parallel}"),
5312+
AlterFunctionAction::Cost(execution_cost) => write!(f, "COST {execution_cost}"),
5313+
AlterFunctionAction::Rows(result_rows) => write!(f, "ROWS {result_rows}"),
5314+
AlterFunctionAction::Support(support_function) => {
5315+
write!(f, "SUPPORT {support_function}")
5316+
}
5317+
AlterFunctionAction::Set(set_param) => write!(f, "{set_param}"),
5318+
AlterFunctionAction::Reset(reset_config) => match reset_config {
5319+
ResetConfig::ALL => write!(f, "RESET ALL"),
5320+
ResetConfig::ConfigName(name) => write!(f, "RESET {name}"),
5321+
},
5322+
}
5323+
}
5324+
}
5325+
5326+
impl Spanned for AlterFunction {
5327+
fn span(&self) -> Span {
5328+
Span::empty()
5329+
}
5330+
}
5331+
51245332
/// CREATE POLICY statement.
51255333
///
51265334
/// 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,
@@ -3739,6 +3740,13 @@ pub enum Statement {
37393740
with_options: Vec<SqlOption>,
37403741
},
37413742
/// ```sql
3743+
/// ALTER FUNCTION
3744+
/// ALTER AGGREGATE
3745+
/// ```
3746+
/// See [PostgreSQL](https://www.postgresql.org/docs/current/sql-alterfunction.html)
3747+
/// and [PostgreSQL](https://www.postgresql.org/docs/current/sql-alteraggregate.html)
3748+
AlterFunction(AlterFunction),
3749+
/// ```sql
37423750
/// ALTER TYPE
37433751
/// See [PostgreSQL](https://www.postgresql.org/docs/current/sql-altertype.html)
37443752
/// ```
@@ -5462,6 +5470,7 @@ impl fmt::Display for Statement {
54625470
}
54635471
write!(f, " AS {query}")
54645472
}
5473+
Statement::AlterFunction(alter_function) => write!(f, "{alter_function}"),
54655474
Statement::AlterType(AlterType { name, operation }) => {
54665475
write!(f, "ALTER TYPE {name} {operation}")
54675476
}
@@ -9687,6 +9696,8 @@ pub enum ArgMode {
96879696
Out,
96889697
/// `INOUT` mode.
96899698
InOut,
9699+
/// `VARIADIC` mode.
9700+
Variadic,
96909701
}
96919702

96929703
impl fmt::Display for ArgMode {
@@ -9695,6 +9706,7 @@ impl fmt::Display for ArgMode {
96959706
ArgMode::In => write!(f, "IN"),
96969707
ArgMode::Out => write!(f, "OUT"),
96979708
ArgMode::InOut => write!(f, "INOUT"),
9709+
ArgMode::Variadic => write!(f, "VARIADIC"),
96989710
}
96999711
}
97009712
}
@@ -9751,6 +9763,8 @@ impl fmt::Display for FunctionSecurity {
97519763
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
97529764
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
97539765
pub enum FunctionSetValue {
9766+
/// SET param = DEFAULT / SET param TO DEFAULT
9767+
Default,
97549768
/// SET param = value1, value2, ...
97559769
Values(Vec<Expr>),
97569770
/// SET param FROM CURRENT
@@ -9765,7 +9779,7 @@ pub enum FunctionSetValue {
97659779
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
97669780
pub struct FunctionDefinitionSetParam {
97679781
/// The name of the configuration parameter.
9768-
pub name: Ident,
9782+
pub name: ObjectName,
97699783
/// The value to set for the parameter.
97709784
pub value: FunctionSetValue,
97719785
}
@@ -9774,6 +9788,7 @@ impl fmt::Display for FunctionDefinitionSetParam {
97749788
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
97759789
write!(f, "SET {} ", self.name)?;
97769790
match &self.value {
9791+
FunctionSetValue::Default => write!(f, "= DEFAULT"),
97779792
FunctionSetValue::Values(values) => {
97789793
write!(f, "= {}", display_comma_separated(values))
97799794
}
@@ -11918,6 +11933,12 @@ impl From<AlterSchema> for Statement {
1191811933
}
1191911934
}
1192011935

11936+
impl From<AlterFunction> for Statement {
11937+
fn from(a: AlterFunction) -> Self {
11938+
Self::AlterFunction(a)
11939+
}
11940+
}
11941+
1192111942
impl From<AlterType> for Statement {
1192211943
fn from(a: AlterType) -> Self {
1192311944
Self::AlterType(a)

src/ast/spans.rs

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

src/keywords.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1127,6 +1127,7 @@ define_keywords!(
11271127
VARCHAR2,
11281128
VARIABLE,
11291129
VARIABLES,
1130+
VARIADIC,
11301131
VARYING,
11311132
VAR_POP,
11321133
VAR_SAMP,

0 commit comments

Comments
 (0)