Skip to content

Commit 613c05f

Browse files
committed
feat(ast): add CreateForeignDataWrapper and CreateForeignTable types
- Add HANDLER and VALIDATOR keywords to the keyword list - Add FdwRoutineClause enum for HANDLER/NO HANDLER and VALIDATOR/NO VALIDATOR clauses - Add CreateForeignDataWrapper struct for CREATE FOREIGN DATA WRAPPER - Add CreateForeignTable struct for CREATE FOREIGN TABLE - Export new types from ast::mod and add Statement variants - Add spans.rs coverage returning Span::empty() for the new variants
1 parent a736c67 commit 613c05f

4 files changed

Lines changed: 125 additions & 6 deletions

File tree

src/ast/ddl.rs

Lines changed: 103 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,8 @@ use crate::ast::{
4242
UniqueConstraint,
4343
},
4444
ArgMode, AttachedToken, CommentDef, ConditionalStatements, CreateFunctionBody,
45-
CreateFunctionUsing, CreateTableLikeKind, CreateTableOptions, CreateViewParams, DataType, Expr,
45+
CreateFunctionUsing, CreateServerOption, CreateTableLikeKind, CreateTableOptions,
46+
CreateViewParams, DataType, Expr,
4647
FileFormat, FunctionBehavior, FunctionCalledOnNull, FunctionDefinitionSetParam, FunctionDesc,
4748
FunctionDeterminismSpecifier, FunctionParallel, FunctionSecurity, HiveDistributionStyle,
4849
HiveFormat, HiveIOFormat, HiveRowFormat, HiveSetLocation, Ident, InitializeKind,
@@ -5757,3 +5758,104 @@ impl From<AlterPolicy> for crate::ast::Statement {
57575758
crate::ast::Statement::AlterPolicy(v)
57585759
}
57595760
}
5761+
5762+
/// The handler/validator clause of a `CREATE FOREIGN DATA WRAPPER` statement.
5763+
///
5764+
/// Specifies either a named function or the absence of a function.
5765+
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
5766+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
5767+
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
5768+
pub enum FdwRoutineClause {
5769+
/// A named function, e.g. `HANDLER myhandler` or `VALIDATOR myvalidator`.
5770+
Function(ObjectName),
5771+
/// The `NO HANDLER` or `NO VALIDATOR` form.
5772+
NoFunction,
5773+
}
5774+
5775+
/// A `CREATE FOREIGN DATA WRAPPER` statement.
5776+
///
5777+
/// See [PostgreSQL](https://www.postgresql.org/docs/current/sql-createforeigndatawrapper.html)
5778+
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
5779+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
5780+
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
5781+
pub struct CreateForeignDataWrapper {
5782+
/// The name of the foreign-data wrapper.
5783+
pub name: Ident,
5784+
/// Optional `HANDLER handler_function` or `NO HANDLER` clause.
5785+
pub handler: Option<FdwRoutineClause>,
5786+
/// Optional `VALIDATOR validator_function` or `NO VALIDATOR` clause.
5787+
pub validator: Option<FdwRoutineClause>,
5788+
/// Optional `OPTIONS (key 'value', ...)` clause.
5789+
pub options: Option<Vec<CreateServerOption>>,
5790+
}
5791+
5792+
impl fmt::Display for CreateForeignDataWrapper {
5793+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5794+
write!(f, "CREATE FOREIGN DATA WRAPPER {}", self.name)?;
5795+
if let Some(handler) = &self.handler {
5796+
match handler {
5797+
FdwRoutineClause::Function(name) => write!(f, " HANDLER {name}")?,
5798+
FdwRoutineClause::NoFunction => write!(f, " NO HANDLER")?,
5799+
}
5800+
}
5801+
if let Some(validator) = &self.validator {
5802+
match validator {
5803+
FdwRoutineClause::Function(name) => write!(f, " VALIDATOR {name}")?,
5804+
FdwRoutineClause::NoFunction => write!(f, " NO VALIDATOR")?,
5805+
}
5806+
}
5807+
if let Some(options) = &self.options {
5808+
write!(f, " OPTIONS ({})", display_comma_separated(options))?;
5809+
}
5810+
Ok(())
5811+
}
5812+
}
5813+
5814+
impl From<CreateForeignDataWrapper> for crate::ast::Statement {
5815+
fn from(v: CreateForeignDataWrapper) -> Self {
5816+
crate::ast::Statement::CreateForeignDataWrapper(v)
5817+
}
5818+
}
5819+
5820+
/// A `CREATE FOREIGN TABLE` statement.
5821+
///
5822+
/// See [PostgreSQL](https://www.postgresql.org/docs/current/sql-createforeigntable.html)
5823+
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
5824+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
5825+
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
5826+
pub struct CreateForeignTable {
5827+
/// The foreign table name.
5828+
#[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
5829+
pub name: ObjectName,
5830+
/// Whether `IF NOT EXISTS` was specified.
5831+
pub if_not_exists: bool,
5832+
/// Column definitions.
5833+
pub columns: Vec<ColumnDef>,
5834+
/// The `SERVER server_name` clause.
5835+
pub server_name: Ident,
5836+
/// Optional `OPTIONS (key 'value', ...)` clause at the table level.
5837+
pub options: Option<Vec<CreateServerOption>>,
5838+
}
5839+
5840+
impl fmt::Display for CreateForeignTable {
5841+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5842+
write!(
5843+
f,
5844+
"CREATE FOREIGN TABLE {if_not_exists}{name} ({columns}) SERVER {server_name}",
5845+
if_not_exists = if self.if_not_exists { "IF NOT EXISTS " } else { "" },
5846+
name = self.name,
5847+
columns = display_comma_separated(&self.columns),
5848+
server_name = self.server_name,
5849+
)?;
5850+
if let Some(options) = &self.options {
5851+
write!(f, " OPTIONS ({})", display_comma_separated(options))?;
5852+
}
5853+
Ok(())
5854+
}
5855+
}
5856+
5857+
impl From<CreateForeignTable> for crate::ast::Statement {
5858+
fn from(v: CreateForeignTable) -> Self {
5859+
crate::ast::Statement::CreateForeignTable(v)
5860+
}
5861+
}

