Commit a3740c48 authored by Fujii Masao's avatar Fujii Masao

postgres_fdw: Allow partitions specified in LIMIT TO to be imported.

Commit f49bcd4e disallowed postgres_fdw to import table partitions.
Because all data can be accessed through the partitioned table which
is the root of the partitioning hierarchy, importing only partitioned
table should allow access to all the data without creating extra objects.
This is a reasonable default when importing a whole schema. But there
may be the case where users want to explicitly import one of
a partitioned tables' partitions.

For that use case, this commit allows postgres_fdw to import tables or
foreign tables which are partitions of some other table only when they
are explicitly specified in LIMIT TO clause.  It doesn't change
the behavior that any partitions not specified in LIMIT TO are
automatically excluded in IMPORT FOREIGN SCHEMA command.

Author: Matthias van de Meent
Reviewed-by: Bernd Helmle, Amit Langote, Michael Paquier, Fujii Masao
Discussion: https://postgr.es/m/CAEze2Whwg4i=mzApMe+PXxCEfgoZmHGqdqQFW7J4bmj_5p6t1A@mail.gmail.com
parent 90c885cd
...@@ -8228,6 +8228,8 @@ ALTER TABLE import_source."x 5" DROP COLUMN c1; ...@@ -8228,6 +8228,8 @@ ALTER TABLE import_source."x 5" DROP COLUMN c1;
CREATE TABLE import_source.t4 (c1 int) PARTITION BY RANGE (c1); CREATE TABLE import_source.t4 (c1 int) PARTITION BY RANGE (c1);
CREATE TABLE import_source.t4_part PARTITION OF import_source.t4 CREATE TABLE import_source.t4_part PARTITION OF import_source.t4
FOR VALUES FROM (1) TO (100); FOR VALUES FROM (1) TO (100);
CREATE TABLE import_source.t4_part2 PARTITION OF import_source.t4
FOR VALUES FROM (100) TO (200);
CREATE SCHEMA import_dest1; CREATE SCHEMA import_dest1;
IMPORT FOREIGN SCHEMA import_source FROM SERVER loopback INTO import_dest1; IMPORT FOREIGN SCHEMA import_source FROM SERVER loopback INTO import_dest1;
\det+ import_dest1.* \det+ import_dest1.*
...@@ -8419,27 +8421,29 @@ FDW options: (schema_name 'import_source', table_name 'x 5') ...@@ -8419,27 +8421,29 @@ FDW options: (schema_name 'import_source', table_name 'x 5')
-- Check LIMIT TO and EXCEPT -- Check LIMIT TO and EXCEPT
CREATE SCHEMA import_dest4; CREATE SCHEMA import_dest4;
IMPORT FOREIGN SCHEMA import_source LIMIT TO (t1, nonesuch) IMPORT FOREIGN SCHEMA import_source LIMIT TO (t1, nonesuch, t4_part)
FROM SERVER loopback INTO import_dest4; FROM SERVER loopback INTO import_dest4;
\det+ import_dest4.* \det+ import_dest4.*
List of foreign tables List of foreign tables
Schema | Table | Server | FDW options | Description Schema | Table | Server | FDW options | Description
--------------+-------+----------+------------------------------------------------+------------- --------------+---------+----------+-----------------------------------------------------+-------------
import_dest4 | t1 | loopback | (schema_name 'import_source', table_name 't1') | import_dest4 | t1 | loopback | (schema_name 'import_source', table_name 't1') |
(1 row) import_dest4 | t4_part | loopback | (schema_name 'import_source', table_name 't4_part') |
(2 rows)
IMPORT FOREIGN SCHEMA import_source EXCEPT (t1, "x 4", nonesuch) IMPORT FOREIGN SCHEMA import_source EXCEPT (t1, "x 4", nonesuch, t4_part)
FROM SERVER loopback INTO import_dest4; FROM SERVER loopback INTO import_dest4;
\det+ import_dest4.* \det+ import_dest4.*
List of foreign tables List of foreign tables
Schema | Table | Server | FDW options | Description Schema | Table | Server | FDW options | Description
--------------+-------+----------+-------------------------------------------------+------------- --------------+---------+----------+-----------------------------------------------------+-------------
import_dest4 | t1 | loopback | (schema_name 'import_source', table_name 't1') | import_dest4 | t1 | loopback | (schema_name 'import_source', table_name 't1') |
import_dest4 | t2 | loopback | (schema_name 'import_source', table_name 't2') | import_dest4 | t2 | loopback | (schema_name 'import_source', table_name 't2') |
import_dest4 | t3 | loopback | (schema_name 'import_source', table_name 't3') | import_dest4 | t3 | loopback | (schema_name 'import_source', table_name 't3') |
import_dest4 | t4 | loopback | (schema_name 'import_source', table_name 't4') | import_dest4 | t4 | loopback | (schema_name 'import_source', table_name 't4') |
import_dest4 | x 5 | loopback | (schema_name 'import_source', table_name 'x 5') | import_dest4 | t4_part | loopback | (schema_name 'import_source', table_name 't4_part') |
(5 rows) import_dest4 | x 5 | loopback | (schema_name 'import_source', table_name 'x 5') |
(6 rows)
-- Assorted error cases -- Assorted error cases
IMPORT FOREIGN SCHEMA import_source FROM SERVER loopback INTO import_dest4; IMPORT FOREIGN SCHEMA import_source FROM SERVER loopback INTO import_dest4;
......
...@@ -5095,9 +5095,11 @@ postgresImportForeignSchema(ImportForeignSchemaStmt *stmt, Oid serverOid) ...@@ -5095,9 +5095,11 @@ postgresImportForeignSchema(ImportForeignSchemaStmt *stmt, Oid serverOid)
* should save a few cycles to not process excluded tables in the * should save a few cycles to not process excluded tables in the
* first place.) * first place.)
* *
* Ignore table data for partitions and only include the definitions * Import table data for partitions only when they are explicitly
* of the root partitioned tables to allow access to the complete * specified in LIMIT TO clause. Otherwise ignore them and only
* remote data set locally in the schema imported. * include the definitions of the root partitioned tables to allow
* access to the complete remote data set locally in the schema
* imported.
* *
* Note: because we run the connection with search_path restricted to * Note: because we run the connection with search_path restricted to
* pg_catalog, the format_type() and pg_get_expr() outputs will always * pg_catalog, the format_type() and pg_get_expr() outputs will always
...@@ -5153,7 +5155,8 @@ postgresImportForeignSchema(ImportForeignSchemaStmt *stmt, Oid serverOid) ...@@ -5153,7 +5155,8 @@ postgresImportForeignSchema(ImportForeignSchemaStmt *stmt, Oid serverOid)
deparseStringLiteral(&buf, stmt->remote_schema); deparseStringLiteral(&buf, stmt->remote_schema);
/* Partitions are supported since Postgres 10 */ /* Partitions are supported since Postgres 10 */
if (PQserverVersion(conn) >= 100000) if (PQserverVersion(conn) >= 100000 &&
stmt->list_type != FDW_IMPORT_SCHEMA_LIMIT_TO)
appendStringInfoString(&buf, " AND NOT c.relispartition "); appendStringInfoString(&buf, " AND NOT c.relispartition ");
/* Apply restrictions for LIMIT TO and EXCEPT */ /* Apply restrictions for LIMIT TO and EXCEPT */
......
...@@ -2366,6 +2366,8 @@ ALTER TABLE import_source."x 5" DROP COLUMN c1; ...@@ -2366,6 +2366,8 @@ ALTER TABLE import_source."x 5" DROP COLUMN c1;
CREATE TABLE import_source.t4 (c1 int) PARTITION BY RANGE (c1); CREATE TABLE import_source.t4 (c1 int) PARTITION BY RANGE (c1);
CREATE TABLE import_source.t4_part PARTITION OF import_source.t4 CREATE TABLE import_source.t4_part PARTITION OF import_source.t4
FOR VALUES FROM (1) TO (100); FOR VALUES FROM (1) TO (100);
CREATE TABLE import_source.t4_part2 PARTITION OF import_source.t4
FOR VALUES FROM (100) TO (200);
CREATE SCHEMA import_dest1; CREATE SCHEMA import_dest1;
IMPORT FOREIGN SCHEMA import_source FROM SERVER loopback INTO import_dest1; IMPORT FOREIGN SCHEMA import_source FROM SERVER loopback INTO import_dest1;
...@@ -2386,10 +2388,10 @@ IMPORT FOREIGN SCHEMA import_source FROM SERVER loopback INTO import_dest3 ...@@ -2386,10 +2388,10 @@ IMPORT FOREIGN SCHEMA import_source FROM SERVER loopback INTO import_dest3
-- Check LIMIT TO and EXCEPT -- Check LIMIT TO and EXCEPT
CREATE SCHEMA import_dest4; CREATE SCHEMA import_dest4;
IMPORT FOREIGN SCHEMA import_source LIMIT TO (t1, nonesuch) IMPORT FOREIGN SCHEMA import_source LIMIT TO (t1, nonesuch, t4_part)
FROM SERVER loopback INTO import_dest4; FROM SERVER loopback INTO import_dest4;
\det+ import_dest4.* \det+ import_dest4.*
IMPORT FOREIGN SCHEMA import_source EXCEPT (t1, "x 4", nonesuch) IMPORT FOREIGN SCHEMA import_source EXCEPT (t1, "x 4", nonesuch, t4_part)
FROM SERVER loopback INTO import_dest4; FROM SERVER loopback INTO import_dest4;
\det+ import_dest4.* \det+ import_dest4.*
......
...@@ -510,10 +510,12 @@ OPTIONS (ADD password_required 'false'); ...@@ -510,10 +510,12 @@ OPTIONS (ADD password_required 'false');
<para> <para>
Tables or foreign tables which are partitions of some other table are Tables or foreign tables which are partitions of some other table are
automatically excluded. Partitioned tables are imported, unless they imported only when they are explicitly specified in
are a partition of some other table. Since all data can be accessed <literal>LIMIT TO</literal> clause. Otherwise they are automatically
through the partitioned table which is the root of the partitioning excluded from <xref linkend="sql-importforeignschema"/>.
hierarchy, this approach should allow access to all the data without Since all data can be accessed through the partitioned table
which is the root of the partitioning hierarchy, importing only
partitioned tables should allow access to all the data without
creating extra objects. creating extra objects.
</para> </para>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment