From f49bcd4ef3e9a75de210357a4d9bbe3e004db956 Mon Sep 17 00:00:00 2001 From: Robert Haas Date: Fri, 31 Mar 2017 15:01:35 -0400 Subject: [PATCH] postgres_fdw: Teach IMPORT FOREIGN SCHEMA about partitioning. Don't import partitions. Do import partitioned tables which are not themselves partitions. Report by Stephen Frost. Design and patch by Michael Paquier, reviewed by Amit Langote. Documentation revised by me. Discussion: http://postgr.es/m/20170309141531.GD9812@tamriel.snowman.net --- .../postgres_fdw/expected/postgres_fdw.out | 36 ++++++++++++++++--- contrib/postgres_fdw/postgres_fdw.c | 11 +++++- contrib/postgres_fdw/sql/postgres_fdw.sql | 3 ++ doc/src/sgml/postgres-fdw.sgml | 10 ++++++ 4 files changed, 55 insertions(+), 5 deletions(-) diff --git a/contrib/postgres_fdw/expected/postgres_fdw.out b/contrib/postgres_fdw/expected/postgres_fdw.out index a466bf2079..1a9e6c87f6 100644 --- a/contrib/postgres_fdw/expected/postgres_fdw.out +++ b/contrib/postgres_fdw/expected/postgres_fdw.out @@ -6907,6 +6907,9 @@ CREATE TABLE import_source.t3 (c1 timestamptz default now(), c2 typ1); CREATE TABLE import_source."x 4" (c1 float8, "C 2" text, c3 varchar(42)); CREATE TABLE import_source."x 5" (c1 float8); 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_part PARTITION OF import_source.t4 + FOR VALUES FROM (1) TO (100); CREATE SCHEMA import_dest1; IMPORT FOREIGN SCHEMA import_source FROM SERVER loopback INTO import_dest1; \det+ import_dest1.* @@ -6916,9 +6919,10 @@ IMPORT FOREIGN SCHEMA import_source FROM SERVER loopback INTO import_dest1; import_dest1 | t1 | loopback | (schema_name 'import_source', table_name 't1') | import_dest1 | t2 | loopback | (schema_name 'import_source', table_name 't2') | import_dest1 | t3 | loopback | (schema_name 'import_source', table_name 't3') | + import_dest1 | t4 | loopback | (schema_name 'import_source', table_name 't4') | import_dest1 | x 4 | loopback | (schema_name 'import_source', table_name 'x 4') | import_dest1 | x 5 | loopback | (schema_name 'import_source', table_name 'x 5') | -(5 rows) +(6 rows) \d import_dest1.* Foreign table "import_dest1.t1" @@ -6946,6 +6950,13 @@ FDW Options: (schema_name 'import_source', table_name 't2') Server: loopback FDW Options: (schema_name 'import_source', table_name 't3') + Foreign table "import_dest1.t4" + Column | Type | Collation | Nullable | Default | FDW Options +--------+---------+-----------+----------+---------+-------------------- + c1 | integer | | not null | | (column_name 'c1') +Server: loopback +FDW Options: (schema_name 'import_source', table_name 't4') + Foreign table "import_dest1.x 4" Column | Type | Collation | Nullable | Default | FDW Options --------+-----------------------+-----------+----------+---------+--------------------- @@ -6972,9 +6983,10 @@ IMPORT FOREIGN SCHEMA import_source FROM SERVER loopback INTO import_dest2 import_dest2 | t1 | loopback | (schema_name 'import_source', table_name 't1') | import_dest2 | t2 | loopback | (schema_name 'import_source', table_name 't2') | import_dest2 | t3 | loopback | (schema_name 'import_source', table_name 't3') | + import_dest2 | t4 | loopback | (schema_name 'import_source', table_name 't4') | import_dest2 | x 4 | loopback | (schema_name 'import_source', table_name 'x 4') | import_dest2 | x 5 | loopback | (schema_name 'import_source', table_name 'x 5') | -(5 rows) +(6 rows) \d import_dest2.* Foreign table "import_dest2.t1" @@ -7002,6 +7014,13 @@ FDW Options: (schema_name 'import_source', table_name 't2') Server: loopback FDW Options: (schema_name 'import_source', table_name 't3') + Foreign table "import_dest2.t4" + Column | Type | Collation | Nullable | Default | FDW Options +--------+---------+-----------+----------+---------+-------------------- + c1 | integer | | not null | | (column_name 'c1') +Server: loopback +FDW Options: (schema_name 'import_source', table_name 't4') + Foreign table "import_dest2.x 4" Column | Type | Collation | Nullable | Default | FDW Options --------+-----------------------+-----------+----------+---------+--------------------- @@ -7027,9 +7046,10 @@ IMPORT FOREIGN SCHEMA import_source FROM SERVER loopback INTO import_dest3 import_dest3 | t1 | loopback | (schema_name 'import_source', table_name 't1') | import_dest3 | t2 | loopback | (schema_name 'import_source', table_name 't2') | import_dest3 | t3 | loopback | (schema_name 'import_source', table_name 't3') | + import_dest3 | t4 | loopback | (schema_name 'import_source', table_name 't4') | import_dest3 | x 4 | loopback | (schema_name 'import_source', table_name 'x 4') | import_dest3 | x 5 | loopback | (schema_name 'import_source', table_name 'x 5') | -(5 rows) +(6 rows) \d import_dest3.* Foreign table "import_dest3.t1" @@ -7057,6 +7077,13 @@ FDW Options: (schema_name 'import_source', table_name 't2') Server: loopback FDW Options: (schema_name 'import_source', table_name 't3') + Foreign table "import_dest3.t4" + Column | Type | Collation | Nullable | Default | FDW Options +--------+---------+-----------+----------+---------+-------------------- + c1 | integer | | | | (column_name 'c1') +Server: loopback +FDW Options: (schema_name 'import_source', table_name 't4') + Foreign table "import_dest3.x 4" Column | Type | Collation | Nullable | Default | FDW Options --------+-----------------------+-----------+----------+---------+--------------------- @@ -7092,8 +7119,9 @@ IMPORT FOREIGN SCHEMA import_source EXCEPT (t1, "x 4", nonesuch) import_dest4 | t1 | loopback | (schema_name 'import_source', table_name 't1') | import_dest4 | t2 | loopback | (schema_name 'import_source', table_name 't2') | import_dest4 | t3 | loopback | (schema_name 'import_source', table_name 't3') | + import_dest4 | t4 | loopback | (schema_name 'import_source', table_name 't4') | import_dest4 | x 5 | loopback | (schema_name 'import_source', table_name 'x 5') | -(4 rows) +(5 rows) -- Assorted error cases IMPORT FOREIGN SCHEMA import_source FROM SERVER loopback INTO import_dest4; diff --git a/contrib/postgres_fdw/postgres_fdw.c b/contrib/postgres_fdw/postgres_fdw.c index 03f14800b0..54b938734a 100644 --- a/contrib/postgres_fdw/postgres_fdw.c +++ b/contrib/postgres_fdw/postgres_fdw.c @@ -3849,6 +3849,10 @@ postgresImportForeignSchema(ImportForeignSchemaStmt *stmt, Oid serverOid) * should save a few cycles to not process excluded tables in the * first place.) * + * Ignore table data for partitions and only 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 * pg_catalog, the format_type() and pg_get_expr() outputs will always * include a schema name for types/functions in other schemas, which @@ -3897,10 +3901,15 @@ postgresImportForeignSchema(ImportForeignSchemaStmt *stmt, Oid serverOid) CppAsString2(RELKIND_RELATION) "," CppAsString2(RELKIND_VIEW) "," CppAsString2(RELKIND_FOREIGN_TABLE) "," - CppAsString2(RELKIND_MATVIEW) ") " + CppAsString2(RELKIND_MATVIEW) "," + CppAsString2(RELKIND_PARTITIONED_TABLE) ") " " AND n.nspname = "); deparseStringLiteral(&buf, stmt->remote_schema); + /* Partitions are supported since Postgres 10 */ + if (PQserverVersion(conn) >= 100000) + appendStringInfoString(&buf, " AND NOT c.relispartition "); + /* Apply restrictions for LIMIT TO and EXCEPT */ if (stmt->list_type == FDW_IMPORT_SCHEMA_LIMIT_TO || stmt->list_type == FDW_IMPORT_SCHEMA_EXCEPT) diff --git a/contrib/postgres_fdw/sql/postgres_fdw.sql b/contrib/postgres_fdw/sql/postgres_fdw.sql index 8f3edc13e1..cf70ca2c01 100644 --- a/contrib/postgres_fdw/sql/postgres_fdw.sql +++ b/contrib/postgres_fdw/sql/postgres_fdw.sql @@ -1618,6 +1618,9 @@ CREATE TABLE import_source.t3 (c1 timestamptz default now(), c2 typ1); CREATE TABLE import_source."x 4" (c1 float8, "C 2" text, c3 varchar(42)); CREATE TABLE import_source."x 5" (c1 float8); 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_part PARTITION OF import_source.t4 + FOR VALUES FROM (1) TO (100); CREATE SCHEMA import_dest1; IMPORT FOREIGN SCHEMA import_source FROM SERVER loopback INTO import_dest1; diff --git a/doc/src/sgml/postgres-fdw.sgml b/doc/src/sgml/postgres-fdw.sgml index 7a9b655d36..3dfc0f84ed 100644 --- a/doc/src/sgml/postgres-fdw.sgml +++ b/doc/src/sgml/postgres-fdw.sgml @@ -425,6 +425,16 @@ For more detail about the treatment of CHECK constraints on foreign tables, see . + + + Tables or foreign tables which are partitions of some other table are + automatically excluded. Partitioned tables are imported, unless they + are a partition of some other table. Since all data can be accessed + through the partitioned table which is the root of the partitioning + hierarchy, this approach should allow access to all the data without + creating extra objects. + +