diff --git a/contrib/postgres_fdw/expected/postgres_fdw.out b/contrib/postgres_fdw/expected/postgres_fdw.out index 97de293f838..5d60ead91cc 100644 --- a/contrib/postgres_fdw/expected/postgres_fdw.out +++ b/contrib/postgres_fdw/expected/postgres_fdw.out @@ -7883,6 +7883,22 @@ drop trigger rem2_trig_row_before on rem2; drop trigger rem2_trig_row_after on rem2; drop trigger loc2_trig_row_before_insert on loc2; delete from rem2; +-- test COPY FROM with foreign table created in the same transaction +create table loc3 (f1 int, f2 text); +begin; +create foreign table rem3 (f1 int, f2 text) + server loopback options(table_name 'loc3'); +copy rem3 from stdin; +commit; +select * from rem3; + f1 | f2 +----+----- + 1 | foo + 2 | bar +(2 rows) + +drop foreign table rem3; +drop table loc3; -- =================================================================== -- test IMPORT FOREIGN SCHEMA -- =================================================================== diff --git a/contrib/postgres_fdw/sql/postgres_fdw.sql b/contrib/postgres_fdw/sql/postgres_fdw.sql index 88b9f5c42d6..cef42d26f19 100644 --- a/contrib/postgres_fdw/sql/postgres_fdw.sql +++ b/contrib/postgres_fdw/sql/postgres_fdw.sql @@ -2085,6 +2085,20 @@ drop trigger loc2_trig_row_before_insert on loc2; delete from rem2; +-- test COPY FROM with foreign table created in the same transaction +create table loc3 (f1 int, f2 text); +begin; +create foreign table rem3 (f1 int, f2 text) + server loopback options(table_name 'loc3'); +copy rem3 from stdin; +1 foo +2 bar +\. +commit; +select * from rem3; +drop foreign table rem3; +drop table loc3; + -- =================================================================== -- test IMPORT FOREIGN SCHEMA -- =================================================================== diff --git a/src/backend/commands/copy.c b/src/backend/commands/copy.c index 25d19a51182..f4653485e2b 100644 --- a/src/backend/commands/copy.c +++ b/src/backend/commands/copy.c @@ -2423,10 +2423,17 @@ CopyFrom(CopyState cstate) * possible to improve on this, but it does mean maintaining heap insert * option flags per partition and setting them when we first open the * partition. + * + * This optimization is not supported for relation types which do not + * have any physical storage, with foreign tables and views using + * INSTEAD OF triggers entering in this category. Partitioned tables + * are not supported as per the description above. *---------- */ /* createSubid is creation check, newRelfilenodeSubid is truncation check */ - if (cstate->rel->rd_rel->relkind != RELKIND_PARTITIONED_TABLE && + if (cstate->rel->rd_rel->relkind != RELKIND_FOREIGN_TABLE && + cstate->rel->rd_rel->relkind != RELKIND_PARTITIONED_TABLE && + cstate->rel->rd_rel->relkind != RELKIND_VIEW && (cstate->rel->rd_createSubid != InvalidSubTransactionId || cstate->rel->rd_newRelfilenodeSubid != InvalidSubTransactionId)) { diff --git a/src/test/regress/expected/copy2.out b/src/test/regress/expected/copy2.out index e606a5fda47..063522e6629 100644 --- a/src/test/regress/expected/copy2.out +++ b/src/test/regress/expected/copy2.out @@ -557,6 +557,23 @@ SELECT * FROM instead_of_insert_tbl; 1 | test1 (1 row) +-- Test of COPY optimization with view using INSTEAD OF INSERT +-- trigger when relation is created in the same transaction as +-- when COPY is executed. +BEGIN; +CREATE VIEW instead_of_insert_tbl_view_2 as select ''::text as str; +CREATE TRIGGER trig_instead_of_insert_tbl_view_2 + INSTEAD OF INSERT ON instead_of_insert_tbl_view_2 + FOR EACH ROW EXECUTE PROCEDURE fun_instead_of_insert_tbl(); +COPY instead_of_insert_tbl_view_2 FROM stdin; +SELECT * FROM instead_of_insert_tbl; + id | name +----+------- + 1 | test1 + 2 | test1 +(2 rows) + +COMMIT; -- clean up DROP TABLE forcetest; DROP TABLE vistest; @@ -569,4 +586,5 @@ DROP FUNCTION fn_x_before(); DROP FUNCTION fn_x_after(); DROP TABLE instead_of_insert_tbl; DROP VIEW instead_of_insert_tbl_view; +DROP VIEW instead_of_insert_tbl_view_2; DROP FUNCTION fun_instead_of_insert_tbl(); diff --git a/src/test/regress/sql/copy2.sql b/src/test/regress/sql/copy2.sql index f3a6d228fae..3022a07d3c2 100644 --- a/src/test/regress/sql/copy2.sql +++ b/src/test/regress/sql/copy2.sql @@ -411,6 +411,21 @@ test1 SELECT * FROM instead_of_insert_tbl; +-- Test of COPY optimization with view using INSTEAD OF INSERT +-- trigger when relation is created in the same transaction as +-- when COPY is executed. +BEGIN; +CREATE VIEW instead_of_insert_tbl_view_2 as select ''::text as str; +CREATE TRIGGER trig_instead_of_insert_tbl_view_2 + INSTEAD OF INSERT ON instead_of_insert_tbl_view_2 + FOR EACH ROW EXECUTE PROCEDURE fun_instead_of_insert_tbl(); + +COPY instead_of_insert_tbl_view_2 FROM stdin; +test1 +\. + +SELECT * FROM instead_of_insert_tbl; +COMMIT; -- clean up DROP TABLE forcetest; @@ -424,4 +439,5 @@ DROP FUNCTION fn_x_before(); DROP FUNCTION fn_x_after(); DROP TABLE instead_of_insert_tbl; DROP VIEW instead_of_insert_tbl_view; +DROP VIEW instead_of_insert_tbl_view_2; DROP FUNCTION fun_instead_of_insert_tbl();