no_heap_opt_fdw_copy.patch
text/x-patch
Filename: no_heap_opt_fdw_copy.patch
Type: text/x-patch
Part: 0
Patch
Format: unified
| File | + | − |
|---|---|---|
| contrib/postgres_fdw/Makefile | 2 | 0 |
| contrib/postgres_fdw/t/001_copy_same_txn_rem.pl | 77 | 0 |
| src/backend/commands/copy.c | 1 | 0 |
diff --git a/contrib/postgres_fdw/Makefile b/contrib/postgres_fdw/Makefile
index 85394b4f1f..681f3bff2b 100644
--- a/contrib/postgres_fdw/Makefile
+++ b/contrib/postgres_fdw/Makefile
@@ -4,6 +4,8 @@ MODULE_big = postgres_fdw
OBJS = postgres_fdw.o option.o deparse.o connection.o shippable.o $(WIN32RES)
PGFILEDESC = "postgres_fdw - foreign data wrapper for PostgreSQL"
+TAP_TESTS = 1
+
PG_CPPFLAGS = -I$(libpq_srcdir)
SHLIB_LINK_INTERNAL = $(libpq)
diff --git a/contrib/postgres_fdw/t/001_copy_same_txn_rem.pl b/contrib/postgres_fdw/t/001_copy_same_txn_rem.pl
new file mode 100644
index 0000000000..66f9c76b0d
--- /dev/null
+++ b/contrib/postgres_fdw/t/001_copy_same_txn_rem.pl
@@ -0,0 +1,77 @@
+# Test COPY FROM inside a transaction along a table creation for multiple WAL levels
+#
+# COPY done to foreign tables should not use heap_insert options.
+# Regression test for BUG#15552
+use strict;
+use warnings;
+
+use PostgresNode;
+use TestLib;
+use Test::More tests => 4;
+
+# Wrapper routine tunable for wal_level.
+sub run_copy_same_txn_wal
+{
+ my $wal_level = shift;
+
+ my $node = get_new_node("node_$wal_level");
+ $node->init;
+ $node->append_conf('postgresql.conf', qq(
+wal_level = $wal_level
+));
+ $node->start;
+
+ my ($database,$port);
+
+ $database = $node->safe_psql('postgres', "SELECT current_database();");
+ $port = $node->safe_psql('postgres', "SELECT current_setting('port');");
+
+ $node->safe_psql('postgres', "
+ CREATE EXTENSION postgres_fdw;
+
+ CREATE SERVER testserver FOREIGN DATA WRAPPER postgres_fdw;
+ DO \$d\$
+ BEGIN
+ EXECUTE \$c\$
+ CREATE SERVER loopback FOREIGN DATA WRAPPER postgres_fdw
+ OPTIONS (dbname '$database', port '$port')
+ \$c\$;
+ END;
+ \$d\$;
+ CREATE USER MAPPING FOR public SERVER testserver
+ OPTIONS (user 'value', password 'value');
+ CREATE USER MAPPING FOR CURRENT_USER SERVER loopback;
+
+ CREATE TABLE loc (a INT, b TEXT);");
+
+ my $stderr;
+ $node->psql('postgres', "
+ BEGIN;
+ CREATE FOREIGN TABLE test_copy_same_txn_rem (a INT, b TEXT) SERVER
+ loopback OPTIONS(table_name 'loc');
+ COPY test_copy_same_txn_rem FROM STDIN DELIMITER ',';
+1,f
+\\\.
+ COMMIT;",
+ stderr => \$stderr
+ );
+
+ is($stderr, '', "Ensure no error is emitted");
+
+ my $stdout;
+ $node->psql('postgres', "
+ SELECT * FROM test_copy_same_txn_rem;",
+ stdout => \$stdout
+ );
+
+ is($stdout, "1|f", "Verify table content");
+
+ $node->stop('immediate');
+ $node->teardown_node;
+ $node->clean_node;
+ return;
+}
+
+# Run same test suite for multiple wal_level values.
+run_copy_same_txn_wal("replica");
+run_copy_same_txn_wal("minimal");
diff --git a/src/backend/commands/copy.c b/src/backend/commands/copy.c
index 4311e16007..fb7acc361e 100644
--- a/src/backend/commands/copy.c
+++ b/src/backend/commands/copy.c
@@ -2401,6 +2401,7 @@ CopyFrom(CopyState cstate)
*/
/* createSubid is creation check, newRelfilenodeSubid is truncation check */
if (cstate->rel->rd_rel->relkind != RELKIND_PARTITIONED_TABLE &&
+ cstate->rel->rd_rel->relkind != RELKIND_FOREIGN_TABLE &&
(cstate->rel->rd_createSubid != InvalidSubTransactionId ||
cstate->rel->rd_newRelfilenodeSubid != InvalidSubTransactionId))
{