Hi, While reviewing copy from I identified few improvements for copy from that can be done : a) copy from stdin copies lesser amount of data to buffer even though space is available in buffer because minread was passed as 1 to CopyGetData, Hence it only reads until the data read from libpq is less than minread. This can be fixed by passing the actual space available in buffer, this reduces the unnecessary frequent calls to CopyGetData. b) CopyMultiInsertInfoNextFreeSlot had an unused function parameter that is not being used, it can be removed. c) Copy from reads header line and do nothing for the header line, we need not clear EOL & need not convert to server encoding for the header line.
Attached patch has the changes for the same. Thoughts? Regards, Vignesh EnterpriseDB: http://www.enterprisedb.com
From b86edd9bf4f4350598a0518996e64f40f13aea21 Mon Sep 17 00:00:00 2001 From: Vignesh C <vignes...@gmail.com> Date: Wed, 1 Jul 2020 17:51:51 +0530 Subject: [PATCH] Improvements in copy from. There are 3 improvements for copy from in this patch which is detailed below: a) copy from stdin copies lesser amount of data to buffer even though space is available in buffer because minread was passed as 1 to CopyGetData, fixed it by passing the actual space available in buffer, this reduces the frequent call to CopyGetData. b) CopyMultiInsertInfoNextFreeSlot had an unused function parameter, this is not being used, it has been removed. c) Copy from reads header line and does nothing for the read line, we need not clear EOL & need not convert to server encoding for the header line. --- src/backend/commands/copy.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/backend/commands/copy.c b/src/backend/commands/copy.c index 3e199bd..dfb7d92 100644 --- a/src/backend/commands/copy.c +++ b/src/backend/commands/copy.c @@ -793,6 +793,7 @@ CopyLoadRawBuf(CopyState cstate) { int nbytes; int inbytes; + int minread = 1; if (cstate->raw_buf_index < cstate->raw_buf_len) { @@ -804,8 +805,11 @@ CopyLoadRawBuf(CopyState cstate) else nbytes = 0; /* no data need be saved */ + if (cstate->copy_dest == COPY_NEW_FE) + minread = RAW_BUF_SIZE - nbytes; + inbytes = CopyGetData(cstate, cstate->raw_buf + nbytes, - 1, RAW_BUF_SIZE - nbytes); + minread, RAW_BUF_SIZE - nbytes); nbytes += inbytes; cstate->raw_buf[nbytes] = '\0'; cstate->raw_buf_index = 0; @@ -2603,8 +2607,7 @@ CopyMultiInsertInfoCleanup(CopyMultiInsertInfo *miinfo) * Callers must ensure that the buffer is not full. */ static inline TupleTableSlot * -CopyMultiInsertInfoNextFreeSlot(CopyMultiInsertInfo *miinfo, - ResultRelInfo *rri) +CopyMultiInsertInfoNextFreeSlot(ResultRelInfo *rri) { CopyMultiInsertBuffer *buffer = rri->ri_CopyMultiInsertBuffer; int nused = buffer->nused; @@ -2969,8 +2972,7 @@ CopyFrom(CopyState cstate) Assert(resultRelInfo == target_resultRelInfo); Assert(insertMethod == CIM_MULTI); - myslot = CopyMultiInsertInfoNextFreeSlot(&multiInsertInfo, - resultRelInfo); + myslot = CopyMultiInsertInfoNextFreeSlot(resultRelInfo); } /* @@ -3117,8 +3119,7 @@ CopyFrom(CopyState cstate) /* no other path available for partitioned table */ Assert(insertMethod == CIM_MULTI_CONDITIONAL); - batchslot = CopyMultiInsertInfoNextFreeSlot(&multiInsertInfo, - resultRelInfo); + batchslot = CopyMultiInsertInfoNextFreeSlot(resultRelInfo); if (map != NULL) myslot = execute_attr_map_slot(map->attrMap, myslot, @@ -3856,7 +3857,7 @@ CopyReadLine(CopyState cstate) } while (CopyLoadRawBuf(cstate)); } } - else + else if (!(cstate->cur_lineno == 0 && cstate->header_line)) { /* * If we didn't hit EOF, then we must have transferred the EOL marker @@ -3890,8 +3891,9 @@ CopyReadLine(CopyState cstate) } } - /* Done reading the line. Convert it to server encoding. */ - if (cstate->need_transcoding) + /* Done reading the line. Convert it to server encoding if not header. */ + if (cstate->need_transcoding && + !(cstate->cur_lineno == 0 && cstate->header_line)) { char *cvt; -- 1.8.3.1