aboutsummaryrefslogtreecommitdiff
path: root/src/backend/commands/copy.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/commands/copy.c')
-rw-r--r--src/backend/commands/copy.c29
1 files changed, 27 insertions, 2 deletions
diff --git a/src/backend/commands/copy.c b/src/backend/commands/copy.c
index a61f3bca4fb..7e5249e1e20 100644
--- a/src/backend/commands/copy.c
+++ b/src/backend/commands/copy.c
@@ -2416,11 +2416,20 @@ CopyFrom(CopyState cstate)
* go into pages containing tuples from any other transactions --- but this
* must be the case if we have a new table or new relfilenode, so we need
* no additional work to enforce that.
+ *
+ * We currently don't support this optimization if the COPY target is a
+ * partitioned table as we currently only lazily initialize partition
+ * information when routing the first tuple to the partition. We cannot
+ * know at this stage if we can perform this optimization. It should be
+ * 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.
*----------
*/
/* createSubid is creation check, newRelfilenodeSubid is truncation check */
- if (cstate->rel->rd_createSubid != InvalidSubTransactionId ||
- cstate->rel->rd_newRelfilenodeSubid != InvalidSubTransactionId)
+ if (cstate->rel->rd_rel->relkind != RELKIND_PARTITIONED_TABLE &&
+ (cstate->rel->rd_createSubid != InvalidSubTransactionId ||
+ cstate->rel->rd_newRelfilenodeSubid != InvalidSubTransactionId))
{
hi_options |= HEAP_INSERT_SKIP_FSM;
if (!XLogIsNeeded())
@@ -2441,6 +2450,22 @@ CopyFrom(CopyState cstate)
if (cstate->freeze)
{
/*
+ * We currently disallow COPY FREEZE on partitioned tables. The
+ * reason for this is that we've simply not yet opened the partitions
+ * to determine if the optimization can be applied to them. We could
+ * go and open them all here, but doing so may be quite a costly
+ * overhead for small copies. In any case, we may just end up routing
+ * tuples to a small number of partitions. It seems better just to
+ * raise an ERROR for partitioned tables.
+ */
+ if (cstate->rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
+ {
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot perform FREEZE on a partitioned table")));
+ }
+
+ /*
* Tolerate one registration for the benefit of FirstXactSnapshot.
* Scan-bearing queries generally create at least two registrations,
* though relying on that is fragile, as is ignoring ActiveSnapshot.