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
1 change: 1 addition & 0 deletions fuzz/fuzz_seeds/postgres_alter_foreign_table.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER FOREIGN TABLE IF EXISTS ONLY public.ft OWNER TO app, OPTIONS (ADD fetch_size '100', SET batch_size '10', DROP updatable), ALTER COLUMN id OPTIONS (column_name 'remote_id')
65 changes: 65 additions & 0 deletions src/ast/ddl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -560,6 +560,14 @@ pub enum AlterTableOperation {
/// Parenthesized options supplied to `SET (...)`.
options: Vec<SqlOption>,
},
/// `OPTIONS ( [ ADD | SET | DROP ] option ['value'] [, ...] )`, changing the
/// options of a foreign table.
///
/// [PostgreSQL](https://www.postgresql.org/docs/current/sql-alterforeigntable.html)
GenericOptions {
/// The option changes, in source order.
options: Vec<AlterGenericOption>,
},
}

/// An `ALTER Policy` (`Statement::AlterPolicy`) operation
Expand Down Expand Up @@ -1122,6 +1130,9 @@ impl fmt::Display for AlterTableOperation {
AlterTableOperation::SetOptionsParens { options } => {
write!(f, "SET ({})", display_comma_separated(options))
}
AlterTableOperation::GenericOptions { options } => {
write!(f, "OPTIONS ({})", display_comma_separated(options))
}
}
}
}
Expand Down Expand Up @@ -1375,6 +1386,14 @@ pub enum AlterColumnOperation {
/// Optional sequence options for identity generation.
sequence_options: Option<Vec<SequenceOptions>>,
},
/// `OPTIONS ( [ ADD | SET | DROP ] option ['value'] [, ...] )`, changing the
/// options of a foreign table column.
///
/// [PostgreSQL](https://www.postgresql.org/docs/current/sql-alterforeigntable.html)
GenericOptions {
/// The option changes, in source order.
options: Vec<AlterGenericOption>,
},
}

impl fmt::Display for AlterColumnOperation {
Expand Down Expand Up @@ -1424,6 +1443,48 @@ impl fmt::Display for AlterColumnOperation {
}
Ok(())
}
AlterColumnOperation::GenericOptions { options } => {
write!(f, "OPTIONS ({})", display_comma_separated(options))
}
}
}
}

/// An element of a PostgreSQL `OPTIONS ( [ ADD | SET | DROP ] option ['value'] [, ...] )`
/// list in an `ALTER` statement.
///
/// [PostgreSQL](https://www.postgresql.org/docs/current/sql-alterforeigntable.html)
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum AlterGenericOption {
/// `[ ADD ] option 'value'`, which fails if the option is already set.
Add {
/// The option to add.
option: CreateServerOption,
/// Whether the `ADD` keyword was written.
add_keyword: bool,
},
/// `SET option 'value'`, which fails if the option is not set.
Set(CreateServerOption),
/// `DROP option`
Drop(Ident),
}

impl fmt::Display for AlterGenericOption {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
AlterGenericOption::Add {
option,
add_keyword,
} => {
if *add_keyword {
f.write_str("ADD ")?;
}
write!(f, "{option}")
}
AlterGenericOption::Set(option) => write!(f, "SET {option}"),
AlterGenericOption::Drop(key) => write!(f, "DROP {key}"),
}
}
}
Expand Down Expand Up @@ -4840,6 +4901,9 @@ pub enum AlterTableType {
/// External table type
/// <https://docs.snowflake.com/en/sql-reference/sql/alter-external-table>
External,
/// Foreign table type
/// <https://www.postgresql.org/docs/current/sql-alterforeigntable.html>
Foreign,
}

/// ALTER TABLE statement
Expand Down Expand Up @@ -4874,6 +4938,7 @@ impl fmt::Display for AlterTable {
Some(AlterTableType::Iceberg) => write!(f, "ALTER ICEBERG TABLE ")?,
Some(AlterTableType::Dynamic) => write!(f, "ALTER DYNAMIC TABLE ")?,
Some(AlterTableType::External) => write!(f, "ALTER EXTERNAL TABLE ")?,
Some(AlterTableType::Foreign) => write!(f, "ALTER FOREIGN TABLE ")?,
None => write!(f, "ALTER TABLE ")?,
}

Expand Down
45 changes: 23 additions & 22 deletions src/ast/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,28 +65,29 @@ pub use self::dcl::{
pub use self::ddl::{
AggregateModifyKind, Alignment, AlterCollation, AlterCollationOperation, AlterColumnOperation,
AlterConnectorOwner, AlterFunction, AlterFunctionAction, AlterFunctionKind,
AlterFunctionOperation, 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, 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, CreateView, Deduplicate, DeferrableInitial, DistStyle, DropBehavior,
DropExtension, DropFunction, DropOperator, DropOperatorClass, DropOperatorFamily,
DropOperatorSignature, DropPolicy, DropTrigger, ForValues, ForeignDataWrapperRoutineClause,
FunctionReturnType, GeneratedAs, GeneratedExpressionMode, IdentityParameters, IdentityProperty,
IdentityPropertyFormatKind, IdentityPropertyKind, IdentityPropertyOrder, IndexColumn,
IndexOption, IndexType, KeyOrIndexDisplay, Msck, NullsDistinctOption, OperatorArgTypes,
OperatorClassItem, OperatorFamilyDropItem, OperatorFamilyItem, OperatorOption, OperatorPurpose,
Owner, Partition, PartitionBoundValue, ProcedureParam, ReferentialAction, RenameTableNameKind,
ReplicaIdentity, SqliteTableOption, SqliteTableOptions, TagsColumnOption, TextSearchObjectType,
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,
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, CreateView, Deduplicate,
DeferrableInitial, DistStyle, DropBehavior, DropExtension, DropFunction, DropOperator,
DropOperatorClass, DropOperatorFamily, DropOperatorSignature, DropPolicy, DropTrigger,
ForValues, ForeignDataWrapperRoutineClause, FunctionReturnType, GeneratedAs,
GeneratedExpressionMode, IdentityParameters, IdentityProperty, IdentityPropertyFormatKind,
IdentityPropertyKind, IdentityPropertyOrder, IndexColumn, IndexOption, IndexType,
KeyOrIndexDisplay, Msck, NullsDistinctOption, OperatorArgTypes, OperatorClassItem,
OperatorFamilyDropItem, OperatorFamilyItem, OperatorOption, OperatorPurpose, Owner, Partition,
PartitionBoundValue, ProcedureParam, ReferentialAction, RenameTableNameKind, ReplicaIdentity,
SqliteTableOption, SqliteTableOptions, TagsColumnOption, TextSearchObjectType,
TriggerObjectKind, Truncate, UserDefinedTypeCompositeAttributeDef,
UserDefinedTypeInternalLength, UserDefinedTypeRangeOption, UserDefinedTypeRepresentation,
UserDefinedTypeSqlDefinitionOption, UserDefinedTypeStorage, ViewColumnDef, WithData,
Expand Down
75 changes: 55 additions & 20 deletions src/ast/spans.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,26 +29,27 @@ use crate::tokenizer::Span;

use super::{
comments, dcl::SecondaryRoles, value::ValueWithSpan, AccessExpr, AlterColumnOperation,
AlterIndexOperation, AlterTableOperation, AlterTrigger, AlterTriggerOperation, Analyze, Array,
Assignment, AssignmentTarget, AttachedToken, BeginEndStatements, CaseStatement, CloseCursor,
ClusteredIndex, ColumnDef, ColumnOption, ColumnOptionDef, ConditionalStatementBlock,
ConditionalStatements, ConflictTarget, ConnectByKind, ConstraintCharacteristics, CopySource,
CreateIndex, CreateRule, CreateRuleAction, CreateTable, CreateTableOptions, Cte, Delete,
DoUpdate, 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, RenameSelectItem, ReplaceSelectElement,
ReplaceSelectItem, Select, SelectInto, SelectItem, SetExpr, Setting, SqlOption, Statement,
Subscript, SymbolDefinition, TableAlias, TableAliasColumnDef, TableConstraint, TableFactor,
TableObject, TableOptionsClustered, TableWithJoins, Update, UpdateTableFromKind, Use, Values,
ViewColumnDef, WhileStatement, WildcardAdditionalOptions, With, WithFill,
AlterGenericOption, AlterIndexOperation, AlterTableOperation, AlterTrigger,
AlterTriggerOperation, Analyze, Array, Assignment, AssignmentTarget, AttachedToken,
BeginEndStatements, CaseStatement, CloseCursor, ClusteredIndex, ColumnDef, ColumnOption,
ColumnOptionDef, ConditionalStatementBlock, ConditionalStatements, ConflictTarget,
ConnectByKind, ConstraintCharacteristics, CopySource, CreateIndex, CreateRule,
CreateRuleAction, CreateTable, CreateTableOptions, Cte, Delete, DoUpdate, 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,
RenameSelectItem, ReplaceSelectElement, ReplaceSelectItem, Select, SelectInto, SelectItem,
SetExpr, Setting, SqlOption, Statement, Subscript, SymbolDefinition, TableAlias,
TableAliasColumnDef, TableConstraint, TableFactor, TableObject, TableOptionsClustered,
TableWithJoins, Update, UpdateTableFromKind, Use, Values, ViewColumnDef, WhileStatement,
WildcardAdditionalOptions, With, WithFill,
};

/// Given an iterator of spans, return the [Span::union] of all spans.
Expand Down Expand Up @@ -966,6 +967,20 @@ impl Spanned for AlterColumnOperation {
had_set: _,
} => using.as_ref().map_or(Span::empty(), |u| u.span()),
AlterColumnOperation::AddGenerated { .. } => Span::empty(),
AlterColumnOperation::GenericOptions { options } => {
union_spans(options.iter().map(|option| option.span()))
}
}
}
}

