Skip to content

Commit 4de6024

Browse files
committed
Fix missing call to table_finish_bulk_insert during COPY
86b8504 abstracted calls to heap functions in COPY FROM to support a generic table AM. However, when performing a copy into a partitioned table, this commit neglected to call table_finish_bulk_insert for each partition. Before 86b8504, when we always called the heap functions, there was no need to call heapam_finish_bulk_insert for partitions since it only did any work when performing a copy without WAL. For partitioned tables, this was unsupported anyway, so there was no issue. With pluggable storage, we can't make any assumptions about what the table AM might want to do in its equivalent function, so we'd better ensure we always call table_finish_bulk_insert each partition that's received a row. For now, we make the table_finish_bulk_insert call whenever we evict a CopyMultiInsertBuffer out of the CopyMultiInsertInfo. This does mean that it's possible that we call table_finish_bulk_insert multiple times per partition, which is not a problem other than being an inefficiency. Improving this requires a more invasive patch, so let's leave that for another day. In passing, move the table_finish_bulk_insert for the target of the COPY command so that it's only called when we're actually performing bulk inserts. We don't need to call this when inserting 1 row at a time. Reported-by: Robert Haas Discussion: https://postgr.es/m/CA+TgmoYK=6BpxiJ0tN-p9wtH0BTAfbdxzHhwou0mdud4+BkYuQ@mail.gmail.com
1 parent 95bbe5d commit 4de6024

File tree

1 file changed

+14
-7
lines changed

1 file changed

+14
-7
lines changed

src/backend/commands/copy.c

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2518,7 +2518,8 @@ CopyMultiInsertBufferFlush(CopyMultiInsertInfo *miinfo,
25182518
* The buffer must be flushed before cleanup.
25192519
*/
25202520
static inline void
2521-
CopyMultiInsertBufferCleanup(CopyMultiInsertBuffer *buffer)
2521+
CopyMultiInsertBufferCleanup(CopyMultiInsertInfo *miinfo,
2522+
CopyMultiInsertBuffer *buffer)
25222523
{
25232524
int i;
25242525

@@ -2534,6 +2535,9 @@ CopyMultiInsertBufferCleanup(CopyMultiInsertBuffer *buffer)
25342535
for (i = 0; i < MAX_BUFFERED_TUPLES && buffer->slots[i] != NULL; i++)
25352536
ExecDropSingleTupleTableSlot(buffer->slots[i]);
25362537

2538+
table_finish_bulk_insert(buffer->resultRelInfo->ri_RelationDesc,
2539+
miinfo->ti_options);
2540+
25372541
pfree(buffer);
25382542
}
25392543

@@ -2585,7 +2589,7 @@ CopyMultiInsertInfoFlush(CopyMultiInsertInfo *miinfo, ResultRelInfo *curr_rri)
25852589
buffer = (CopyMultiInsertBuffer *) linitial(miinfo->multiInsertBuffers);
25862590
}
25872591

2588-
CopyMultiInsertBufferCleanup(buffer);
2592+
CopyMultiInsertBufferCleanup(miinfo, buffer);
25892593
miinfo->multiInsertBuffers = list_delete_first(miinfo->multiInsertBuffers);
25902594
}
25912595
}
@@ -2599,7 +2603,7 @@ CopyMultiInsertInfoCleanup(CopyMultiInsertInfo *miinfo)
25992603
ListCell *lc;
26002604

26012605
foreach(lc, miinfo->multiInsertBuffers)
2602-
CopyMultiInsertBufferCleanup(lfirst(lc));
2606+
CopyMultiInsertBufferCleanup(miinfo, lfirst(lc));
26032607

26042608
list_free(miinfo->multiInsertBuffers);
26052609
}
@@ -3321,9 +3325,6 @@ CopyFrom(CopyState cstate)
33213325
{
33223326
if (!CopyMultiInsertInfoIsEmpty(&multiInsertInfo))
33233327
CopyMultiInsertInfoFlush(&multiInsertInfo, NULL);
3324-
3325-
/* Tear down the multi-insert buffer data */
3326-
CopyMultiInsertInfoCleanup(&multiInsertInfo);
33273328
}
33283329

33293330
/* Done, clean up */
@@ -3366,7 +3367,13 @@ CopyFrom(CopyState cstate)
33663367

33673368
FreeExecutorState(estate);
33683369

3369-
table_finish_bulk_insert(cstate->rel, ti_options);
3370+
if (insertMethod != CIM_SINGLE)
3371+
{
3372+
table_finish_bulk_insert(cstate->rel, ti_options);
3373+
3374+
/* Tear down the multi-insert buffer data */
3375+
CopyMultiInsertInfoCleanup(&multiInsertInfo);
3376+
}
33703377

33713378
return processed;
33723379
}

0 commit comments

Comments
 (0)