Skip to content

PostgreSQL: add support for CREATE FOREIGN TABLE and CREATE FOREIGN DATA WRAPPER#2317

Open
fmguerreiro wants to merge 12 commits into
apache:mainfrom
fmguerreiro:upstream/foreign-table-fdw
Open

PostgreSQL: add support for CREATE FOREIGN TABLE and CREATE FOREIGN DATA WRAPPER#2317
fmguerreiro wants to merge 12 commits into
apache:mainfrom
fmguerreiro:upstream/foreign-table-fdw

Conversation

@fmguerreiro

@fmguerreiro fmguerreiro commented Apr 18, 2026

Copy link
Copy Markdown
Contributor

Parses the two statements that set up a PostgreSQL foreign-data wrapper:

  • CREATE FOREIGN DATA WRAPPER name [HANDLER fn | NO HANDLER] [VALIDATOR fn | NO VALIDATOR] [OPTIONS (...)] (docs)
  • CREATE FOREIGN TABLE [IF NOT EXISTS] name (columns) SERVER server [OPTIONS (...)] (docs)

Both dispatch from parse_create into new CreateForeignDataWrapper, CreateForeignTable, and FdwRoutineClause nodes with matching Statement variants. Round-trip tests cover handler and validator present, NO HANDLER / NO VALIDATOR, and foreign tables with columns, SERVER, optional IF NOT EXISTS, and table-level OPTIONS.

ALTER FOREIGN TABLE, ALTER FOREIGN DATA WRAPPER, CREATE SERVER, and CREATE USER MAPPING are out of scope. CREATE SERVER already exists on the pgmold-sqlparser fork and can be upstreamed as a follow-up.

Ported from the pgmold-sqlparser fork, where it was tested against PostgreSQL 13-17 schemas in pgmold.

- 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
- Dispatch on FOREIGN keyword in parse_create, branching on DATA WRAPPER or TABLE
- parse_create_foreign_data_wrapper: parses optional HANDLER/NO HANDLER,
  VALIDATOR/NO VALIDATOR, and OPTIONS clauses
- parse_create_foreign_table: parses IF NOT EXISTS, column list via parse_columns,
  required SERVER name, and optional OPTIONS clause
Round-trip tests via pg().verified_stmt for:
- FDW: name-only, HANDLER, NO HANDLER, NO VALIDATOR, combined HANDLER+VALIDATOR+OPTIONS
- FOREIGN TABLE: basic columns+SERVER, IF NOT EXISTS, table-level OPTIONS
- CreateForeignTable now carries `constraints: Vec<TableConstraint>`
  so CHECK and other table-level constraints round-trip faithfully
  instead of being silently discarded.
- CreateForeignDataWrapper.name is now ObjectName for parity with
  other CREATE statements and to permit schema-qualified FDW names.
- Rename FdwRoutineClause::NoFunction -> Absent so the variant is
  not misleading when used for VALIDATOR.
- Extract parse_fdw_options_clause shared by CREATE SERVER, CREATE
  FOREIGN DATA WRAPPER, and CREATE FOREIGN TABLE.
- Extract parse_fdw_routine_clause parameterised over HANDLER /
  VALIDATOR so handler and validator share one code path.
- FdwRoutineClause gains a Display helper that formats with a label,
  replacing the duplicated match arms in CreateForeignDataWrapper.
- Tests cover schema-qualified FDW name and round-trip of a CHECK
  constraint on CREATE FOREIGN TABLE.
…eForeignTable

Return each statement's name span instead of Span::empty(), matching
the sibling Create* arms.
- Fix CreateForeignTable Display emitting `(, CONSTRAINT ...)` when columns
  is empty but constraints is non-empty; only emit the joining comma when
  both are non-empty, mirroring CreateTable::fmt
- Implement union Spanned for CreateForeignTable and CreateForeignDataWrapper
  and delegate from spans.rs via stmt.span()
- Add Display for FdwRoutineClause defaulting to the HANDLER label
- Strengthen CREATE FOREIGN TABLE/FDW OPTIONS assertions to full
  CreateServerOption structs including quote_style and span
- Run the four new foreign tests under pg_and_generic()
- Document the deliberate parser relaxation for schema-qualified FDW names
- Flatten the nested CREATE FOREIGN dispatch into the parser chain
- Trim the redundant FdwRoutineClause doc sentence
…splay

Rename FdwRoutineClause to ForeignDataWrapperRoutineClause and the
parse_fdw_* helpers to parse_foreign_data_wrapper_* to match the
codebase convention of spelling out foreign data wrapper. Remove the
Display impl that hardcoded HANDLER, since every call site uses
fmt_with_label with the correct per-clause label. Rename the opts local
to options and correct a doc comment spelling.
…e-fdw

# Conflicts:
#	src/ast/mod.rs
#	tests/sqlparser_postgres.rs
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant