diff options
Diffstat (limited to 'src/backend/commands')
-rw-r--r-- | src/backend/commands/async.c | 3 | ||||
-rw-r--r-- | src/backend/commands/copyfrom.c | 7 | ||||
-rw-r--r-- | src/backend/commands/copyfromparse.c | 83 | ||||
-rw-r--r-- | src/backend/commands/copyto.c | 127 |
4 files changed, 52 insertions, 168 deletions
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index 42b232d98b1..4b16fb56825 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -2311,8 +2311,7 @@ NotifyMyFrontEnd(const char *channel, const char *payload, int32 srcPid) pq_beginmessage(&buf, 'A'); pq_sendint32(&buf, srcPid); pq_sendstring(&buf, channel); - if (PG_PROTOCOL_MAJOR(FrontendProtocol) >= 3) - pq_sendstring(&buf, payload); + pq_sendstring(&buf, payload); pq_endmessage(&buf); /* diff --git a/src/backend/commands/copyfrom.c b/src/backend/commands/copyfrom.c index 796ca7b3f7b..f05e2d23476 100644 --- a/src/backend/commands/copyfrom.c +++ b/src/backend/commands/copyfrom.c @@ -1126,13 +1126,6 @@ CopyFrom(CopyFromState cstate) MemoryContextSwitchTo(oldcontext); - /* - * In the old protocol, tell pqcomm that we can process normal protocol - * messages again. - */ - if (cstate->copy_src == COPY_OLD_FE) - pq_endmsgread(); - /* Execute AFTER STATEMENT insertion triggers */ ExecASInsertTriggers(estate, target_resultRelInfo, cstate->transition_capture); diff --git a/src/backend/commands/copyfromparse.c b/src/backend/commands/copyfromparse.c index 315b16fd7af..ce24a1528bd 100644 --- a/src/backend/commands/copyfromparse.c +++ b/src/backend/commands/copyfromparse.c @@ -124,35 +124,19 @@ static int CopyReadBinaryData(CopyFromState cstate, char *dest, int nbytes); void ReceiveCopyBegin(CopyFromState cstate) { - if (PG_PROTOCOL_MAJOR(FrontendProtocol) >= 3) - { - /* new way */ - StringInfoData buf; - int natts = list_length(cstate->attnumlist); - int16 format = (cstate->opts.binary ? 1 : 0); - int i; - - pq_beginmessage(&buf, 'G'); - pq_sendbyte(&buf, format); /* overall format */ - pq_sendint16(&buf, natts); - for (i = 0; i < natts; i++) - pq_sendint16(&buf, format); /* per-column formats */ - pq_endmessage(&buf); - cstate->copy_src = COPY_NEW_FE; - cstate->fe_msgbuf = makeStringInfo(); - } - else - { - /* old way */ - if (cstate->opts.binary) - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("COPY BINARY is not supported to stdout or from stdin"))); - pq_putemptymessage('G'); - /* any error in old protocol will make us lose sync */ - pq_startmsgread(); - cstate->copy_src = COPY_OLD_FE; - } + StringInfoData buf; + int natts = list_length(cstate->attnumlist); + int16 format = (cstate->opts.binary ? 1 : 0); + int i; + + pq_beginmessage(&buf, 'G'); + pq_sendbyte(&buf, format); /* overall format */ + pq_sendint16(&buf, natts); + for (i = 0; i < natts; i++) + pq_sendint16(&buf, format); /* per-column formats */ + pq_endmessage(&buf); + cstate->copy_src = COPY_FRONTEND; + cstate->fe_msgbuf = makeStringInfo(); /* We *must* flush here to ensure FE knows it can send. */ pq_flush(); } @@ -228,25 +212,7 @@ CopyGetData(CopyFromState cstate, void *databuf, int minread, int maxread) if (bytesread == 0) cstate->reached_eof = true; break; - case COPY_OLD_FE: - - /* - * We cannot read more than minread bytes (which in practice is 1) - * because old protocol doesn't have any clear way of separating - * the COPY stream from following data. This is slow, but not any - * slower than the code path was originally, and we don't care - * much anymore about the performance of old protocol. - */ - if (pq_getbytes((char *) databuf, minread)) - { - /* Only a \. terminator is legal EOF in old protocol */ - ereport(ERROR, - (errcode(ERRCODE_CONNECTION_FAILURE), - errmsg("unexpected EOF on client connection with an open transaction"))); - } - bytesread = minread; - break; - case COPY_NEW_FE: + case COPY_FRONTEND: while (maxread > 0 && bytesread < minread && !cstate->reached_eof) { int avail; @@ -619,21 +585,16 @@ NextCopyFrom(CopyFromState cstate, ExprContext *econtext, if (fld_count == -1) { /* - * Received EOF marker. In a V3-protocol copy, wait for the - * protocol-level EOF, and complain if it doesn't come - * immediately. This ensures that we correctly handle CopyFail, - * if client chooses to send that now. - * - * Note that we MUST NOT try to read more data in an old-protocol - * copy, since there is no protocol-level EOF marker then. We - * could go either way for copy from file, but choose to throw - * error if there's data after the EOF marker, for consistency - * with the new-protocol case. + * Received EOF marker. Wait for the protocol-level EOF, and + * complain if it doesn't come immediately. In COPY FROM STDIN, + * this ensures that we correctly handle CopyFail, if client + * chooses to send that now. When copying from file, we could + * ignore the rest of the file like in text mode, but we choose to + * be consistent with the COPY FROM STDIN case. */ char dummy; - if (cstate->copy_src != COPY_OLD_FE && - CopyReadBinaryData(cstate, &dummy, 1) > 0) + if (CopyReadBinaryData(cstate, &dummy, 1) > 0) ereport(ERROR, (errcode(ERRCODE_BAD_COPY_FILE_FORMAT), errmsg("received copy data after EOF marker"))); @@ -712,7 +673,7 @@ CopyReadLine(CopyFromState cstate) * after \. up to the protocol end of copy data. (XXX maybe better * not to treat \. as special?) */ - if (cstate->copy_src == COPY_NEW_FE) + if (cstate->copy_src == COPY_FRONTEND) { do { diff --git a/src/backend/commands/copyto.c b/src/backend/commands/copyto.c index e04ec1e331b..46155015cfd 100644 --- a/src/backend/commands/copyto.c +++ b/src/backend/commands/copyto.c @@ -50,8 +50,7 @@ typedef enum CopyDest { COPY_FILE, /* to file (or a piped program) */ - COPY_OLD_FE, /* to frontend (2.0 protocol) */ - COPY_NEW_FE, /* to frontend (3.0 protocol) */ + COPY_FRONTEND, /* to frontend */ } CopyDest; /* @@ -116,7 +115,6 @@ static const char BinarySignature[11] = "PGCOPY\n\377\r\n\0"; /* non-export function prototypes */ static void EndCopy(CopyToState cstate); static void ClosePipeToProgram(CopyToState cstate); -static uint64 CopyTo(CopyToState cstate); static void CopyOneRowTo(CopyToState cstate, TupleTableSlot *slot); static void CopyAttributeOutText(CopyToState cstate, char *string); static void CopyAttributeOutCSV(CopyToState cstate, char *string, @@ -140,53 +138,27 @@ static void CopySendInt16(CopyToState cstate, int16 val); static void SendCopyBegin(CopyToState cstate) { - if (PG_PROTOCOL_MAJOR(FrontendProtocol) >= 3) - { - /* new way */ - StringInfoData buf; - int natts = list_length(cstate->attnumlist); - int16 format = (cstate->opts.binary ? 1 : 0); - int i; - - pq_beginmessage(&buf, 'H'); - pq_sendbyte(&buf, format); /* overall format */ - pq_sendint16(&buf, natts); - for (i = 0; i < natts; i++) - pq_sendint16(&buf, format); /* per-column formats */ - pq_endmessage(&buf); - cstate->copy_dest = COPY_NEW_FE; - } - else - { - /* old way */ - if (cstate->opts.binary) - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("COPY BINARY is not supported to stdout or from stdin"))); - pq_putemptymessage('H'); - /* grottiness needed for old COPY OUT protocol */ - pq_startcopyout(); - cstate->copy_dest = COPY_OLD_FE; - } + StringInfoData buf; + int natts = list_length(cstate->attnumlist); + int16 format = (cstate->opts.binary ? 1 : 0); + int i; + + pq_beginmessage(&buf, 'H'); + pq_sendbyte(&buf, format); /* overall format */ + pq_sendint16(&buf, natts); + for (i = 0; i < natts; i++) + pq_sendint16(&buf, format); /* per-column formats */ + pq_endmessage(&buf); + cstate->copy_dest = COPY_FRONTEND; } static void SendCopyEnd(CopyToState cstate) { - if (cstate->copy_dest == COPY_NEW_FE) - { - /* Shouldn't have any unsent data */ - Assert(cstate->fe_msgbuf->len == 0); - /* Send Copy Done message */ - pq_putemptymessage('c'); - } - else - { - CopySendData(cstate, "\\.", 2); - /* Need to flush out the trailer (this also appends a newline) */ - CopySendEndOfRow(cstate); - pq_endcopyout(false); - } + /* Shouldn't have any unsent data */ + Assert(cstate->fe_msgbuf->len == 0); + /* Send Copy Done message */ + pq_putemptymessage('c'); } /*---------- @@ -268,20 +240,7 @@ CopySendEndOfRow(CopyToState cstate) errmsg("could not write to COPY file: %m"))); } break; - case COPY_OLD_FE: - /* The FE/BE protocol uses \n as newline for all platforms */ - if (!cstate->opts.binary) - CopySendChar(cstate, '\n'); - - if (pq_putbytes(fe_msgbuf->data, fe_msgbuf->len)) - { - /* no hope of recovering connection sync, so FATAL */ - ereport(FATAL, - (errcode(ERRCODE_CONNECTION_FAILURE), - errmsg("connection lost during COPY to stdout"))); - } - break; - case COPY_NEW_FE: + case COPY_FRONTEND: /* The FE/BE protocol uses \n as newline for all platforms */ if (!cstate->opts.binary) CopySendChar(cstate, '\n'); @@ -780,42 +739,6 @@ BeginCopyTo(ParseState *pstate, } /* - * This intermediate routine exists mainly to localize the effects of setjmp - * so we don't need to plaster a lot of variables with "volatile". - */ -uint64 -DoCopyTo(CopyToState cstate) -{ - bool pipe = (cstate->filename == NULL); - bool fe_copy = (pipe && whereToSendOutput == DestRemote); - uint64 processed; - - PG_TRY(); - { - if (fe_copy) - SendCopyBegin(cstate); - - processed = CopyTo(cstate); - - if (fe_copy) - SendCopyEnd(cstate); - } - PG_CATCH(); - { - /* - * Make sure we turn off old-style COPY OUT mode upon error. It is - * okay to do this in all cases, since it does nothing if the mode is - * not on. - */ - pq_endcopyout(true); - PG_RE_THROW(); - } - PG_END_TRY(); - - return processed; -} - -/* * Clean up storage and release resources for COPY TO. */ void @@ -837,14 +760,19 @@ EndCopyTo(CopyToState cstate) /* * Copy from relation or query TO file. */ -static uint64 -CopyTo(CopyToState cstate) +uint64 +DoCopyTo(CopyToState cstate) { + bool pipe = (cstate->filename == NULL); + bool fe_copy = (pipe && whereToSendOutput == DestRemote); TupleDesc tupDesc; int num_phys_attrs; ListCell *cur; uint64 processed; + if (fe_copy) + SendCopyBegin(cstate); + if (cstate->rel) tupDesc = RelationGetDescr(cstate->rel); else @@ -977,11 +905,14 @@ CopyTo(CopyToState cstate) MemoryContextDelete(cstate->rowcontext); + if (fe_copy) + SendCopyEnd(cstate); + return processed; } /* - * Emit one row during CopyTo(). + * Emit one row during DoCopyTo(). */ static void CopyOneRowTo(CopyToState cstate, TupleTableSlot *slot) |