@@ -5213,6 +5213,17 @@ impl<'a> Parser<'a> {
52135213 }
52145214 } else if self.parse_keyword(Keyword::SERVER) {
52155215 self.parse_pg_create_server()
5216+ } else if self.parse_keyword(Keyword::FOREIGN) {
5217+ if self.parse_keywords(&[Keyword::DATA, Keyword::WRAPPER]) {
5218+ self.parse_create_foreign_data_wrapper().map(Into::into)
5219+ } else if self.parse_keyword(Keyword::TABLE) {
5220+ self.parse_create_foreign_table().map(Into::into)
5221+ } else {
5222+ self.expected_ref(
5223+ "DATA WRAPPER or TABLE after CREATE FOREIGN",
5224+ self.peek_token_ref(),
5225+ )
5226+ }
52165227 } else {
52175228 self.expected_ref("an object type after CREATE", self.peek_token_ref())
52185229 }
@@ -19757,6 +19768,86 @@ impl<'a> Parser<'a> {
1975719768 }))
1975819769 }
1975919770
19771+ /// Parse a `CREATE FOREIGN DATA WRAPPER` statement.
19772+ ///
19773+ /// See <https://www.postgresql.org/docs/current/sql-createforeigndatawrapper.html>
19774+ pub fn parse_create_foreign_data_wrapper(
19775+ &mut self,
19776+ ) -> Result<CreateForeignDataWrapper, ParserError> {
19777+ let name = self.parse_identifier()?;
19778+
19779+ let handler = if self.parse_keyword(Keyword::HANDLER) {
19780+ Some(FdwRoutineClause::Function(self.parse_object_name(false)?))
19781+ } else if self.parse_keywords(&[Keyword::NO, Keyword::HANDLER]) {
19782+ Some(FdwRoutineClause::NoFunction)
19783+ } else {
19784+ None
19785+ };
19786+
19787+ let validator = if self.parse_keyword(Keyword::VALIDATOR) {
19788+ Some(FdwRoutineClause::Function(self.parse_object_name(false)?))
19789+ } else if self.parse_keywords(&[Keyword::NO, Keyword::VALIDATOR]) {
19790+ Some(FdwRoutineClause::NoFunction)
19791+ } else {
19792+ None
19793+ };
19794+
19795+ let options = if self.parse_keyword(Keyword::OPTIONS) {
19796+ self.expect_token(&Token::LParen)?;
19797+ let opts = self.parse_comma_separated(|p| {
19798+ let key = p.parse_identifier()?;
19799+ let value = p.parse_identifier()?;
19800+ Ok(CreateServerOption { key, value })
19801+ })?;
19802+ self.expect_token(&Token::RParen)?;
19803+ Some(opts)
19804+ } else {
19805+ None
19806+ };
19807+
19808+ Ok(CreateForeignDataWrapper {
19809+ name,
19810+ handler,
19811+ validator,
19812+ options,
19813+ })
19814+ }
19815+
19816+ /// Parse a `CREATE FOREIGN TABLE` statement.
19817+ ///
19818+ /// See <https://www.postgresql.org/docs/current/sql-createforeigntable.html>
19819+ pub fn parse_create_foreign_table(
19820+ &mut self,
19821+ ) -> Result<CreateForeignTable, ParserError> {
19822+ let if_not_exists =
19823+ self.parse_keywords(&[Keyword::IF, Keyword::NOT, Keyword::EXISTS]);
19824+ let name = self.parse_object_name(false)?;
19825+ let (columns, _constraints) = self.parse_columns()?;
19826+ self.expect_keyword_is(Keyword::SERVER)?;
19827+ let server_name = self.parse_identifier()?;
19828+
19829+ let options = if self.parse_keyword(Keyword::OPTIONS) {
19830+ self.expect_token(&Token::LParen)?;
19831+ let opts = self.parse_comma_separated(|p| {
19832+ let key = p.parse_identifier()?;
19833+ let value = p.parse_identifier()?;
19834+ Ok(CreateServerOption { key, value })
19835+ })?;
19836+ self.expect_token(&Token::RParen)?;
19837+ Some(opts)
19838+ } else {
19839+ None
19840+ };
19841+
19842+ Ok(CreateForeignTable {
19843+ name,
19844+ if_not_exists,
19845+ columns,
19846+ server_name,
19847+ options,
19848+ })
19849+ }
19850+
1976019851 /// The index of the first unprocessed token.
1976119852 pub fn index(&self) -> usize {
1976219853 self.index
0 commit comments