Disallow COPY FREEZE on foreign tables.
authorNathan Bossart <nathan@postgresql.org>
Thu, 6 Feb 2025 21:23:40 +0000 (15:23 -0600)
committerNathan Bossart <nathan@postgresql.org>
Thu, 6 Feb 2025 21:23:40 +0000 (15:23 -0600)
This didn't actually work: the COPY succeeds, but the FREEZE
optimization isn't applied.  There doesn't seem to be an easy way
to support FREEZE on foreign tables, so let's follow the precedent
established by commit 5c9a5513a3 by raising an error early.  This
is arguably a bug fix, but due to the lack of reports, the minimal
discussion on the mailing list, and the potential to break existing
scripts, I am not back-patching it for now.

Author: Sami Imseih <samimseih@gmail.com>
Reviewed-by: Zhang Mingli <zmlpostgres@gmail.com>
Discussion: https://postgr.es/m/CAA5RZ0ujeNgKpE3OrLtR%3DeJGa5LkGMekFzQTwjgw%3DrzaLufQLQ%40mail.gmail.com

doc/src/sgml/ref/copy.sgml
src/backend/commands/copyfrom.c
src/test/regress/expected/copy.out
src/test/regress/sql/copy.sql

index 8394402f0961d6cde3042e3f8bfb34780cc729f5..df093da97c5ed31a9605024fb2fe33e81fd0d3da 100644 (file)
@@ -237,7 +237,7 @@ COPY { <replaceable class="parameter">table_name</replaceable> [ ( <replaceable
       or truncated in the current subtransaction, there are no cursors
       open and there are no older snapshots held by this transaction.  It is
       currently not possible to perform a <command>COPY FREEZE</command> on
-      a partitioned table.
+      a partitioned table or foreign table.
       This option is only allowed in <command>COPY FROM</command>.
      </para>
      <para>
index 0cbd05f56028872451f2a06b71bcdefa3c329db7..b70f4691b72f463cf895d869c4601b8c5aa09409 100644 (file)
@@ -740,6 +740,12 @@ CopyFrom(CopyFromState cstate)
                     errmsg("cannot perform COPY FREEZE on a partitioned table")));
        }
 
+       /* There's currently no support for COPY FREEZE on foreign tables. */
+       if (cstate->rel->rd_rel->relkind == RELKIND_FOREIGN_TABLE)
+           ereport(ERROR,
+                   (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+                    errmsg("cannot perform COPY FREEZE on a foreign table")));
+
        /*
         * Tolerate one registration for the benefit of FirstXactSnapshot.
         * Scan-bearing queries generally create at least two registrations,
index f554d42c84cdb76a25544cfdb224a1910db1b62f..e69e34c69b878a8588a588cabbfd6f7be3d1b1bf 100644 (file)
@@ -325,3 +325,11 @@ SELECT tableoid::regclass, id % 2 = 0 is_even, count(*) from parted_si GROUP BY
 (2 rows)
 
 DROP TABLE parted_si;
+-- ensure COPY FREEZE errors for foreign tables
+begin;
+create foreign data wrapper copytest_wrapper;
+create server copytest_server foreign data wrapper copytest_wrapper;
+create foreign table copytest_foreign_table (a int) server copytest_server;
+copy copytest_foreign_table from stdin (freeze);
+ERROR:  cannot perform COPY FREEZE on a foreign table
+rollback;
index f1699b66b0442ce249e702582e22262ef9c16067..895479d2d0fd09d8ba6993c72ef2bc1d5ee5b4b9 100644 (file)
@@ -348,3 +348,13 @@ COPY parted_si(id, data) FROM :'filename';
 SELECT tableoid::regclass, id % 2 = 0 is_even, count(*) from parted_si GROUP BY 1, 2 ORDER BY 1;
 
 DROP TABLE parted_si;
+
+-- ensure COPY FREEZE errors for foreign tables
+begin;
+create foreign data wrapper copytest_wrapper;
+create server copytest_server foreign data wrapper copytest_wrapper;
+create foreign table copytest_foreign_table (a int) server copytest_server;
+copy copytest_foreign_table from stdin (freeze);
+1
+\.
+rollback;