Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 5c9a551

Browse files
committed
Disallow COPY FREEZE on partitioned tables
This didn't actually work: COPY would fail to flush the right files, and instead would try to flush a non-existing file, causing the whole transaction to fail. Cope by raising an error as soon as the command is sent instead, to avoid a nasty later surprise. Of course, it would be much better to make it work, but we don't have a patch for that yet, and we don't know if we'll want to backpatch one when we do. Reported-by: Tomas Vondra Author: David Rowley Reviewed-by: Amit Langote, Steve Singer, Tomas Vondra
1 parent fc47e99 commit 5c9a551

File tree

5 files changed

+44
-5
lines changed

5 files changed

+44
-5
lines changed

doc/src/sgml/perform.sgml

+2-2
Original file line numberDiff line numberDiff line change
@@ -1535,8 +1535,8 @@ SELECT * FROM x, y, a, b, c WHERE something AND somethingelse;
15351535
needs to be written, because in case of an error, the files
15361536
containing the newly loaded data will be removed anyway.
15371537
However, this consideration only applies when
1538-
<xref linkend="guc-wal-level"/> is <literal>minimal</literal> as all commands
1539-
must write WAL otherwise.
1538+
<xref linkend="guc-wal-level"/> is <literal>minimal</literal> for
1539+
non-partitioned tables as all commands must write WAL otherwise.
15401540
</para>
15411541

15421542
</sect2>

doc/src/sgml/ref/copy.sgml

+3-1
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,9 @@ COPY { <replaceable class="parameter">table_name</replaceable> [ ( <replaceable
224224
This is intended as a performance option for initial data loading.
225225
Rows will be frozen only if the table being loaded has been created
226226
or truncated in the current subtransaction, there are no cursors
227-
open and there are no older snapshots held by this transaction.
227+
open and there are no older snapshots held by this transaction. It is
228+
currently not possible to perform a <command>COPY FREEZE</command> on
229+
a partitioned table.
228230
</para>
229231
<para>
230232
Note that all other sessions will immediately be able to see the data

src/backend/commands/copy.c

+27-2
Original file line numberDiff line numberDiff line change
@@ -2416,11 +2416,20 @@ CopyFrom(CopyState cstate)
24162416
* go into pages containing tuples from any other transactions --- but this
24172417
* must be the case if we have a new table or new relfilenode, so we need
24182418
* no additional work to enforce that.
2419+
*
2420+
* We currently don't support this optimization if the COPY target is a
2421+
* partitioned table as we currently only lazily initialize partition
2422+
* information when routing the first tuple to the partition. We cannot
2423+
* know at this stage if we can perform this optimization. It should be
2424+
* possible to improve on this, but it does mean maintaining heap insert
2425+
* option flags per partition and setting them when we first open the
2426+
* partition.
24192427
*----------
24202428
*/
24212429
/* createSubid is creation check, newRelfilenodeSubid is truncation check */
2422-
if (cstate->rel->rd_createSubid != InvalidSubTransactionId ||
2423-
cstate->rel->rd_newRelfilenodeSubid != InvalidSubTransactionId)
2430+
if (cstate->rel->rd_rel->relkind != RELKIND_PARTITIONED_TABLE &&
2431+
(cstate->rel->rd_createSubid != InvalidSubTransactionId ||
2432+
cstate->rel->rd_newRelfilenodeSubid != InvalidSubTransactionId))
24242433
{
24252434
hi_options |= HEAP_INSERT_SKIP_FSM;
24262435
if (!XLogIsNeeded())
@@ -2440,6 +2449,22 @@ CopyFrom(CopyState cstate)
24402449
*/
24412450
if (cstate->freeze)
24422451
{
2452+
/*
2453+
* We currently disallow COPY FREEZE on partitioned tables. The
2454+
* reason for this is that we've simply not yet opened the partitions
2455+
* to determine if the optimization can be applied to them. We could
2456+
* go and open them all here, but doing so may be quite a costly
2457+
* overhead for small copies. In any case, we may just end up routing
2458+
* tuples to a small number of partitions. It seems better just to
2459+
* raise an ERROR for partitioned tables.
2460+
*/
2461+
if (cstate->rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
2462+
{
2463+
ereport(ERROR,
2464+
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2465+
errmsg("cannot perform FREEZE on a partitioned table")));
2466+
}
2467+
24432468
/*
24442469
* Tolerate one registration for the benefit of FirstXactSnapshot.
24452470
* Scan-bearing queries generally create at least two registrations,

src/test/regress/input/copy.source

+6
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,12 @@ truncate parted_copytest;
159159

160160
copy parted_copytest from '@abs_builddir@/results/parted_copytest.csv';
161161

162+
-- Ensure COPY FREEZE errors for partitioned tables.
163+
begin;
164+
truncate parted_copytest;
165+
copy parted_copytest from '@abs_builddir@/results/parted_copytest.csv' (freeze);
166+
rollback;
167+
162168
select tableoid::regclass,count(*),sum(a) from parted_copytest
163169
group by tableoid order by tableoid::regclass::name;
164170

src/test/regress/output/copy.source

+6
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,12 @@ insert into parted_copytest select x,1,'One' from generate_series(1011,1020) x;
113113
copy (select * from parted_copytest order by a) to '@abs_builddir@/results/parted_copytest.csv';
114114
truncate parted_copytest;
115115
copy parted_copytest from '@abs_builddir@/results/parted_copytest.csv';
116+
-- Ensure COPY FREEZE errors for partitioned tables.
117+
begin;
118+
truncate parted_copytest;
119+
copy parted_copytest from '@abs_builddir@/results/parted_copytest.csv' (freeze);
120+
ERROR: cannot perform FREEZE on a partitioned table
121+
rollback;
116122
select tableoid::regclass,count(*),sum(a) from parted_copytest
117123
group by tableoid order by tableoid::regclass::name;
118124
tableoid | count | sum

0 commit comments

Comments
 (0)