1
0
mirror of https://github.com/postgres/postgres.git synced 2025-11-03 09:13:20 +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:
Heikki Linnakangas
2021-03-04 10:45:55 +02:00
parent 0a687c8f10
commit 3174d69fb9
33 changed files with 301 additions and 3112 deletions

View File

@@ -589,16 +589,6 @@ errfinish(const char *filename, int lineno, const char *funcname)
PG_RE_THROW();
}
/*
* If we are doing FATAL or PANIC, abort any old-style COPY OUT in
* progress, so that we can report the message before dying. (Without
* this, pq_putmessage will refuse to send the message at all, which is
* what we want for NOTICE messages, but not for fatal exits.) This hack
* is necessary because of poor design of old-style copy protocol.
*/
if (elevel >= FATAL && whereToSendOutput == DestRemote)
pq_endcopyout(true);
/* Emit the message to the right places */
EmitErrorReport();
@@ -1261,28 +1251,6 @@ errhidecontext(bool hide_ctx)
return 0; /* return value does not matter */
}
/*
* errfunction --- add reporting function name to the current error
*
* This is used when backwards compatibility demands that the function
* name appear in messages sent to old-protocol clients. Note that the
* passed string is expected to be a non-freeable constant string.
*/
int
errfunction(const char *funcname)
{
ErrorData *edata = &errordata[errordata_stack_depth];
/* we don't bother incrementing recursion_depth */
CHECK_STACK_DEPTH();
edata->funcname = funcname;
edata->show_funcname = true;
return 0; /* return value does not matter */
}
/*
* errposition --- add cursor position to the current error
*/
@@ -3291,10 +3259,14 @@ send_message_to_frontend(ErrorData *edata)
{
StringInfoData msgbuf;
/* 'N' (Notice) is for nonfatal conditions, 'E' is for errors */
pq_beginmessage(&msgbuf, (edata->elevel < ERROR) ? 'N' : 'E');
if (PG_PROTOCOL_MAJOR(FrontendProtocol) >= 3)
/*
* We no longer support pre-3.0 FE/BE protocol, except here. If a client
* tries to connect using an older protocol version, it's nice to send the
* "protocol version not supported" error in a format the client
* understands. If protocol hasn't been set yet, early in backend
* startup, assume modern protocol.
*/
if (PG_PROTOCOL_MAJOR(FrontendProtocol) >= 3 || FrontendProtocol == 0)
{
/* New style with separate fields */
const char *sev;
@@ -3302,6 +3274,9 @@ send_message_to_frontend(ErrorData *edata)
int ssval;
int i;
/* 'N' (Notice) is for nonfatal conditions, 'E' is for errors */
pq_beginmessage(&msgbuf, (edata->elevel < ERROR) ? 'N' : 'E');
sev = error_severity(edata->elevel);
pq_sendbyte(&msgbuf, PG_DIAG_SEVERITY);
err_sendstring(&msgbuf, _(sev));
@@ -3417,6 +3392,8 @@ send_message_to_frontend(ErrorData *edata)
}
pq_sendbyte(&msgbuf, '\0'); /* terminator */
pq_endmessage(&msgbuf);
}
else
{
@@ -3427,30 +3404,19 @@ send_message_to_frontend(ErrorData *edata)
appendStringInfo(&buf, "%s: ", _(error_severity(edata->elevel)));
if (edata->show_funcname && edata->funcname)
appendStringInfo(&buf, "%s: ", edata->funcname);
if (edata->message)
appendStringInfoString(&buf, edata->message);
else
appendStringInfoString(&buf, _("missing error text"));
if (edata->cursorpos > 0)
appendStringInfo(&buf, _(" at character %d"),
edata->cursorpos);
else if (edata->internalpos > 0)
appendStringInfo(&buf, _(" at character %d"),
edata->internalpos);
appendStringInfoChar(&buf, '\n');
err_sendstring(&msgbuf, buf.data);
/* 'N' (Notice) is for nonfatal conditions, 'E' is for errors */
pq_putmessage_v2((edata->elevel < ERROR) ? 'N' : 'E', buf.data, buf.len + 1);
pfree(buf.data);
}
pq_endmessage(&msgbuf);
/*
* This flush is normally not necessary, since postgres.c will flush out
* waiting data when control returns to the main loop. But it seems best