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
2 changes: 2 additions & 0 deletions fuzz/fuzz_seeds/postgres_alter_server.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ALTER SERVER s VERSION NULL OPTIONS (ADD host 'db', SET port '5432', DROP dbname);
ALTER SERVER s OWNER TO postgres
73 changes: 73 additions & 0 deletions src/ast/ddl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5036,6 +5036,73 @@ impl fmt::Display for AlterViewOperation {
}
}

/// `ALTER SERVER` statement.
///
/// [PostgreSQL](https://www.postgresql.org/docs/current/sql-alterserver.html)
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct AlterServer {
/// Name of the server being altered.
pub name: Ident,
/// The operation to perform on the server.
pub operation: AlterServerOperation,
}

/// Operations supported by `ALTER SERVER`.
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum AlterServerOperation {
/// Change the server version, its options, or both.
///
/// ```sql
/// ALTER SERVER name [ VERSION 'new_version' ] [ OPTIONS ( [ ADD | SET | DROP ] option ['value'] [, ...] ) ]
/// ```
Update {
/// The new version, `NULL` included.
version: Option<ValueWithSpan>,
/// The option changes, in source order.
options: Option<Vec<AlterGenericOption>>,
},
/// Change the server owner.
///
/// ```sql
/// ALTER SERVER name OWNER TO role_name
/// ```
OwnerTo(Owner),
/// Rename the server.
///
/// ```sql
/// ALTER SERVER name RENAME TO new_name
/// ```
RenameTo {
/// New server name.
new_name: Ident,
},
}

impl fmt::Display for AlterServerOperation {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
AlterServerOperation::Update { version, options } => {
if let Some(version) = version {
write!(f, "VERSION {version}")?;
if options.is_some() {
f.write_str(" ")?;
}
}
if let Some(options) = options {
write!(f, "OPTIONS ({})", display_comma_separated(options))?;
}
Ok(())
}
AlterServerOperation::OwnerTo(owner) => write!(f, "OWNER TO {owner}"),
AlterServerOperation::RenameTo { new_name } => write!(f, "RENAME TO {new_name}"),
}
}
}

impl fmt::Display for AlterView {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "ALTER VIEW ")?;
Expand All @@ -5046,6 +5113,12 @@ impl fmt::Display for AlterView {
}
}

impl fmt::Display for AlterServer {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "ALTER SERVER {} {}", self.name, self.operation)
}
}

