Skip to content

Commit 6b4b2d8

Browse files
LucaCappelletti94ayman-sigma
authored andcommitted
Added support for ALTER OPERATOR syntax (apache#2114)
1 parent 0424012 commit 6b4b2d8

File tree

8 files changed

+585
-142
lines changed

8 files changed

+585
-142
lines changed

src/ast/ddl.rs

Lines changed: 103 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -995,6 +995,103 @@ impl fmt::Display for AlterTypeOperation {
995995
}
996996
}
997997

998+
/// `ALTER OPERATOR` statement
999+
/// See <https://www.postgresql.org/docs/current/sql-alteroperator.html>
1000+
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1001+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1002+
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1003+
pub struct AlterOperator {
1004+
/// Operator name (can be schema-qualified)
1005+
pub name: ObjectName,
1006+
/// Left operand type (`None` if no left operand)
1007+
pub left_type: Option<DataType>,
1008+
/// Right operand type
1009+
pub right_type: DataType,
1010+
/// The operation to perform
1011+
pub operation: AlterOperatorOperation,
1012+
}
1013+
1014+
/// An [AlterOperator] operation
1015+
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1016+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1017+
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1018+
pub enum AlterOperatorOperation {
1019+
/// `OWNER TO { new_owner | CURRENT_ROLE | CURRENT_USER | SESSION_USER }`
1020+
OwnerTo(Owner),
1021+
/// `SET SCHEMA new_schema`
1022+
SetSchema { schema_name: ObjectName },
1023+
/// `SET ( options )`
1024+
Set {
1025+
/// List of operator options to set
1026+
options: Vec<OperatorOption>,
1027+
},
1028+
}
1029+
1030+
/// Option for `ALTER OPERATOR SET` operation
1031+
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1032+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1033+
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1034+
pub enum OperatorOption {
1035+
/// `RESTRICT = { res_proc | NONE }`
1036+
Restrict(Option<ObjectName>),
1037+
/// `JOIN = { join_proc | NONE }`
1038+
Join(Option<ObjectName>),
1039+
/// `COMMUTATOR = com_op`
1040+
Commutator(ObjectName),
1041+
/// `NEGATOR = neg_op`
1042+
Negator(ObjectName),
1043+
/// `HASHES`
1044+
Hashes,
1045+
/// `MERGES`
1046+
Merges,
1047+
}
1048+
1049+
impl fmt::Display for AlterOperator {
1050+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1051+
write!(f, "ALTER OPERATOR {} (", self.name)?;
1052+
if let Some(left_type) = &self.left_type {
1053+
write!(f, "{}", left_type)?;
1054+
} else {
1055+
write!(f, "NONE")?;
1056+
}
1057+
write!(f, ", {}) {}", self.right_type, self.operation)
1058+
}
1059+
}
1060+
1061+
impl fmt::Display for AlterOperatorOperation {
1062+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1063+
match self {
1064+
Self::OwnerTo(owner) => write!(f, "OWNER TO {}", owner),
1065+
Self::SetSchema { schema_name } => write!(f, "SET SCHEMA {}", schema_name),
1066+
Self::Set { options } => {
1067+
write!(f, "SET (")?;
1068+
for (i, option) in options.iter().enumerate() {
1069+
if i > 0 {
1070+
write!(f, ", ")?;
1071+
}
1072+
write!(f, "{}", option)?;
1073+
}
1074+
write!(f, ")")
1075+
}
1076+
}
1077+
}
1078+
}
1079+
1080+
impl fmt::Display for OperatorOption {
1081+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1082+
match self {
1083+
Self::Restrict(Some(proc_name)) => write!(f, "RESTRICT = {}", proc_name),
1084+
Self::Restrict(None) => write!(f, "RESTRICT = NONE"),
1085+
Self::Join(Some(proc_name)) => write!(f, "JOIN = {}", proc_name),
1086+
Self::Join(None) => write!(f, "JOIN = NONE"),
1087+
Self::Commutator(op_name) => write!(f, "COMMUTATOR = {}", op_name),
1088+
Self::Negator(op_name) => write!(f, "NEGATOR = {}", op_name),
1089+
Self::Hashes => write!(f, "HASHES"),
1090+
Self::Merges => write!(f, "MERGES"),
1091+
}
1092+
}
1093+
}
1094+
9981095
/// An `ALTER COLUMN` (`Statement::AlterTable`) operation
9991096
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
10001097
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
@@ -1790,7 +1887,7 @@ impl fmt::Display for ColumnOption {
17901887
GeneratedAs::Always => "ALWAYS",
17911888
GeneratedAs::ByDefault => "BY DEFAULT",
17921889
// ExpStored goes with an expression, handled above
1793-
GeneratedAs::ExpStored => unreachable!(),
1890+
GeneratedAs::ExpStored => "",
17941891
};
17951892
write!(f, "GENERATED {when} AS IDENTITY")?;
17961893
if sequence_options.is_some() {
@@ -3981,18 +4078,8 @@ pub struct CreateOperator {
39814078
pub left_arg: Option<DataType>,
39824079
/// RIGHTARG parameter (right operand type)
39834080
pub right_arg: Option<DataType>,
3984-
/// COMMUTATOR parameter (commutator operator)
3985-
pub commutator: Option<ObjectName>,
3986-
/// NEGATOR parameter (negator operator)
3987-
pub negator: Option<ObjectName>,
3988-
/// RESTRICT parameter (restriction selectivity function)
3989-
pub restrict: Option<ObjectName>,
3990-
/// JOIN parameter (join selectivity function)
3991-
pub join: Option<ObjectName>,
3992-
/// HASHES flag
3993-
pub hashes: bool,
3994-
/// MERGES flag
3995-
pub merges: bool,
4081+
/// Operator options (COMMUTATOR, NEGATOR, RESTRICT, JOIN, HASHES, MERGES)
4082+
pub options: Vec<OperatorOption>,
39964083
}
39974084

39984085
/// CREATE OPERATOR FAMILY statement
@@ -4044,23 +4131,9 @@ impl fmt::Display for CreateOperator {
40444131
if let Some(right_arg) = &self.right_arg {
40454132
params.push(format!("RIGHTARG = {}", right_arg));
40464133
}
4047-
if let Some(commutator) = &self.commutator {
4048-
params.push(format!("COMMUTATOR = {}", commutator));
4049-
}
4050-
if let Some(negator) = &self.negator {
4051-
params.push(format!("NEGATOR = {}", negator));
4052-
}
4053-
if let Some(restrict) = &self.restrict {
4054-
params.push(format!("RESTRICT = {}", restrict));
4055-
}
4056-
if let Some(join) = &self.join {
4057-
params.push(format!("JOIN = {}", join));
4058-
}
4059-
if self.hashes {
4060-
params.push("HASHES".to_string());
4061-
}
4062-
if self.merges {
4063-
params.push("MERGES".to_string());
4134+
4135+
for option in &self.options {
4136+
params.push(option.to_string());
40644137
}
40654138

40664139
write!(f, "{}", params.join(", "))?;

src/ast/helpers/stmt_data_loading.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -99,15 +99,15 @@ impl fmt::Display for StageParamsObject {
9999

100100
impl fmt::Display for StageLoadSelectItem {
101101
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
102-
if self.alias.is_some() {
103-
write!(f, "{}.", self.alias.as_ref().unwrap())?;
102+
if let Some(alias) = &self.alias {
103+
write!(f, "{alias}.")?;
104104
}
105105
write!(f, "${}", self.file_col_num)?;
106-
if self.element.is_some() {
107-
write!(f, ":{}", self.element.as_ref().unwrap())?;
106+
if let Some(element) = &self.element {
107+
write!(f, ":{element}")?;
108108
}
109-
if self.item_as.is_some() {
110-
write!(f, " AS {}", self.item_as.as_ref().unwrap())?;
109+
if let Some(item_as) = &self.item_as {
110+
write!(f, " AS {item_as}")?;
111111
}
112112
Ok(())
113113
}

src/ast/mod.rs

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -59,23 +59,23 @@ pub use self::dcl::{
5959
AlterRoleOperation, CreateRole, ResetConfig, RoleOption, SecondaryRoles, SetConfigValue, Use,
6060
};
6161
pub use self::ddl::{
62-
Alignment, AlterColumnOperation, AlterConnectorOwner, AlterIndexOperation,
63-
AlterPolicyOperation, AlterSchema, AlterSchemaOperation, AlterTable, AlterTableAlgorithm,
64-
AlterTableLock, AlterTableOperation, AlterTableType, AlterType, AlterTypeAddValue,
65-
AlterTypeAddValuePosition, AlterTypeOperation, AlterTypeRename, AlterTypeRenameValue,
66-
ClusteredBy, ColumnDef, ColumnOption, ColumnOptionDef, ColumnOptions, ColumnPolicy,
67-
ColumnPolicyProperty, ConstraintCharacteristics, CreateConnector, CreateDomain,
62+
Alignment, AlterColumnOperation, AlterConnectorOwner, AlterIndexOperation, AlterOperator,
63+
AlterOperatorOperation, AlterPolicyOperation, AlterSchema, AlterSchemaOperation, AlterTable,
64+
AlterTableAlgorithm, AlterTableLock, AlterTableOperation, AlterTableType, AlterType,
65+
AlterTypeAddValue, AlterTypeAddValuePosition, AlterTypeOperation, AlterTypeRename,
66+
AlterTypeRenameValue, ClusteredBy, ColumnDef, ColumnOption, ColumnOptionDef, ColumnOptions,
67+
ColumnPolicy, ColumnPolicyProperty, ConstraintCharacteristics, CreateConnector, CreateDomain,
6868
CreateExtension, CreateFunction, CreateIndex, CreateOperator, CreateOperatorClass,
6969
CreateOperatorFamily, CreateTable, CreateTrigger, CreateView, Deduplicate, DeferrableInitial,
7070
DropBehavior, DropExtension, DropFunction, DropOperator, DropOperatorClass, DropOperatorFamily,
7171
DropOperatorSignature, DropTrigger, GeneratedAs, GeneratedExpressionMode, IdentityParameters,
7272
IdentityProperty, IdentityPropertyFormatKind, IdentityPropertyKind, IdentityPropertyOrder,
7373
IndexColumn, IndexOption, IndexType, KeyOrIndexDisplay, Msck, NullsDistinctOption,
74-
OperatorArgTypes, OperatorClassItem, OperatorPurpose, Owner, Partition, ProcedureParam,
75-
ReferentialAction, RenameTableNameKind, ReplicaIdentity, TagsColumnOption, TriggerObjectKind,
76-
Truncate, UserDefinedTypeCompositeAttributeDef, UserDefinedTypeInternalLength,
77-
UserDefinedTypeRangeOption, UserDefinedTypeRepresentation, UserDefinedTypeSqlDefinitionOption,
78-
UserDefinedTypeStorage, ViewColumnDef,
74+
OperatorArgTypes, OperatorClassItem, OperatorOption, OperatorPurpose, Owner, Partition,
75+
ProcedureParam, ReferentialAction, RenameTableNameKind, ReplicaIdentity, TagsColumnOption,
76+
TriggerObjectKind, Truncate, UserDefinedTypeCompositeAttributeDef,
77+
UserDefinedTypeInternalLength, UserDefinedTypeRangeOption, UserDefinedTypeRepresentation,
78+
UserDefinedTypeSqlDefinitionOption, UserDefinedTypeStorage, ViewColumnDef,
7979
};
8080
pub use self::dml::{Delete, Insert, Update};
8181
pub use self::operator::{BinaryOperator, UnaryOperator};
@@ -3430,6 +3430,11 @@ pub enum Statement {
34303430
/// ```
34313431
AlterType(AlterType),
34323432
/// ```sql
3433+
/// ALTER OPERATOR
3434+
/// ```
3435+
/// See [PostgreSQL](https://www.postgresql.org/docs/current/sql-alteroperator.html)
3436+
AlterOperator(AlterOperator),
3437+
/// ```sql
34333438
/// ALTER ROLE
34343439
/// ```
34353440
AlterRole {
@@ -5005,6 +5010,7 @@ impl fmt::Display for Statement {
50055010
Statement::AlterType(AlterType { name, operation }) => {
50065011
write!(f, "ALTER TYPE {name} {operation}")
50075012
}
5013+
Statement::AlterOperator(alter_operator) => write!(f, "{alter_operator}"),
50085014
Statement::AlterRole { name, operation } => {
50095015
write!(f, "ALTER ROLE {name} {operation}")
50105016
}
@@ -9848,8 +9854,8 @@ impl fmt::Display for ShowCharset {
98489854
} else {
98499855
write!(f, " CHARACTER SET")?;
98509856
}
9851-
if self.filter.is_some() {
9852-
write!(f, " {}", self.filter.as_ref().unwrap())?;
9857+
if let Some(filter) = &self.filter {
9858+
write!(f, " {filter}")?;
98539859
}
98549860
Ok(())
98559861
}

src/ast/spans.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,7 @@ impl Spanned for Values {
252252
/// - [Statement::CreateSecret]
253253
/// - [Statement::CreateRole]
254254
/// - [Statement::AlterType]
255+
/// - [Statement::AlterOperator]
255256
/// - [Statement::AlterRole]
256257
/// - [Statement::AttachDatabase]
257258
/// - [Statement::AttachDuckDBDatabase]
@@ -401,6 +402,7 @@ impl Spanned for Statement {
401402
),
402403
// These statements need to be implemented
403404
Statement::AlterType { .. } => Span::empty(),
405+
Statement::AlterOperator { .. } => Span::empty(),
404406
Statement::AlterRole { .. } => Span::empty(),
405407
Statement::AlterSession { .. } => Span::empty(),
406408
Statement::AttachDatabase { .. } => Span::empty(),

src/keywords.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,15 @@ macro_rules! define_keywords {
6767
pub const ALL_KEYWORDS: &[&str] = &[
6868
$($ident),*
6969
];
70+
71+
impl core::fmt::Display for Keyword {
72+
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
73+
match self {
74+
Keyword::NoKeyword => write!(f, "NoKeyword"),
75+
$(Keyword::$ident => write!(f, "{}", $ident),)*
76+
}
77+
}
78+
}
7079
};
7180
}
7281

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@
153153
// Splitting complex nodes (expressions, statements, types) into separate types
154154
// would bloat the API and hide intent. Extra memory is a worthwhile tradeoff.
155155
#![allow(clippy::large_enum_variant)]
156+
#![forbid(clippy::unreachable)]
156157
// TODO: Fix and remove this.
157158
#![expect(clippy::unnecessary_unwrap)]
158159

0 commit comments

Comments
 (0)