impl Spanned for AlterGenericOption {
fn span(&self) -> Span {
match self {
AlterGenericOption::Add { option, .. } | AlterGenericOption::Set(option) => {
option.key.span.union(&option.value.span)
}
AlterGenericOption::Drop(key) => key.span,
}
}
}
Expand Down Expand Up @@ -1312,6 +1327,9 @@ impl Spanned for AlterTableOperation {
AlterTableOperation::SetOptionsParens { options } => {
union_spans(options.iter().map(|i| i.span()))
}
AlterTableOperation::GenericOptions { options } => {
union_spans(options.iter().map(|option| option.span()))
}
}
}
}
Expand Down Expand Up @@ -3377,6 +3395,23 @@ SETTINGS update_parallel_mode = 'auto'"#;
assert_eq!(test.get_source(options[0].value.span), "'public'");
}

#[test]
fn test_alter_foreign_table_option_spans() {
let dialect = &crate::dialect::PostgreSqlDialect {};
let sql = "ALTER FOREIGN TABLE ft OPTIONS (ADD a '1', DROP b), ALTER COLUMN c OPTIONS (SET d '2')";
let mut test = SpanTest::new(dialect, sql);

let operations = match test.0.parse_statement().unwrap() {
Statement::AlterTable(alter) => alter.operations,
stmt => panic!("expected ALTER FOREIGN TABLE, got {stmt:?}"),
};
assert_eq!(test.get_source(operations[0].span()), "a '1', DROP b");
assert_eq!(
test.get_source(operations[1].span()),
"c OPTIONS (SET d '2'"
);
}

#[test]
fn test_alter_table_modify_order_by_span() {
let dialect = &crate::dialect::ClickHouseDialect {};
Expand Down
Loading
Loading