mirror of
https://github.com/postgres/postgres.git
synced 2025-07-05 07:21:24 +03:00
Remove server and libpq support for old FE/BE protocol version 2.
Protocol version 3 was introduced in PostgreSQL 7.4. There shouldn't be many clients or servers left out there without version 3 support. But as a courtesy, I kept just enough of the old protocol support that we can still send the "unsupported protocol version" error in v2 format, so that old clients can display the message properly. Likewise, libpq still understands v2 ErrorResponse messages when establishing a connection. The impetus to do this now is that I'm working on a patch to COPY FROM, to always prefetch some data. We cannot do that safely with the old protocol, because it requires parsing the input one byte at a time to detect the end-of-copy marker. Reviewed-by: Tom Lane, Alvaro Herrera, John Naylor Discussion: https://www.postgresql.org/message-id/9ec25819-0a8a-d51a-17dc-4150bb3cca3b%40iki.fi
This commit is contained in:
@ -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;
|
||||
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;
|
||||
}
|
||||
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
|
||||
{
|
||||
|
Reference in New Issue
Block a user