GeezerVison is showing github.com — feat: parse PostgreSQL IMPORT FOREIGN SCHEMA by minleejae · Pull Request #2909 · JSQLParser/JSqlParser
Conversation
Purpose
PostgreSQL's IMPORT FOREIGN SCHEMA failed to parse at IMPORT:
IMPORT FOREIGN SCHEMA remote FROM SERVER srv INTO local;
IMPORT FOREIGN SCHEMA remote LIMIT TO (t1, t2) FROM SERVER srv INTO local
OPTIONS (import_default 'true');
IMPORT FOREIGN SCHEMA remote EXCEPT (t3) FROM SERVER srv INTO local;
It is the one statement of PostgreSQL's foreign-data DDL that had no model: CREATE/ALTER/DROP
of FOREIGN DATA WRAPPER, SERVER, USER MAPPING and FOREIGN TABLE already parse.
Current design (As-is)
IMPORT starts a statement only with the EXASOL dialect (Import, and (IMPORT …) as a
sub-select source). Elsewhere it is used inside MySQL's ALTER TABLE … IMPORT TABLESPACE /
IMPORT PARTITION.
- With the PostgreSQL dialect or without a dialect,
IMPORT FOREIGN SCHEMA … is a parse error,
or an UnsupportedStatement when unsupported statements are allowed.
- The foreign-data statements share
ForeignDataStatement (the OPTIONS (…) list of
ForeignDataOption values, its rendering and its expression traversal) and the
ForeignDataOptions production.
LOCK and TRUNCATE share TableReference and the RelationTarget production for
PostgreSQL's relation_expr (name, name *, ONLY name, ONLY (name)).
Target design (To-be)
-
Model. ImportForeignSchema in net.sf.jsqlparser.statement.foreign extends
ForeignDataStatement:
getRemoteSchema(), getServer(), getLocalSchema(): the three names;
getQualification(): LIMIT_TO, EXCEPT, or null when the whole schema is imported;
getTables(): the listed tables as TableReference values (a read-only snapshot);
setTables(qualification, tables) changes the kind and the list together and rejects a kind
without tables or tables without a kind;
getOptions(): the inherited ForeignDataOption list.
-
Grammar. One production follows PostgreSQL's ImportForeignSchemaStmt:
IMPORT FOREIGN SCHEMA name [ { LIMIT TO | EXCEPT } ( relation_expr [, ...] ) ]
FROM SERVER name INTO name [ OPTIONS ( option 'value' [, ...] ) ]
- The table list reuses
RelationTarget, because PostgreSQL's grammar reads a
relation_expr_list there: LIMIT TO (ONLY t1, s.t2 *) is accepted by the server and by the
parser, LIMIT TO (ONLY t1 *) and LIMIT TO ((t1)) by neither.
OPTIONS reuses ForeignDataOptions in its CREATE mode, so ADD, SET and DROP are
rejected, as are an empty list and a value that is not a string constant.
- No keyword is added:
IMPORT, FOREIGN, SCHEMA, LIMIT, TO, EXCEPT, FROM and INTO
are existing tokens, and SERVER and OPTIONS are read as contextual words, so server,
options, import and schema stay usable as names
(IMPORT FOREIGN SCHEMA server FROM SERVER server INTO server).
-
Dialects. The statement is read with the PostgreSQL dialect or without one, when FOREIGN
follows IMPORT. The EXASOL dialect keeps IMPORT for its own statement, which FOREIGN
cannot continue; MySQL, MariaDB, Oracle, SQL Server and EXASOL keep rejecting
IMPORT FOREIGN SCHEMA. ALTER TABLE … IMPORT TABLESPACE is unchanged.
-
Wiring. StatementVisitor default method, StatementVisitorAdapter (visits the option
values like the other foreign-data statements), StatementDeParser (through the shared
appendTo), TablesNamesFinder (no tables: the listed names belong to the remote schema),
and feature analysis (MODIFIES_SCHEMA). Validation gets the feature importForeignSchema,
enabled by the PostgreSQL capabilities and by FeaturesAllowed.DDL.
Reference: PostgreSQL IMPORT FOREIGN SCHEMA.
Not included:
- A reserved word as an option name (
OPTIONS (select 'y')). PostgreSQL reads option names as
column labels; the shared ForeignDataOptions production reads them as object names, for this
statement as for CREATE SERVER, CREATE USER MAPPING and CREATE FOREIGN TABLE. That
belongs in a change to the shared production.
Validation
-
New ImportForeignSchemaTest with 59 test cases. They cover parsing with the PostgreSQL
dialect and without one, toString, StatementDeParser, reparse, AST fields, the AST node,
rejected forms, other dialects and other uses of IMPORT keeping their readings, statement
boundaries with and without semicolons (including after an unsupported statement), visitors,
TablesNamesFinder, feature analysis, validation and the model API.
-
Updated tests:
ASTNodeCoverageTest walks one of the new forms.
- Six tests (
DiscardStatementTest, ReindexTest, CheckpointStatementTest,
ClusterStatementTest, VacuumStatementTest, SecurityLabelTest) used
IMPORT FOREIGN SCHEMA … as their example of an unsupported statement; they now use
EXASOL's IMPORT INTO t FROM LOCAL CSV FILE 'f.csv', which stays unsupported there.
-
These tests fail on master, where the statement does not parse.
-
./gradlew spotlessApply check jar: 13392 tests, 25 skipped, 0 failures. Grammar ambiguity check, Checkstyle, PMD,
SpotBugs and JaCoCo pass.
-
Compared with master (e27929f76) on the DDL/DCL and non-DDL survey corpora, nothing
regressed or changed. The corpora do not contain IMPORT FOREIGN SCHEMA; a separate list of 24
accepted forms (PostgreSQL dialect and no dialect) parses and round-trips, and 35 forms that
PostgreSQL rejects are rejected.
-
PostgreSQL 18.6 accepts all 19 IMPORT FOREIGN SCHEMA statements the tests accept, all of which master rejects; they fail only when run (the foreign server cannot be reached). This includes LIMIT TO (ONLY t1, t2 *), EXCEPT (ONLY (t1)), quoted names, dollar-quoted and escape-string option values, and server, options, import and schema used as names. It reports a syntax error for all 35 statements the tests reject, including an empty table list, ONLY t1 *, ((t1)), LIMIT TO together with EXCEPT, OPTIONS (), ADD/SET/DROP in the option list and a qualified schema or server name. One form PostgreSQL accepts is not parsed: a reserved word as an option name (OPTIONS (select 'y')), which the shared option production rejects for CREATE SERVER on master as well.
AI assistance: prepared with Claude Code.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Add ImportForeignSchema for IMPORT FOREIGN SCHEMA remote [{LIMIT TO | EXCEPT} (table, ...)] FROM SERVER server INTO local [OPTIONS (...)], read with the PostgreSQL dialect or without one. The table list reuses the relation targets of LOCK and TRUNCATE, and OPTIONS the generic options of the other foreign-data statements. The EXASOL IMPORT statement and other dialects are unchanged.
Signed-off-by: minleejae <[email protected]>
This branch has not been deployed
No deployments
Uh oh!
There was an error while loading. Please reload this page.
Assignees
No one assigned
Milestone
No milestone
Development
Successfully merging this pull request may close these issues.
Uh oh!
There was an error while loading. Please reload this page.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
|