Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
216 changes: 212 additions & 4 deletions src/ast/ddl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,10 @@ use crate::ast::{
FunctionDeterminismSpecifier, FunctionParallel, FunctionSecurity, HiveDistributionStyle,
HiveFormat, HiveIOFormat, HiveRowFormat, HiveSetLocation, Ident, InitializeKind,
MySQLColumnPosition, ObjectName, OnCommit, OneOrManyWithParens, OperateFunctionArg,
OrderByExpr, ProjectionSelect, Query, RefreshModeKind, RowAccessPolicy, SequenceOptions,
Spanned, SqlOption, StorageSerializationPolicy, TableVersion, Tag, TriggerEvent,
TriggerExecBody, TriggerObject, TriggerPeriod, TriggerReferencing, Value, ValueWithSpan,
WrappedCollection,
OrderByExpr, ProjectionSelect, Query, RefreshModeKind, ResetConfig, RowAccessPolicy,
SequenceOptions, Spanned, SqlOption, StorageSerializationPolicy, TableVersion, Tag,
TriggerEvent, TriggerExecBody, TriggerObject, TriggerPeriod, TriggerReferencing, Value,
ValueWithSpan, WrappedCollection,
};
use crate::display_utils::{DisplayCommaSeparated, Indent, NewLine, SpaceOrNewline};
use crate::keywords::Keyword;
Expand Down Expand Up @@ -5121,6 +5121,214 @@ impl Spanned for AlterOperatorClass {
}
}

/// `ALTER FUNCTION` / `ALTER AGGREGATE` statement.
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct AlterFunction {
/// Object type being altered.
pub kind: AlterFunctionKind,
/// Function or aggregate signature.
pub function: FunctionDesc,
/// `ORDER BY` argument list for aggregate signatures.
///
/// This is only used for `ALTER AGGREGATE`.
pub aggregate_order_by: Option<Vec<OperateFunctionArg>>,
/// Whether the aggregate signature uses `*`.
///
/// This is only used for `ALTER AGGREGATE`.
pub aggregate_star: bool,
/// Operation applied to the object.
pub operation: AlterFunctionOperation,
}

/// Function-like object type used by [`AlterFunction`].
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum AlterFunctionKind {
/// `FUNCTION`
Function,
/// `AGGREGATE`
Aggregate,
}

impl fmt::Display for AlterFunctionKind {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Self::Function => write!(f, "FUNCTION"),
Self::Aggregate => write!(f, "AGGREGATE"),
}
}
}

/// Operation for `ALTER FUNCTION` / `ALTER AGGREGATE`.
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum AlterFunctionOperation {
/// `RENAME TO new_name`
RenameTo {
/// New unqualified function or aggregate name.
new_name: Ident,
},
/// `OWNER TO { new_owner | CURRENT_ROLE | CURRENT_USER | SESSION_USER }`
OwnerTo(Owner),
/// `SET SCHEMA schema_name`
SetSchema {
/// The target schema name.
schema_name: ObjectName,
},
/// `[ NO ] DEPENDS ON EXTENSION extension_name`
DependsOnExtension {
/// `true` when `NO DEPENDS ON EXTENSION`.
no: bool,
/// Extension name.
extension_name: ObjectName,
},
/// `action [ ... ] [ RESTRICT ]` (function only).
Actions {
/// One or more function actions.
actions: Vec<AlterFunctionAction>,
/// Whether `RESTRICT` is present.
restrict: bool,
},
}

/// Function action in `ALTER FUNCTION ... action [ ... ] [ RESTRICT ]`.
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum AlterFunctionAction {
/// `CALLED ON NULL INPUT` / `RETURNS NULL ON NULL INPUT` / `STRICT`
CalledOnNull(FunctionCalledOnNull),
/// `IMMUTABLE` / `STABLE` / `VOLATILE`
Behavior(FunctionBehavior),
/// `[ NOT ] LEAKPROOF`
Leakproof(bool),
/// `[ EXTERNAL ] SECURITY { DEFINER | INVOKER }`
Security {
/// Whether the optional `EXTERNAL` keyword was present.
external: bool,
/// Security mode.
security: FunctionSecurity,
},
/// `PARALLEL { UNSAFE | RESTRICTED | SAFE }`
Parallel(FunctionParallel),
/// `COST execution_cost`
Cost(Expr),
/// `ROWS result_rows`
Rows(Expr),
/// `SUPPORT support_function`
Support(ObjectName),
/// `SET configuration_parameter { TO | = } { value | DEFAULT }`
/// or `SET configuration_parameter FROM CURRENT`
Set(FunctionDefinitionSetParam),
/// `RESET configuration_parameter` or `RESET ALL`
Reset(ResetConfig),
}