src/ast/mod.rs

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -69,11 +69,12 @@ pub use self::ddl::{
6969
AlterTypeAddValuePosition, AlterTypeOperation, AlterTypeRename, AlterTypeRenameValue,
7070
ClusteredBy, ColumnDef, ColumnOption, ColumnOptionDef, ColumnOptions, ColumnPolicy,
7171
ColumnPolicyProperty, ConstraintCharacteristics, CreateCollation, CreateCollationDefinition,
72-
CreateConnector, CreateDomain, CreateExtension, CreateFunction, CreateIndex, CreateOperator,
73-
CreateOperatorClass, CreateOperatorFamily, CreatePolicy, CreatePolicyCommand, CreatePolicyType,
74-
CreateTable, CreateTrigger, CreateView, Deduplicate, DeferrableInitial, DistStyle,
75-
DropBehavior, DropExtension, DropFunction, DropOperator, DropOperatorClass, DropOperatorFamily,
76-
DropOperatorSignature, DropPolicy, DropTrigger, ForValues, FunctionReturnType, GeneratedAs,
72+
CreateConnector, CreateDomain, CreateExtension, CreateForeignDataWrapper, CreateForeignTable,
73+
CreateFunction, CreateIndex, CreateOperator, CreateOperatorClass, CreateOperatorFamily,
74+
CreatePolicy, CreatePolicyCommand, CreatePolicyType, CreateTable, CreateTrigger, CreateView,
75+
Deduplicate, DeferrableInitial, DistStyle, DropBehavior, DropExtension, DropFunction,
76+
DropOperator, DropOperatorClass, DropOperatorFamily, DropOperatorSignature, DropPolicy,
77+
DropTrigger, FdwRoutineClause, ForValues, FunctionReturnType, GeneratedAs,
7778
GeneratedExpressionMode, IdentityParameters, IdentityProperty, IdentityPropertyFormatKind,
7879
IdentityPropertyKind, IdentityPropertyOrder, IndexColumn, IndexOption, IndexType,
7980
KeyOrIndexDisplay, Msck, NullsDistinctOption, OperatorArgTypes, OperatorClassItem,
@@ -3699,6 +3700,16 @@ pub enum Statement {
36993700
/// A `CREATE SERVER` statement.
37003701
CreateServer(CreateServerStatement),
37013702
/// ```sql
3703+
/// CREATE FOREIGN DATA WRAPPER
3704+
/// ```
3705+
/// See [PostgreSQL](https://www.postgresql.org/docs/current/sql-createforeigndatawrapper.html)
3706+
CreateForeignDataWrapper(CreateForeignDataWrapper),
3707+
/// ```sql
3708+
/// CREATE FOREIGN TABLE
3709+
/// ```
3710+
/// See [PostgreSQL](https://www.postgresql.org/docs/current/sql-createforeigntable.html)
3711+
CreateForeignTable(CreateForeignTable),
3712+
/// ```sql
37023713
/// CREATE POLICY
37033714
/// ```
37043715
/// See [PostgreSQL](https://www.postgresql.org/docs/current/sql-createpolicy.html)
@@ -5504,6 +5515,8 @@ impl fmt::Display for Statement {
55045515
Statement::CreateServer(stmt) => {
55055516
write!(f, "{stmt}")
55065517
}
5518+
Statement::CreateForeignDataWrapper(stmt) => write!(f, "{stmt}"),
5519+
Statement::CreateForeignTable(stmt) => write!(f, "{stmt}"),
55075520
Statement::CreatePolicy(policy) => write!(f, "{policy}"),
55085521
Statement::CreateConnector(create_connector) => create_connector.fmt(f),
55095522
Statement::CreateOperator(create_operator) => create_operator.fmt(f),

src/ast/spans.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,8 @@ impl Spanned for Statement {
386386
Statement::DropOperatorClass(drop_operator_class) => drop_operator_class.span(),
387387
Statement::CreateSecret { .. } => Span::empty(),
388388
Statement::CreateServer { .. } => Span::empty(),
389+
Statement::CreateForeignDataWrapper { .. } => Span::empty(),
390+
Statement::CreateForeignTable { .. } => Span::empty(),
389391
Statement::CreateConnector { .. } => Span::empty(),
390392
Statement::CreateOperator(create_operator) => create_operator.span(),
391393
Statement::CreateOperatorFamily(create_operator_family) => {

src/keywords.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -476,6 +476,7 @@ define_keywords!(
476476
GROUPING,
477477
GROUPS,
478478
GZIP,
479+
HANDLER,
479480
HASH,
480481
HASHES,
481482
HAVING,
@@ -1130,6 +1131,7 @@ define_keywords!(
11301131
VALID,
11311132
VALIDATE,
11321133
VALIDATION_MODE,
1134+
VALIDATOR,
11331135
VALUE,
11341136
VALUES,
11351137
VALUE_OF,

0 commit comments

Comments
 (0)