/// Table type for ALTER TABLE statements.
/// Used to distinguish between regular tables, Iceberg tables, and Dynamic tables.
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
Expand Down
38 changes: 25 additions & 13 deletions src/ast/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,19 +68,19 @@ pub use self::ddl::{
AlterFunctionOperation, AlterGenericOption, AlterIndexOperation, AlterOperator,
AlterOperatorClass, AlterOperatorClassOperation, AlterOperatorFamily,
AlterOperatorFamilyOperation, AlterOperatorOperation, AlterPolicy, AlterPolicyOperation,
AlterSchema, AlterSchemaOperation, AlterTable, AlterTableAlgorithm, AlterTableLock,
AlterTableOperation, AlterTableType, AlterTextSearch, AlterTextSearchOperation,
AlterTextSearchOption, AlterTrigger, AlterTriggerOperation, AlterType, AlterTypeAddValue,
AlterTypeAddValuePosition, AlterTypeOperation, AlterTypeRename, AlterTypeRenameValue,
AlterView, AlterViewOperation, ClusteredBy, ColumnDef, ColumnOption, ColumnOptionDef,
ColumnOptions, ColumnPolicy, ColumnPolicyProperty, ConstraintCharacteristics, CreateAggregate,
CreateAggregateArgs, CreateAggregateOption, CreateCollation, CreateCollationDefinition,
CreateConnector, CreateDomain, CreateExtension, CreateForeignDataWrapper, CreateForeignTable,
CreateFunction, CreateIndex, CreateOperator, CreateOperatorClass, CreateOperatorFamily,
CreatePolicy, CreatePolicyCommand, CreatePolicyType, CreateRule, CreateRuleAction,
CreateRuleDoKind, CreateRuleEvent, CreateTable, CreateTextSearch, CreateTrigger,
CreateUserMapping, CreateView, Deduplicate, DeferrableInitial, DistStyle, DropBehavior,
DropExtension, DropFunction, DropOperator, DropOperatorClass, DropOperatorFamily,
AlterSchema, AlterSchemaOperation, AlterServer, AlterServerOperation, AlterTable,
AlterTableAlgorithm, AlterTableLock, AlterTableOperation, AlterTableType, AlterTextSearch,
AlterTextSearchOperation, AlterTextSearchOption, AlterTrigger, AlterTriggerOperation,
AlterType, AlterTypeAddValue, AlterTypeAddValuePosition, AlterTypeOperation, AlterTypeRename,
AlterTypeRenameValue, AlterView, AlterViewOperation, ClusteredBy, ColumnDef, ColumnOption,
ColumnOptionDef, ColumnOptions, ColumnPolicy, ColumnPolicyProperty, ConstraintCharacteristics,
CreateAggregate, CreateAggregateArgs, CreateAggregateOption, CreateCollation,
CreateCollationDefinition, CreateConnector, CreateDomain, CreateExtension,
CreateForeignDataWrapper, CreateForeignTable, CreateFunction, CreateIndex, CreateOperator,
CreateOperatorClass, CreateOperatorFamily, CreatePolicy, CreatePolicyCommand, CreatePolicyType,
CreateRule, CreateRuleAction, CreateRuleDoKind, CreateRuleEvent, CreateTable, CreateTextSearch,
CreateTrigger, CreateUserMapping, CreateView, Deduplicate, DeferrableInitial, DistStyle,
DropBehavior, DropExtension, DropFunction, DropOperator, DropOperatorClass, DropOperatorFamily,
DropOperatorSignature, DropPolicy, DropRule, DropTrigger, ForValues,
ForeignDataWrapperRoutineClause, FunctionReturnType, GeneratedAs, GeneratedExpressionMode,
IdentityParameters, IdentityProperty, IdentityPropertyFormatKind, IdentityPropertyKind,
Expand Down Expand Up @@ -3932,6 +3932,11 @@ pub enum Statement {
/// See [PostgreSQL](https://www.postgresql.org/docs/current/sql-altercollation.html)
AlterCollation(AlterCollation),
/// ```sql
/// ALTER SERVER
/// ```
/// See [PostgreSQL](https://www.postgresql.org/docs/current/sql-alterserver.html)
AlterServer(AlterServer),
/// ```sql
/// ALTER OPERATOR
/// ```
/// See [PostgreSQL](https://www.postgresql.org/docs/current/sql-alteroperator.html)
Expand Down Expand Up @@ -5759,6 +5764,7 @@ impl fmt::Display for Statement {
write!(f, "ALTER TYPE {name} {operation}")
}
Statement::AlterCollation(alter_collation) => write!(f, "{alter_collation}"),
Statement::AlterServer(alter_server) => write!(f, "{alter_server}"),
Statement::AlterOperator(alter_operator) => write!(f, "{alter_operator}"),
Statement::AlterOperatorFamily(alter_operator_family) => {
write!(f, "{alter_operator_family}")
Expand Down Expand Up @@ -12679,6 +12685,12 @@ impl From<AlterView> for Statement {
}
}

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

impl From<AlterOperator> for Statement {
fn from(a: AlterOperator) -> Self {
Self::AlterOperator(a)
Expand Down
62 changes: 40 additions & 22 deletions src/ast/spans.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,28 +29,28 @@ use crate::tokenizer::Span;

use super::{
comments, dcl::SecondaryRoles, value::ValueWithSpan, AccessExpr, AlterColumnOperation,
AlterGenericOption, AlterIndexOperation, AlterTableOperation, AlterTrigger,
AlterTriggerOperation, AlterView, AlterViewOperation, Analyze, Array, Assignment,
AssignmentTarget, AttachedToken, BeginEndStatements, CaseStatement, CloseCursor,
ClusteredIndex, ColumnDef, ColumnOption, ColumnOptionDef, ConditionalStatementBlock,
ConditionalStatements, ConflictTarget, ConnectByKind, ConstraintCharacteristics, CopySource,
CreateIndex, CreateRule, CreateRuleAction, CreateTable, CreateTableOptions, CreateUserMapping,
Cte, Delete, DoUpdate, DropRule, ExceptSelectItem, ExcludeConstraintElement, ExcludeSelectItem,
Expr, ExprWithAlias, Fetch, ForValues, FromTable, Function, FunctionArg, FunctionArgExpr,
FunctionArgumentClause, FunctionArgumentList, FunctionArguments, GroupByExpr, HavingBound,
IfStatement, IlikeSelectItem, InTarget, IndexColumn, Insert, Interpolate, InterpolateExpr,
Join, JoinConstraint, JoinOperator, JsonPath, JsonPathElem, LateralView, LimitClause,
MatchRecognizePattern, Measure, Merge, MergeAction, MergeClause, MergeInsertExpr,
MergeInsertKind, MergeUpdateExpr, MergeUpdateKind, NamedParenthesizedList,
NamedWindowDefinition, ObjectName, ObjectNamePart, Offset, OnConflict, OnConflictAction,
OnInsert, OpenStatement, OperateFunctionArg, OrderBy, OrderByExpr, OrderByKind, OutputClause,
Parens, Partition, PartitionBoundValue, PivotValueSource, ProjectionSelect, Query,
RaiseStatement, RaiseStatementValue, ReferentialAction, RefreshMaterializedView,
RenameSelectItem, ReplaceSelectElement, ReplaceSelectItem, Select, SelectInto, SelectItem,
SetExpr, Setting, SqlOption, Statement, Subscript, SymbolDefinition, TableAlias,
TableAliasColumnDef, TableConstraint, TableFactor, TableObject, TableOptionsClustered,
TableWithJoins, Update, UpdateTableFromKind, Use, UserMappingUser, Values, ViewColumnDef,
WhileStatement, WildcardAdditionalOptions, With, WithFill,
AlterGenericOption, AlterIndexOperation, AlterServer, AlterServerOperation,
AlterTableOperation, AlterTrigger, AlterTriggerOperation, AlterView, AlterViewOperation,
Analyze, Array, Assignment, AssignmentTarget, AttachedToken, BeginEndStatements, CaseStatement,
CloseCursor, ClusteredIndex, ColumnDef, ColumnOption, ColumnOptionDef,
ConditionalStatementBlock, ConditionalStatements, ConflictTarget, ConnectByKind,
ConstraintCharacteristics, CopySource, CreateIndex, CreateRule, CreateRuleAction, CreateTable,
CreateTableOptions, CreateUserMapping, Cte, Delete, DoUpdate, DropRule, ExceptSelectItem,
ExcludeConstraintElement, ExcludeSelectItem, Expr, ExprWithAlias, Fetch, ForValues, FromTable,
Function, FunctionArg, FunctionArgExpr, FunctionArgumentClause, FunctionArgumentList,
FunctionArguments, GroupByExpr, HavingBound, IfStatement, IlikeSelectItem, InTarget,
IndexColumn, Insert, Interpolate, InterpolateExpr, Join, JoinConstraint, JoinOperator,
JsonPath, JsonPathElem, LateralView, LimitClause, MatchRecognizePattern, Measure, Merge,
MergeAction, MergeClause, MergeInsertExpr, MergeInsertKind, MergeUpdateExpr, MergeUpdateKind,
NamedParenthesizedList, NamedWindowDefinition, ObjectName, ObjectNamePart, Offset, OnConflict,
OnConflictAction, OnInsert, OpenStatement, OperateFunctionArg, OrderBy, OrderByExpr,
OrderByKind, OutputClause, Parens, Partition, PartitionBoundValue, PivotValueSource,
ProjectionSelect, Query, RaiseStatement, RaiseStatementValue, ReferentialAction,
RefreshMaterializedView, RenameSelectItem, ReplaceSelectElement, ReplaceSelectItem, Select,
SelectInto, SelectItem, SetExpr, Setting, SqlOption, Statement, Subscript, SymbolDefinition,
TableAlias, TableAliasColumnDef, TableConstraint, TableFactor, TableObject,
TableOptionsClustered, TableWithJoins, Update, UpdateTableFromKind, Use, UserMappingUser,
Values, ViewColumnDef, WhileStatement, WildcardAdditionalOptions, With, WithFill,
};

/// Given an iterator of spans, return the [Span::union] of all spans.
Expand Down Expand Up @@ -416,6 +416,7 @@ impl Spanned for Statement {
Statement::AlterFunction { .. } => Span::empty(),
Statement::AlterType { .. } => Span::empty(),
Statement::AlterCollation { .. } => Span::empty(),
Statement::AlterServer(alter_server) => alter_server.span(),
Statement::AlterOperator { .. } => Span::empty(),
Statement::AlterOperatorFamily { .. } => Span::empty(),
Statement::AlterOperatorClass { .. } => Span::empty(),
Expand Down Expand Up @@ -2862,6 +2863,23 @@ impl Spanned for CreateUserMapping {
}
}

impl Spanned for AlterServer {
fn span(&self) -> Span {
let operation = match &self.operation {
AlterServerOperation::Update { version, options } => Span::union_iter(
version
.iter()
.map(|version| version.span)
.chain(options.iter().flatten().map(|option| option.span())),
),
AlterServerOperation::OwnerTo(Owner::Ident(owner)) => owner.span,
AlterServerOperation::OwnerTo(_) => Span::empty(),
AlterServerOperation::RenameTo { new_name } => new_name.span,
};
self.name.span.union(&operation)
}
}

#[cfg(test)]
pub mod tests {
use crate::ast::Value;
Expand Down
37 changes: 36 additions & 1 deletion src/parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11923,14 +11923,15 @@ impl<'a> Parser<'a> {
Keyword::POLICY => self.parse_alter_policy().map(Into::into),
Keyword::TRIGGER => self.parse_alter_trigger().map(Into::into),
Keyword::CONNECTOR => self.parse_alter_connector(),
Keyword::SERVER => self.parse_alter_server().map(Into::into),
Keyword::USER if self.dialect.supports_alter_user_as_alter_role() => {
self.parse_alter_role()
}
Keyword::USER => self.parse_alter_user().map(Into::into),
_ => {
self.index = index;
self.expected_ref(
"one of VIEW or TYPE or COLLATION or TABLE or INDEX or FUNCTION or AGGREGATE or ROLE or POLICY or TRIGGER or CONNECTOR or ICEBERG or FOREIGN TABLE or SCHEMA or USER or OPERATOR",
"one of VIEW or TYPE or COLLATION or TABLE or INDEX or FUNCTION or AGGREGATE or ROLE or POLICY or TRIGGER or CONNECTOR or ICEBERG or FOREIGN TABLE or SCHEMA or SERVER or USER or OPERATOR",
self.peek_token_ref(),
)
}
Expand Down Expand Up @@ -12362,6 +12363,40 @@ impl<'a> Parser<'a> {
Ok(AlterCollation { name, operation })
}

/// Parse a [Statement::AlterServer].
///
/// [PostgreSQL Documentation](https://www.postgresql.org/docs/current/sql-alterserver.html)
pub fn parse_alter_server(&mut self) -> Result<AlterServer, ParserError> {
let name = self.parse_identifier()?;
let operation = if self.parse_keywords(&[Keyword::RENAME, Keyword::TO]) {
AlterServerOperation::RenameTo {
new_name: self.parse_identifier()?,
}
} else if self.parse_keywords(&[Keyword::OWNER, Keyword::TO]) {
AlterServerOperation::OwnerTo(self.parse_owner()?)
} else {
let version = if self.parse_keyword(Keyword::VERSION) {
Some(self.parse_value()?)
} else {
None
};
let options = if self.parse_keyword(Keyword::OPTIONS) {
Some(self.parse_alter_generic_options()?)
} else {
None
};
if version.is_none() && options.is_none() {
return self.expected_ref(
"VERSION, OPTIONS, OWNER TO, or RENAME TO after ALTER SERVER",
self.peek_token_ref(),
);
}
AlterServerOperation::Update { version, options }
};

Ok(AlterServer { name, operation })
}

/// Parse a [Statement::AlterOperator]
///
/// [PostgreSQL Documentation](https://www.postgresql.org/docs/current/sql-alteroperator.html)
Expand Down
2 changes: 1 addition & 1 deletion tests/sqlparser_common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16193,7 +16193,7 @@ fn parse_alter_trigger_spans() {

#[test]
fn parse_alter_rejects_missing_or_unknown_object_type() {
let objects = "one of VIEW or TYPE or COLLATION or TABLE or INDEX or FUNCTION or AGGREGATE or ROLE or POLICY or TRIGGER or CONNECTOR or ICEBERG or FOREIGN TABLE or SCHEMA or USER or OPERATOR";
let objects = "one of VIEW or TYPE or COLLATION or TABLE or INDEX or FUNCTION or AGGREGATE or ROLE or POLICY or TRIGGER or CONNECTOR or ICEBERG or FOREIGN TABLE or SCHEMA or SERVER or USER or OPERATOR";
for (sql, found) in [
("ALTER", "EOF"),
("ALTER 1", "1"),
Expand Down
Loading
Loading