impl fmt::Display for AlterFunction {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "ALTER {} ", self.kind)?;
match self.kind {
AlterFunctionKind::Function => {
write!(f, "{} ", self.function)?;
}
AlterFunctionKind::Aggregate => {
write!(f, "{}(", self.function.name)?;
if self.aggregate_star {
write!(f, "*")?;
} else {
if let Some(args) = &self.function.args {
write!(f, "{}", display_comma_separated(args))?;
}
if let Some(order_by_args) = &self.aggregate_order_by {
if self
.function
.args
.as_ref()
.is_some_and(|args| !args.is_empty())
{
write!(f, " ")?;
}
write!(f, "ORDER BY {}", display_comma_separated(order_by_args))?;
}
}
write!(f, ") ")?;
}
}
write!(f, "{}", self.operation)
}
}

impl fmt::Display for AlterFunctionOperation {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
AlterFunctionOperation::RenameTo { new_name } => {
write!(f, "RENAME TO {new_name}")
}
AlterFunctionOperation::OwnerTo(owner) => write!(f, "OWNER TO {owner}"),
AlterFunctionOperation::SetSchema { schema_name } => {
write!(f, "SET SCHEMA {schema_name}")
}
AlterFunctionOperation::DependsOnExtension { no, extension_name } => {
if *no {
write!(f, "NO DEPENDS ON EXTENSION {extension_name}")
} else {
write!(f, "DEPENDS ON EXTENSION {extension_name}")
}
}
AlterFunctionOperation::Actions { actions, restrict } => {
write!(f, "{}", display_separated(actions, " "))?;
if *restrict {
write!(f, " RESTRICT")?;
}
Ok(())
}
}
}
}

impl fmt::Display for AlterFunctionAction {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
AlterFunctionAction::CalledOnNull(called_on_null) => write!(f, "{called_on_null}"),
AlterFunctionAction::Behavior(behavior) => write!(f, "{behavior}"),
AlterFunctionAction::Leakproof(leakproof) => {
if *leakproof {
write!(f, "LEAKPROOF")
} else {
write!(f, "NOT LEAKPROOF")
}
}
AlterFunctionAction::Security { external, security } => {
if *external {
write!(f, "EXTERNAL ")?;
}
write!(f, "{security}")
}
AlterFunctionAction::Parallel(parallel) => write!(f, "{parallel}"),
AlterFunctionAction::Cost(execution_cost) => write!(f, "COST {execution_cost}"),
AlterFunctionAction::Rows(result_rows) => write!(f, "ROWS {result_rows}"),
AlterFunctionAction::Support(support_function) => {
write!(f, "SUPPORT {support_function}")
}
AlterFunctionAction::Set(set_param) => write!(f, "{set_param}"),
AlterFunctionAction::Reset(reset_config) => match reset_config {
ResetConfig::ALL => write!(f, "RESET ALL"),
ResetConfig::ConfigName(name) => write!(f, "RESET {name}"),
},
}
}
}

impl Spanned for AlterFunction {
fn span(&self) -> Span {
Span::empty()
}
}

