]> granicus.if.org Git - postgresql/commitdiff
postgres_fdw: Teach IMPORT FOREIGN SCHEMA about partitioning.
authorRobert Haas <rhaas@postgresql.org>
Fri, 31 Mar 2017 19:01:35 +0000 (15:01 -0400)
committerRobert Haas <rhaas@postgresql.org>
Fri, 31 Mar 2017 19:06:34 +0000 (15:06 -0400)
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

contrib/postgres_fdw/expected/postgres_fdw.out
contrib/postgres_fdw/postgres_fdw.c
contrib/postgres_fdw/sql/postgres_fdw.sql
doc/src/sgml/postgres-fdw.sgml

index a466bf2079a482efdec6d1192a82cb4efd496521..1a9e6c87f6c3c20bbd5947c96040e67d81b69a80 100644 (file)
@@ -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;
index 03f14800b0e375cb83e1260fb1c05c4aad8a7831..54b938734a87bced4659a41de2bc7c151a6a5017 100644 (file)
@@ -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)
index 8f3edc13e16b3997a7e016d9ee8f65af3880248d..cf70ca2c01e094d850f5811e75063a1af09e5dd1 100644 (file)
@@ -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;
index 7a9b655d366b4984168e75fc23a96e447b1c36db..3dfc0f84ed3d3b6df72bbf0336663aa10b796bae 100644 (file)
     For more detail about the treatment of <literal>CHECK</> constraints on
     foreign tables, see <xref linkend="sql-createforeigntable">.
    </para>
+
+   <para>
+    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.
+   </para>
+
   </sect3>
  </sect2>