/// CREATE POLICY statement.
///
/// See [PostgreSQL](https://www.postgresql.org/docs/current/sql-createpolicy.html)
Expand Down
25 changes: 23 additions & 2 deletions src/ast/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@ pub use self::dcl::{
SetConfigValue, Use,
};
pub use self::ddl::{
Alignment, AlterColumnOperation, AlterConnectorOwner, AlterIndexOperation, AlterOperator,
Alignment, AlterColumnOperation, AlterConnectorOwner, AlterFunction, AlterFunctionAction,
AlterFunctionKind, AlterFunctionOperation, AlterIndexOperation, AlterOperator,
AlterOperatorClass, AlterOperatorClassOperation, AlterOperatorFamily,
AlterOperatorFamilyOperation, AlterOperatorOperation, AlterPolicy, AlterPolicyOperation,
AlterSchema, AlterSchemaOperation, AlterTable, AlterTableAlgorithm, AlterTableLock,
Expand Down Expand Up @@ -3739,6 +3740,13 @@ pub enum Statement {
with_options: Vec<SqlOption>,
},
/// ```sql
/// ALTER FUNCTION
/// ALTER AGGREGATE
/// ```
/// See [PostgreSQL](https://www.postgresql.org/docs/current/sql-alterfunction.html)
/// and [PostgreSQL](https://www.postgresql.org/docs/current/sql-alteraggregate.html)
AlterFunction(AlterFunction),
/// ```sql
/// ALTER TYPE
/// See [PostgreSQL](https://www.postgresql.org/docs/current/sql-altertype.html)
/// ```
Expand Down Expand Up @@ -5462,6 +5470,7 @@ impl fmt::Display for Statement {
}
write!(f, " AS {query}")
}
Statement::AlterFunction(alter_function) => write!(f, "{alter_function}"),
Statement::AlterType(AlterType { name, operation }) => {
write!(f, "ALTER TYPE {name} {operation}")
}
Expand Down Expand Up @@ -9687,6 +9696,8 @@ pub enum ArgMode {
Out,
/// `INOUT` mode.
InOut,
/// `VARIADIC` mode.
Variadic,
}

impl fmt::Display for ArgMode {
Expand All @@ -9695,6 +9706,7 @@ impl fmt::Display for ArgMode {
ArgMode::In => write!(f, "IN"),
ArgMode::Out => write!(f, "OUT"),
ArgMode::InOut => write!(f, "INOUT"),
ArgMode::Variadic => write!(f, "VARIADIC"),
}
}
}
Expand Down Expand Up @@ -9751,6 +9763,8 @@ impl fmt::Display for FunctionSecurity {
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum FunctionSetValue {
/// SET param = DEFAULT / SET param TO DEFAULT
Default,
/// SET param = value1, value2, ...
Values(Vec<Expr>),
/// SET param FROM CURRENT
Expand All @@ -9765,7 +9779,7 @@ pub enum FunctionSetValue {
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct FunctionDefinitionSetParam {
/// The name of the configuration parameter.
pub name: Ident,
pub name: ObjectName,
/// The value to set for the parameter.
pub value: FunctionSetValue,
}
Expand All @@ -9774,6 +9788,7 @@ impl fmt::Display for FunctionDefinitionSetParam {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "SET {} ", self.name)?;
match &self.value {
FunctionSetValue::Default => write!(f, "= DEFAULT"),
FunctionSetValue::Values(values) => {
write!(f, "= {}", display_comma_separated(values))
}
Expand Down Expand Up @@ -11918,6 +11933,12 @@ impl From<AlterSchema> for Statement {
}
}

impl From<AlterFunction> for Statement {
fn from(a: AlterFunction) -> Self {
Self::AlterFunction(a)
}
}

impl From<AlterType> for Statement {
fn from(a: AlterType) -> Self {
Self::AlterType(a)
Expand Down
1 change: 1 addition & 0 deletions src/ast/spans.rs
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,7 @@ impl Spanned for Statement {
.chain(with_options.iter().map(|i| i.span())),
),
// These statements need to be implemented
Statement::AlterFunction { .. } => Span::empty(),
Statement::AlterType { .. } => Span::empty(),
Statement::AlterOperator { .. } => Span::empty(),
Statement::AlterOperatorFamily { .. } => Span::empty(),
Expand Down
1 change: 1 addition & 0 deletions src/keywords.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1127,6 +1127,7 @@ define_keywords!(
VARCHAR2,
VARIABLE,
VARIABLES,
VARIADIC,
VARYING,
VAR_POP,
VAR_SAMP,
Expand Down
Loading