1
0
mirror of https://github.com/postgres/postgres.git synced 2025-04-24 10:47:04 +03:00

Introduce macros for protocol characters.

This commit introduces descriptively-named macros for the
identifiers used in wire protocol messages.  These new macros are
placed in a new header file so that they can be easily used by
third-party code.

Author: Dave Cramer
Reviewed-by: Alvaro Herrera, Tatsuo Ishii, Peter Smith, Robert Haas, Tom Lane, Peter Eisentraut, Michael Paquier
Discussion: https://postgr.es/m/CADK3HHKbBmK-PKf1bPNFoMC%2BoBt%2BpD9PH8h5nvmBQskEHm-Ehw%40mail.gmail.com
This commit is contained in:
Nathan Bossart 2023-08-22 19:16:12 -07:00
parent 7114791158
commit f4b54e1ed9
25 changed files with 305 additions and 204 deletions

View File

@ -20,6 +20,7 @@
#include "access/printsimple.h" #include "access/printsimple.h"
#include "catalog/pg_type.h" #include "catalog/pg_type.h"
#include "libpq/protocol.h"
#include "libpq/pqformat.h" #include "libpq/pqformat.h"
#include "utils/builtins.h" #include "utils/builtins.h"
@ -32,7 +33,7 @@ printsimple_startup(DestReceiver *self, int operation, TupleDesc tupdesc)
StringInfoData buf; StringInfoData buf;
int i; int i;
pq_beginmessage(&buf, 'T'); /* RowDescription */ pq_beginmessage(&buf, PqMsg_RowDescription);
pq_sendint16(&buf, tupdesc->natts); pq_sendint16(&buf, tupdesc->natts);
for (i = 0; i < tupdesc->natts; ++i) for (i = 0; i < tupdesc->natts; ++i)
@ -65,7 +66,7 @@ printsimple(TupleTableSlot *slot, DestReceiver *self)
slot_getallattrs(slot); slot_getallattrs(slot);
/* Prepare and send message */ /* Prepare and send message */
pq_beginmessage(&buf, 'D'); pq_beginmessage(&buf, PqMsg_DataRow);
pq_sendint16(&buf, tupdesc->natts); pq_sendint16(&buf, tupdesc->natts);
for (i = 0; i < tupdesc->natts; ++i) for (i = 0; i < tupdesc->natts; ++i)

View File

@ -1127,7 +1127,7 @@ HandleParallelMessage(ParallelContext *pcxt, int i, StringInfo msg)
switch (msgtype) switch (msgtype)
{ {
case 'K': /* BackendKeyData */ case PqMsg_BackendKeyData:
{ {
int32 pid = pq_getmsgint(msg, 4); int32 pid = pq_getmsgint(msg, 4);
@ -1137,8 +1137,8 @@ HandleParallelMessage(ParallelContext *pcxt, int i, StringInfo msg)
break; break;
} }
case 'E': /* ErrorResponse */ case PqMsg_ErrorResponse:
case 'N': /* NoticeResponse */ case PqMsg_NoticeResponse:
{ {
ErrorData edata; ErrorData edata;
ErrorContextCallback *save_error_context_stack; ErrorContextCallback *save_error_context_stack;
@ -1183,7 +1183,7 @@ HandleParallelMessage(ParallelContext *pcxt, int i, StringInfo msg)
break; break;
} }
case 'A': /* NotifyResponse */ case PqMsg_NotificationResponse:
{ {
/* Propagate NotifyResponse. */ /* Propagate NotifyResponse. */
int32 pid; int32 pid;
@ -1217,7 +1217,7 @@ HandleParallelMessage(ParallelContext *pcxt, int i, StringInfo msg)
break; break;
} }
case 'X': /* Terminate, indicating clean exit */ case PqMsg_Terminate:
{ {
shm_mq_detach(pcxt->worker[i].error_mqh); shm_mq_detach(pcxt->worker[i].error_mqh);
pcxt->worker[i].error_mqh = NULL; pcxt->worker[i].error_mqh = NULL;
@ -1372,7 +1372,7 @@ ParallelWorkerMain(Datum main_arg)
* protocol message is defined, but it won't actually be used for anything * protocol message is defined, but it won't actually be used for anything
* in this case. * in this case.
*/ */
pq_beginmessage(&msgbuf, 'K'); pq_beginmessage(&msgbuf, PqMsg_BackendKeyData);
pq_sendint32(&msgbuf, (int32) MyProcPid); pq_sendint32(&msgbuf, (int32) MyProcPid);
pq_sendint32(&msgbuf, (int32) MyCancelKey); pq_sendint32(&msgbuf, (int32) MyCancelKey);
pq_endmessage(&msgbuf); pq_endmessage(&msgbuf);
@ -1550,7 +1550,7 @@ ParallelWorkerMain(Datum main_arg)
DetachSession(); DetachSession();
/* Report success. */ /* Report success. */
pq_putmessage('X', NULL, 0); pq_putmessage(PqMsg_Terminate, NULL, 0);
} }
/* /*

View File

@ -152,7 +152,7 @@ bbsink_copystream_begin_backup(bbsink *sink)
SendTablespaceList(state->tablespaces); SendTablespaceList(state->tablespaces);
/* Send a CommandComplete message */ /* Send a CommandComplete message */
pq_puttextmessage('C', "SELECT"); pq_puttextmessage(PqMsg_CommandComplete, "SELECT");
/* Begin COPY stream. This will be used for all archives + manifest. */ /* Begin COPY stream. This will be used for all archives + manifest. */
SendCopyOutResponse(); SendCopyOutResponse();
@ -169,7 +169,7 @@ bbsink_copystream_begin_archive(bbsink *sink, const char *archive_name)
StringInfoData buf; StringInfoData buf;
ti = list_nth(state->tablespaces, state->tablespace_num); ti = list_nth(state->tablespaces, state->tablespace_num);
pq_beginmessage(&buf, 'd'); /* CopyData */ pq_beginmessage(&buf, PqMsg_CopyData);
pq_sendbyte(&buf, 'n'); /* New archive */ pq_sendbyte(&buf, 'n'); /* New archive */
pq_sendstring(&buf, archive_name); pq_sendstring(&buf, archive_name);
pq_sendstring(&buf, ti->path == NULL ? "" : ti->path); pq_sendstring(&buf, ti->path == NULL ? "" : ti->path);
@ -220,7 +220,7 @@ bbsink_copystream_archive_contents(bbsink *sink, size_t len)
{ {
mysink->last_progress_report_time = now; mysink->last_progress_report_time = now;
pq_beginmessage(&buf, 'd'); /* CopyData */ pq_beginmessage(&buf, PqMsg_CopyData);
pq_sendbyte(&buf, 'p'); /* Progress report */ pq_sendbyte(&buf, 'p'); /* Progress report */
pq_sendint64(&buf, state->bytes_done); pq_sendint64(&buf, state->bytes_done);
pq_endmessage(&buf); pq_endmessage(&buf);
@ -246,7 +246,7 @@ bbsink_copystream_end_archive(bbsink *sink)
mysink->bytes_done_at_last_time_check = state->bytes_done; mysink->bytes_done_at_last_time_check = state->bytes_done;
mysink->last_progress_report_time = GetCurrentTimestamp(); mysink->last_progress_report_time = GetCurrentTimestamp();
pq_beginmessage(&buf, 'd'); /* CopyData */ pq_beginmessage(&buf, PqMsg_CopyData);
pq_sendbyte(&buf, 'p'); /* Progress report */ pq_sendbyte(&buf, 'p'); /* Progress report */
pq_sendint64(&buf, state->bytes_done); pq_sendint64(&buf, state->bytes_done);
pq_endmessage(&buf); pq_endmessage(&buf);
@ -261,7 +261,7 @@ bbsink_copystream_begin_manifest(bbsink *sink)
{ {
StringInfoData buf; StringInfoData buf;
pq_beginmessage(&buf, 'd'); /* CopyData */ pq_beginmessage(&buf, PqMsg_CopyData);
pq_sendbyte(&buf, 'm'); /* Manifest */ pq_sendbyte(&buf, 'm'); /* Manifest */
pq_endmessage(&buf); pq_endmessage(&buf);
} }
@ -318,7 +318,7 @@ SendCopyOutResponse(void)
{ {
StringInfoData buf; StringInfoData buf;
pq_beginmessage(&buf, 'H'); pq_beginmessage(&buf, PqMsg_CopyOutResponse);
pq_sendbyte(&buf, 0); /* overall format */ pq_sendbyte(&buf, 0); /* overall format */
pq_sendint16(&buf, 0); /* natts */ pq_sendint16(&buf, 0); /* natts */
pq_endmessage(&buf); pq_endmessage(&buf);
@ -330,7 +330,7 @@ SendCopyOutResponse(void)
static void static void
SendCopyDone(void) SendCopyDone(void)
{ {
pq_putemptymessage('c'); pq_putemptymessage(PqMsg_CopyDone);
} }
/* /*
@ -368,7 +368,7 @@ SendXlogRecPtrResult(XLogRecPtr ptr, TimeLineID tli)
end_tup_output(tstate); end_tup_output(tstate);
/* Send a CommandComplete message */ /* Send a CommandComplete message */
pq_puttextmessage('C', "SELECT"); pq_puttextmessage(PqMsg_CommandComplete, "SELECT");
} }
/* /*

View File

@ -2281,7 +2281,7 @@ NotifyMyFrontEnd(const char *channel, const char *payload, int32 srcPid)
{ {
StringInfoData buf; StringInfoData buf;
pq_beginmessage(&buf, 'A'); pq_beginmessage(&buf, PqMsg_NotificationResponse);
pq_sendint32(&buf, srcPid); pq_sendint32(&buf, srcPid);
pq_sendstring(&buf, channel); pq_sendstring(&buf, channel);
pq_sendstring(&buf, payload); pq_sendstring(&buf, payload);

View File

@ -174,7 +174,7 @@ ReceiveCopyBegin(CopyFromState cstate)
int16 format = (cstate->opts.binary ? 1 : 0); int16 format = (cstate->opts.binary ? 1 : 0);
int i; int i;
pq_beginmessage(&buf, 'G'); pq_beginmessage(&buf, PqMsg_CopyInResponse);
pq_sendbyte(&buf, format); /* overall format */ pq_sendbyte(&buf, format); /* overall format */
pq_sendint16(&buf, natts); pq_sendint16(&buf, natts);
for (i = 0; i < natts; i++) for (i = 0; i < natts; i++)
@ -279,13 +279,13 @@ CopyGetData(CopyFromState cstate, void *databuf, int minread, int maxread)
/* Validate message type and set packet size limit */ /* Validate message type and set packet size limit */
switch (mtype) switch (mtype)
{ {
case 'd': /* CopyData */ case PqMsg_CopyData:
maxmsglen = PQ_LARGE_MESSAGE_LIMIT; maxmsglen = PQ_LARGE_MESSAGE_LIMIT;
break; break;
case 'c': /* CopyDone */ case PqMsg_CopyDone:
case 'f': /* CopyFail */ case PqMsg_CopyFail:
case 'H': /* Flush */ case PqMsg_Flush:
case 'S': /* Sync */ case PqMsg_Sync:
maxmsglen = PQ_SMALL_MESSAGE_LIMIT; maxmsglen = PQ_SMALL_MESSAGE_LIMIT;
break; break;
default: default:
@ -305,20 +305,20 @@ CopyGetData(CopyFromState cstate, void *databuf, int minread, int maxread)
/* ... and process it */ /* ... and process it */
switch (mtype) switch (mtype)
{ {
case 'd': /* CopyData */ case PqMsg_CopyData:
break; break;
case 'c': /* CopyDone */ case PqMsg_CopyDone:
/* COPY IN correctly terminated by frontend */ /* COPY IN correctly terminated by frontend */
cstate->raw_reached_eof = true; cstate->raw_reached_eof = true;
return bytesread; return bytesread;
case 'f': /* CopyFail */ case PqMsg_CopyFail:
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_QUERY_CANCELED), (errcode(ERRCODE_QUERY_CANCELED),
errmsg("COPY from stdin failed: %s", errmsg("COPY from stdin failed: %s",
pq_getmsgstring(cstate->fe_msgbuf)))); pq_getmsgstring(cstate->fe_msgbuf))));
break; break;
case 'H': /* Flush */ case PqMsg_Flush:
case 'S': /* Sync */ case PqMsg_Sync:
/* /*
* Ignore Flush/Sync for the convenience of client * Ignore Flush/Sync for the convenience of client

View File

@ -144,7 +144,7 @@ SendCopyBegin(CopyToState cstate)
int16 format = (cstate->opts.binary ? 1 : 0); int16 format = (cstate->opts.binary ? 1 : 0);
int i; int i;
pq_beginmessage(&buf, 'H'); pq_beginmessage(&buf, PqMsg_CopyOutResponse);
pq_sendbyte(&buf, format); /* overall format */ pq_sendbyte(&buf, format); /* overall format */
pq_sendint16(&buf, natts); pq_sendint16(&buf, natts);
for (i = 0; i < natts; i++) for (i = 0; i < natts; i++)
@ -159,7 +159,7 @@ SendCopyEnd(CopyToState cstate)
/* Shouldn't have any unsent data */ /* Shouldn't have any unsent data */
Assert(cstate->fe_msgbuf->len == 0); Assert(cstate->fe_msgbuf->len == 0);
/* Send Copy Done message */ /* Send Copy Done message */
pq_putemptymessage('c'); pq_putemptymessage(PqMsg_CopyDone);
} }
/*---------- /*----------
@ -247,7 +247,7 @@ CopySendEndOfRow(CopyToState cstate)
CopySendChar(cstate, '\n'); CopySendChar(cstate, '\n');
/* Dump the accumulated row as one CopyData message */ /* Dump the accumulated row as one CopyData message */
(void) pq_putmessage('d', fe_msgbuf->data, fe_msgbuf->len); (void) pq_putmessage(PqMsg_CopyData, fe_msgbuf->data, fe_msgbuf->len);
break; break;
case COPY_CALLBACK: case COPY_CALLBACK:
cstate->data_dest_cb(fe_msgbuf->data, fe_msgbuf->len); cstate->data_dest_cb(fe_msgbuf->data, fe_msgbuf->len);

View File

@ -87,7 +87,7 @@ CheckSASLAuth(const pg_be_sasl_mech *mech, Port *port, char *shadow_pass,
{ {
pq_startmsgread(); pq_startmsgread();
mtype = pq_getbyte(); mtype = pq_getbyte();
if (mtype != 'p') if (mtype != PqMsg_SASLResponse)
{ {
/* Only log error if client didn't disconnect. */ /* Only log error if client didn't disconnect. */
if (mtype != EOF) if (mtype != EOF)

View File

@ -665,7 +665,7 @@ sendAuthRequest(Port *port, AuthRequest areq, const char *extradata, int extrale
CHECK_FOR_INTERRUPTS(); CHECK_FOR_INTERRUPTS();
pq_beginmessage(&buf, 'R'); pq_beginmessage(&buf, PqMsg_AuthenticationRequest);
pq_sendint32(&buf, (int32) areq); pq_sendint32(&buf, (int32) areq);
if (extralen > 0) if (extralen > 0)
pq_sendbytes(&buf, extradata, extralen); pq_sendbytes(&buf, extradata, extralen);
@ -698,7 +698,7 @@ recv_password_packet(Port *port)
/* Expect 'p' message type */ /* Expect 'p' message type */
mtype = pq_getbyte(); mtype = pq_getbyte();
if (mtype != 'p') if (mtype != PqMsg_PasswordMessage)
{ {
/* /*
* If the client just disconnects without offering a password, don't * If the client just disconnects without offering a password, don't
@ -961,7 +961,7 @@ pg_GSS_recvauth(Port *port)
CHECK_FOR_INTERRUPTS(); CHECK_FOR_INTERRUPTS();
mtype = pq_getbyte(); mtype = pq_getbyte();
if (mtype != 'p') if (mtype != PqMsg_GSSResponse)
{ {
/* Only log error if client didn't disconnect. */ /* Only log error if client didn't disconnect. */
if (mtype != EOF) if (mtype != EOF)
@ -1232,7 +1232,7 @@ pg_SSPI_recvauth(Port *port)
{ {
pq_startmsgread(); pq_startmsgread();
mtype = pq_getbyte(); mtype = pq_getbyte();
if (mtype != 'p') if (mtype != PqMsg_GSSResponse)
{ {
if (sspictx != NULL) if (sspictx != NULL)
{ {

View File

@ -2357,7 +2357,7 @@ SendNegotiateProtocolVersion(List *unrecognized_protocol_options)
StringInfoData buf; StringInfoData buf;
ListCell *lc; ListCell *lc;
pq_beginmessage(&buf, 'v'); /* NegotiateProtocolVersion */ pq_beginmessage(&buf, PqMsg_NegotiateProtocolVersion);
pq_sendint32(&buf, PG_PROTOCOL_LATEST); pq_sendint32(&buf, PG_PROTOCOL_LATEST);
pq_sendint32(&buf, list_length(unrecognized_protocol_options)); pq_sendint32(&buf, list_length(unrecognized_protocol_options));
foreach(lc, unrecognized_protocol_options) foreach(lc, unrecognized_protocol_options)

View File

@ -603,7 +603,7 @@ SendTimeLineHistory(TimeLineHistoryCmd *cmd)
dest->rStartup(dest, CMD_SELECT, tupdesc); dest->rStartup(dest, CMD_SELECT, tupdesc);
/* Send a DataRow message */ /* Send a DataRow message */
pq_beginmessage(&buf, 'D'); pq_beginmessage(&buf, PqMsg_DataRow);
pq_sendint16(&buf, 2); /* # of columns */ pq_sendint16(&buf, 2); /* # of columns */
len = strlen(histfname); len = strlen(histfname);
pq_sendint32(&buf, len); /* col1 len */ pq_sendint32(&buf, len); /* col1 len */
@ -801,7 +801,7 @@ StartReplication(StartReplicationCmd *cmd)
WalSndSetState(WALSNDSTATE_CATCHUP); WalSndSetState(WALSNDSTATE_CATCHUP);
/* Send a CopyBothResponse message, and start streaming */ /* Send a CopyBothResponse message, and start streaming */
pq_beginmessage(&buf, 'W'); pq_beginmessage(&buf, PqMsg_CopyBothResponse);
pq_sendbyte(&buf, 0); pq_sendbyte(&buf, 0);
pq_sendint16(&buf, 0); pq_sendint16(&buf, 0);
pq_endmessage(&buf); pq_endmessage(&buf);
@ -1294,7 +1294,7 @@ StartLogicalReplication(StartReplicationCmd *cmd)
WalSndSetState(WALSNDSTATE_CATCHUP); WalSndSetState(WALSNDSTATE_CATCHUP);
/* Send a CopyBothResponse message, and start streaming */ /* Send a CopyBothResponse message, and start streaming */
pq_beginmessage(&buf, 'W'); pq_beginmessage(&buf, PqMsg_CopyBothResponse);
pq_sendbyte(&buf, 0); pq_sendbyte(&buf, 0);
pq_sendint16(&buf, 0); pq_sendint16(&buf, 0);
pq_endmessage(&buf); pq_endmessage(&buf);
@ -1923,11 +1923,11 @@ ProcessRepliesIfAny(void)
/* Validate message type and set packet size limit */ /* Validate message type and set packet size limit */
switch (firstchar) switch (firstchar)
{ {
case 'd': case PqMsg_CopyData:
maxmsglen = PQ_LARGE_MESSAGE_LIMIT; maxmsglen = PQ_LARGE_MESSAGE_LIMIT;
break; break;
case 'c': case PqMsg_CopyDone:
case 'X': case PqMsg_Terminate:
maxmsglen = PQ_SMALL_MESSAGE_LIMIT; maxmsglen = PQ_SMALL_MESSAGE_LIMIT;
break; break;
default: default:
@ -1955,7 +1955,7 @@ ProcessRepliesIfAny(void)
/* /*
* 'd' means a standby reply wrapped in a CopyData packet. * 'd' means a standby reply wrapped in a CopyData packet.
*/ */
case 'd': case PqMsg_CopyData:
ProcessStandbyMessage(); ProcessStandbyMessage();
received = true; received = true;
break; break;
@ -1964,7 +1964,7 @@ ProcessRepliesIfAny(void)
* CopyDone means the standby requested to finish streaming. * CopyDone means the standby requested to finish streaming.
* Reply with CopyDone, if we had not sent that already. * Reply with CopyDone, if we had not sent that already.
*/ */
case 'c': case PqMsg_CopyDone:
if (!streamingDoneSending) if (!streamingDoneSending)
{ {
pq_putmessage_noblock('c', NULL, 0); pq_putmessage_noblock('c', NULL, 0);
@ -1978,7 +1978,7 @@ ProcessRepliesIfAny(void)
/* /*
* 'X' means that the standby is closing down the socket. * 'X' means that the standby is closing down the socket.
*/ */
case 'X': case PqMsg_Terminate:
proc_exit(0); proc_exit(0);
default: default:

View File

@ -176,7 +176,7 @@ EndCommand(const QueryCompletion *qc, CommandDest dest, bool force_undecorated_o
len = BuildQueryCompletionString(completionTag, qc, len = BuildQueryCompletionString(completionTag, qc,
force_undecorated_output); force_undecorated_output);
pq_putmessage('C', completionTag, len + 1); pq_putmessage(PqMsg_Close, completionTag, len + 1);
case DestNone: case DestNone:
case DestDebug: case DestDebug:
@ -200,7 +200,7 @@ EndCommand(const QueryCompletion *qc, CommandDest dest, bool force_undecorated_o
void void
EndReplicationCommand(const char *commandTag) EndReplicationCommand(const char *commandTag)
{ {
pq_putmessage('C', commandTag, strlen(commandTag) + 1); pq_putmessage(PqMsg_Close, commandTag, strlen(commandTag) + 1);
} }
/* ---------------- /* ----------------
@ -220,7 +220,7 @@ NullCommand(CommandDest dest)
case DestRemoteSimple: case DestRemoteSimple:
/* Tell the FE that we saw an empty query string */ /* Tell the FE that we saw an empty query string */
pq_putemptymessage('I'); pq_putemptymessage(PqMsg_EmptyQueryResponse);
break; break;
case DestNone: case DestNone:
@ -258,7 +258,7 @@ ReadyForQuery(CommandDest dest)
{ {
StringInfoData buf; StringInfoData buf;
pq_beginmessage(&buf, 'Z'); pq_beginmessage(&buf, PqMsg_ReadyForQuery);
pq_sendbyte(&buf, TransactionBlockStatusCode()); pq_sendbyte(&buf, TransactionBlockStatusCode());
pq_endmessage(&buf); pq_endmessage(&buf);
} }

View File

@ -69,7 +69,7 @@ SendFunctionResult(Datum retval, bool isnull, Oid rettype, int16 format)
{ {
StringInfoData buf; StringInfoData buf;
pq_beginmessage(&buf, 'V'); pq_beginmessage(&buf, PqMsg_FunctionCallResponse);
if (isnull) if (isnull)
{ {

View File

@ -402,37 +402,37 @@ SocketBackend(StringInfo inBuf)
*/ */
switch (qtype) switch (qtype)
{ {
case 'Q': /* simple query */ case PqMsg_Query:
maxmsglen = PQ_LARGE_MESSAGE_LIMIT; maxmsglen = PQ_LARGE_MESSAGE_LIMIT;
doing_extended_query_message = false; doing_extended_query_message = false;
break; break;
case 'F': /* fastpath function call */ case PqMsg_FunctionCall:
maxmsglen = PQ_LARGE_MESSAGE_LIMIT; maxmsglen = PQ_LARGE_MESSAGE_LIMIT;
doing_extended_query_message = false; doing_extended_query_message = false;
break; break;
case 'X': /* terminate */ case PqMsg_Terminate:
maxmsglen = PQ_SMALL_MESSAGE_LIMIT; maxmsglen = PQ_SMALL_MESSAGE_LIMIT;
doing_extended_query_message = false; doing_extended_query_message = false;
ignore_till_sync = false; ignore_till_sync = false;
break; break;
case 'B': /* bind */ case PqMsg_Bind:
case 'P': /* parse */ case PqMsg_Parse:
maxmsglen = PQ_LARGE_MESSAGE_LIMIT; maxmsglen = PQ_LARGE_MESSAGE_LIMIT;
doing_extended_query_message = true; doing_extended_query_message = true;
break; break;
case 'C': /* close */ case PqMsg_Close:
case 'D': /* describe */ case PqMsg_Describe:
case 'E': /* execute */ case PqMsg_Execute:
case 'H': /* flush */ case PqMsg_Flush:
maxmsglen = PQ_SMALL_MESSAGE_LIMIT; maxmsglen = PQ_SMALL_MESSAGE_LIMIT;
doing_extended_query_message = true; doing_extended_query_message = true;
break; break;
case 'S': /* sync */ case PqMsg_Sync:
maxmsglen = PQ_SMALL_MESSAGE_LIMIT; maxmsglen = PQ_SMALL_MESSAGE_LIMIT;
/* stop any active skip-till-Sync */ /* stop any active skip-till-Sync */
ignore_till_sync = false; ignore_till_sync = false;
@ -440,13 +440,13 @@ SocketBackend(StringInfo inBuf)
doing_extended_query_message = false; doing_extended_query_message = false;
break; break;
case 'd': /* copy data */ case PqMsg_CopyData:
maxmsglen = PQ_LARGE_MESSAGE_LIMIT; maxmsglen = PQ_LARGE_MESSAGE_LIMIT;
doing_extended_query_message = false; doing_extended_query_message = false;
break; break;
case 'c': /* copy done */ case PqMsg_CopyDone:
case 'f': /* copy fail */ case PqMsg_CopyFail:
maxmsglen = PQ_SMALL_MESSAGE_LIMIT; maxmsglen = PQ_SMALL_MESSAGE_LIMIT;
doing_extended_query_message = false; doing_extended_query_message = false;
break; break;
@ -1589,7 +1589,7 @@ exec_parse_message(const char *query_string, /* string to execute */
* Send ParseComplete. * Send ParseComplete.
*/ */
if (whereToSendOutput == DestRemote) if (whereToSendOutput == DestRemote)
pq_putemptymessage('1'); pq_putemptymessage(PqMsg_ParseComplete);
/* /*
* Emit duration logging if appropriate. * Emit duration logging if appropriate.
@ -2047,7 +2047,7 @@ exec_bind_message(StringInfo input_message)
* Send BindComplete. * Send BindComplete.
*/ */
if (whereToSendOutput == DestRemote) if (whereToSendOutput == DestRemote)
pq_putemptymessage('2'); pq_putemptymessage(PqMsg_BindComplete);
/* /*
* Emit duration logging if appropriate. * Emit duration logging if appropriate.
@ -2290,7 +2290,7 @@ exec_execute_message(const char *portal_name, long max_rows)
{ {
/* Portal run not complete, so send PortalSuspended */ /* Portal run not complete, so send PortalSuspended */
if (whereToSendOutput == DestRemote) if (whereToSendOutput == DestRemote)
pq_putemptymessage('s'); pq_putemptymessage(PqMsg_PortalSuspended);
/* /*
* Set XACT_FLAGS_PIPELINING whenever we suspend an Execute message, * Set XACT_FLAGS_PIPELINING whenever we suspend an Execute message,
@ -2683,7 +2683,7 @@ exec_describe_statement_message(const char *stmt_name)
NULL); NULL);
} }
else else
pq_putemptymessage('n'); /* NoData */ pq_putemptymessage(PqMsg_NoData);
} }
/* /*
@ -2736,7 +2736,7 @@ exec_describe_portal_message(const char *portal_name)
FetchPortalTargetList(portal), FetchPortalTargetList(portal),
portal->formats); portal->formats);
else else
pq_putemptymessage('n'); /* NoData */ pq_putemptymessage(PqMsg_NoData);
} }
@ -4239,7 +4239,7 @@ PostgresMain(const char *dbname, const char *username)
{ {
StringInfoData buf; StringInfoData buf;
pq_beginmessage(&buf, 'K'); pq_beginmessage(&buf, PqMsg_BackendKeyData);
pq_sendint32(&buf, (int32) MyProcPid); pq_sendint32(&buf, (int32) MyProcPid);
pq_sendint32(&buf, (int32) MyCancelKey); pq_sendint32(&buf, (int32) MyCancelKey);
pq_endmessage(&buf); pq_endmessage(&buf);
@ -4618,7 +4618,7 @@ PostgresMain(const char *dbname, const char *username)
switch (firstchar) switch (firstchar)
{ {
case 'Q': /* simple query */ case PqMsg_Query:
{ {
const char *query_string; const char *query_string;
@ -4642,7 +4642,7 @@ PostgresMain(const char *dbname, const char *username)
} }
break; break;
case 'P': /* parse */ case PqMsg_Parse:
{ {
const char *stmt_name; const char *stmt_name;
const char *query_string; const char *query_string;
@ -4672,7 +4672,7 @@ PostgresMain(const char *dbname, const char *username)
} }
break; break;
case 'B': /* bind */ case PqMsg_Bind:
forbidden_in_wal_sender(firstchar); forbidden_in_wal_sender(firstchar);
/* Set statement_timestamp() */ /* Set statement_timestamp() */
@ -4687,7 +4687,7 @@ PostgresMain(const char *dbname, const char *username)
/* exec_bind_message does valgrind_report_error_query */ /* exec_bind_message does valgrind_report_error_query */
break; break;
case 'E': /* execute */ case PqMsg_Execute:
{ {
const char *portal_name; const char *portal_name;
int max_rows; int max_rows;
@ -4707,7 +4707,7 @@ PostgresMain(const char *dbname, const char *username)
} }
break; break;
case 'F': /* fastpath function call */ case PqMsg_FunctionCall:
forbidden_in_wal_sender(firstchar); forbidden_in_wal_sender(firstchar);
/* Set statement_timestamp() */ /* Set statement_timestamp() */
@ -4742,7 +4742,7 @@ PostgresMain(const char *dbname, const char *username)
send_ready_for_query = true; send_ready_for_query = true;
break; break;
case 'C': /* close */ case PqMsg_Close:
{ {
int close_type; int close_type;
const char *close_target; const char *close_target;
@ -4782,13 +4782,13 @@ PostgresMain(const char *dbname, const char *username)
} }
if (whereToSendOutput == DestRemote) if (whereToSendOutput == DestRemote)
pq_putemptymessage('3'); /* CloseComplete */ pq_putemptymessage(PqMsg_CloseComplete);
valgrind_report_error_query("CLOSE message"); valgrind_report_error_query("CLOSE message");
} }
break; break;
case 'D': /* describe */ case PqMsg_Describe:
{ {
int describe_type; int describe_type;
const char *describe_target; const char *describe_target;
@ -4822,13 +4822,13 @@ PostgresMain(const char *dbname, const char *username)
} }
break; break;
case 'H': /* flush */ case PqMsg_Flush:
pq_getmsgend(&input_message); pq_getmsgend(&input_message);
if (whereToSendOutput == DestRemote) if (whereToSendOutput == DestRemote)
pq_flush(); pq_flush();
break; break;
case 'S': /* sync */ case PqMsg_Sync:
pq_getmsgend(&input_message); pq_getmsgend(&input_message);
finish_xact_command(); finish_xact_command();
valgrind_report_error_query("SYNC message"); valgrind_report_error_query("SYNC message");
@ -4847,7 +4847,7 @@ PostgresMain(const char *dbname, const char *username)
/* FALLTHROUGH */ /* FALLTHROUGH */
case 'X': case PqMsg_Terminate:
/* /*
* Reset whereToSendOutput to prevent ereport from attempting * Reset whereToSendOutput to prevent ereport from attempting
@ -4865,9 +4865,9 @@ PostgresMain(const char *dbname, const char *username)
*/ */
proc_exit(0); proc_exit(0);
case 'd': /* copy data */ case PqMsg_CopyData:
case 'c': /* copy done */ case PqMsg_CopyDone:
case 'f': /* copy fail */ case PqMsg_CopyFail:
/* /*
* Accept but ignore these messages, per protocol spec; we * Accept but ignore these messages, per protocol spec; we
@ -4897,7 +4897,7 @@ forbidden_in_wal_sender(char firstchar)
{ {
if (am_walsender) if (am_walsender)
{ {
if (firstchar == 'F') if (firstchar == PqMsg_FunctionCall)
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_PROTOCOL_VIOLATION), (errcode(ERRCODE_PROTOCOL_VIOLATION),
errmsg("fastpath function calls not supported in a replication connection"))); errmsg("fastpath function calls not supported in a replication connection")));

View File

@ -3465,7 +3465,10 @@ send_message_to_frontend(ErrorData *edata)
char tbuf[12]; char tbuf[12];
/* 'N' (Notice) is for nonfatal conditions, 'E' is for errors */ /* 'N' (Notice) is for nonfatal conditions, 'E' is for errors */
pq_beginmessage(&msgbuf, (edata->elevel < ERROR) ? 'N' : 'E'); if (edata->elevel < ERROR)
pq_beginmessage(&msgbuf, PqMsg_NoticeResponse);
else
pq_beginmessage(&msgbuf, PqMsg_ErrorResponse);
sev = error_severity(edata->elevel); sev = error_severity(edata->elevel);
pq_sendbyte(&msgbuf, PG_DIAG_SEVERITY); pq_sendbyte(&msgbuf, PG_DIAG_SEVERITY);

View File

@ -2593,7 +2593,7 @@ ReportGUCOption(struct config_generic *record)
{ {
StringInfoData msgbuf; StringInfoData msgbuf;
pq_beginmessage(&msgbuf, 'S'); pq_beginmessage(&msgbuf, PqMsg_ParameterStatus);
pq_sendstring(&msgbuf, record->name); pq_sendstring(&msgbuf, record->name);
pq_sendstring(&msgbuf, val); pq_sendstring(&msgbuf, val);
pq_endmessage(&msgbuf); pq_endmessage(&msgbuf);

View File

@ -40,6 +40,7 @@ install: all installdirs
$(INSTALL_DATA) $(srcdir)/port.h '$(DESTDIR)$(includedir_internal)' $(INSTALL_DATA) $(srcdir)/port.h '$(DESTDIR)$(includedir_internal)'
$(INSTALL_DATA) $(srcdir)/postgres_fe.h '$(DESTDIR)$(includedir_internal)' $(INSTALL_DATA) $(srcdir)/postgres_fe.h '$(DESTDIR)$(includedir_internal)'
$(INSTALL_DATA) $(srcdir)/libpq/pqcomm.h '$(DESTDIR)$(includedir_internal)/libpq' $(INSTALL_DATA) $(srcdir)/libpq/pqcomm.h '$(DESTDIR)$(includedir_internal)/libpq'
$(INSTALL_DATA) $(srcdir)/libpq/protocol.h '$(DESTDIR)$(includedir_internal)/libpq'
# These headers are needed for server-side development # These headers are needed for server-side development
$(INSTALL_DATA) pg_config.h '$(DESTDIR)$(includedir_server)' $(INSTALL_DATA) pg_config.h '$(DESTDIR)$(includedir_server)'
$(INSTALL_DATA) pg_config_ext.h '$(DESTDIR)$(includedir_server)' $(INSTALL_DATA) pg_config_ext.h '$(DESTDIR)$(includedir_server)'
@ -65,7 +66,7 @@ installdirs:
uninstall: uninstall:
rm -f $(addprefix '$(DESTDIR)$(includedir)'/, pg_config.h pg_config_ext.h pg_config_os.h pg_config_manual.h postgres_ext.h libpq/libpq-fs.h) rm -f $(addprefix '$(DESTDIR)$(includedir)'/, pg_config.h pg_config_ext.h pg_config_os.h pg_config_manual.h postgres_ext.h libpq/libpq-fs.h)
rm -f $(addprefix '$(DESTDIR)$(includedir_internal)'/, c.h port.h postgres_fe.h libpq/pqcomm.h) rm -f $(addprefix '$(DESTDIR)$(includedir_internal)'/, c.h port.h postgres_fe.h libpq/pqcomm.h libpq/protocol.h)
# heuristic... # heuristic...
rm -rf $(addprefix '$(DESTDIR)$(includedir_server)'/, $(SUBDIRS) *.h) rm -rf $(addprefix '$(DESTDIR)$(includedir_server)'/, $(SUBDIRS) *.h)

View File

@ -21,6 +21,12 @@
#include <netdb.h> #include <netdb.h>
#include <netinet/in.h> #include <netinet/in.h>
/*
* The definitions for the request/response codes are kept in a separate file
* for ease of use in third party programs.
*/
#include "libpq/protocol.h"
typedef struct typedef struct
{ {
struct sockaddr_storage addr; struct sockaddr_storage addr;
@ -112,23 +118,6 @@ typedef uint32 PacketLen;
#define MAX_STARTUP_PACKET_LENGTH 10000 #define MAX_STARTUP_PACKET_LENGTH 10000
/* These are the authentication request codes sent by the backend. */
#define AUTH_REQ_OK 0 /* User is authenticated */
#define AUTH_REQ_KRB4 1 /* Kerberos V4. Not supported any more. */
#define AUTH_REQ_KRB5 2 /* Kerberos V5. Not supported any more. */
#define AUTH_REQ_PASSWORD 3 /* Password */
#define AUTH_REQ_CRYPT 4 /* crypt password. Not supported any more. */
#define AUTH_REQ_MD5 5 /* md5 password */
/* 6 is available. It was used for SCM creds, not supported any more. */
#define AUTH_REQ_GSS 7 /* GSSAPI without wrap() */
#define AUTH_REQ_GSS_CONT 8 /* Continue GSS exchanges */
#define AUTH_REQ_SSPI 9 /* SSPI negotiate without wrap() */
#define AUTH_REQ_SASL 10 /* Begin SASL authentication */
#define AUTH_REQ_SASL_CONT 11 /* Continue SASL authentication */
#define AUTH_REQ_SASL_FIN 12 /* Final SASL message */
#define AUTH_REQ_MAX AUTH_REQ_SASL_FIN /* maximum AUTH_REQ_* value */
typedef uint32 AuthRequest; typedef uint32 AuthRequest;

View File

@ -0,0 +1,85 @@
/*-------------------------------------------------------------------------
*
* protocol.h
* Definitions of the request/response codes for the wire protocol.
*
*
* Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* src/include/libpq/protocol.h
*
*-------------------------------------------------------------------------
*/
#ifndef PROTOCOL_H
#define PROTOCOL_H
/* These are the request codes sent by the frontend. */
#define PqMsg_Bind 'B'
#define PqMsg_Close 'C'
#define PqMsg_Describe 'D'
#define PqMsg_Execute 'E'
#define PqMsg_FunctionCall 'F'
#define PqMsg_Flush 'H'
#define PqMsg_Parse 'P'
#define PqMsg_Query 'Q'
#define PqMsg_Sync 'S'
#define PqMsg_Terminate 'X'
#define PqMsg_CopyFail 'f'
#define PqMsg_GSSResponse 'p'
#define PqMsg_PasswordMessage 'p'
#define PqMsg_SASLInitialResponse 'p'
#define PqMsg_SASLResponse 'p'
/* These are the response codes sent by the backend. */
#define PqMsg_ParseComplete '1'
#define PqMsg_BindComplete '2'
#define PqMsg_CloseComplete '3'
#define PqMsg_NotificationResponse 'A'
#define PqMsg_CommandComplete 'C'
#define PqMsg_DataRow 'D'
#define PqMsg_ErrorResponse 'E'
#define PqMsg_CopyInResponse 'G'
#define PqMsg_CopyOutResponse 'H'
#define PqMsg_EmptyQueryResponse 'I'
#define PqMsg_BackendKeyData 'K'
#define PqMsg_NoticeResponse 'N'
#define PqMsg_AuthenticationRequest 'R'
#define PqMsg_ParameterStatus 'S'
#define PqMsg_RowDescription 'T'
#define PqMsg_FunctionCallResponse 'V'
#define PqMsg_CopyBothResponse 'W'
#define PqMsg_ReadyForQuery 'Z'
#define PqMsg_NoData 'n'
#define PqMsg_PortalSuspended 's'
#define PqMsg_ParameterDescription 't'
#define PqMsg_NegotiateProtocolVersion 'v'
/* These are the codes sent by both the frontend and backend. */
#define PqMsg_CopyDone 'c'
#define PqMsg_CopyData 'd'
/* These are the authentication request codes sent by the backend. */
#define AUTH_REQ_OK 0 /* User is authenticated */
#define AUTH_REQ_KRB4 1 /* Kerberos V4. Not supported any more. */
#define AUTH_REQ_KRB5 2 /* Kerberos V5. Not supported any more. */
#define AUTH_REQ_PASSWORD 3 /* Password */
#define AUTH_REQ_CRYPT 4 /* crypt password. Not supported any more. */
#define AUTH_REQ_MD5 5 /* md5 password */
/* 6 is available. It was used for SCM creds, not supported any more. */
#define AUTH_REQ_GSS 7 /* GSSAPI without wrap() */
#define AUTH_REQ_GSS_CONT 8 /* Continue GSS exchanges */
#define AUTH_REQ_SSPI 9 /* SSPI negotiate without wrap() */
#define AUTH_REQ_SASL 10 /* Begin SASL authentication */
#define AUTH_REQ_SASL_CONT 11 /* Continue SASL authentication */
#define AUTH_REQ_SASL_FIN 12 /* Final SASL message */
#define AUTH_REQ_MAX AUTH_REQ_SASL_FIN /* maximum AUTH_REQ_* value */
#endif /* PROTOCOL_H */

View File

@ -94,6 +94,7 @@ install_headers(
install_headers( install_headers(
'libpq/pqcomm.h', 'libpq/pqcomm.h',
'libpq/protocol.h',
install_dir: dir_include_internal / 'libpq', install_dir: dir_include_internal / 'libpq',
) )

View File

@ -586,7 +586,7 @@ pg_SASL_init(PGconn *conn, int payloadlen)
/* /*
* Build a SASLInitialResponse message, and send it. * Build a SASLInitialResponse message, and send it.
*/ */
if (pqPutMsgStart('p', conn)) if (pqPutMsgStart(PqMsg_SASLInitialResponse, conn))
goto error; goto error;
if (pqPuts(selected_mechanism, conn)) if (pqPuts(selected_mechanism, conn))
goto error; goto error;

View File

@ -3591,7 +3591,9 @@ keep_going: /* We will come back to here until there is
* Anything else probably means it's not Postgres on the other * Anything else probably means it's not Postgres on the other
* end at all. * end at all.
*/ */
if (!(beresp == 'R' || beresp == 'v' || beresp == 'E')) if (beresp != PqMsg_AuthenticationRequest &&
beresp != PqMsg_ErrorResponse &&
beresp != PqMsg_NegotiateProtocolVersion)
{ {
libpq_append_conn_error(conn, "expected authentication request from server, but received %c", libpq_append_conn_error(conn, "expected authentication request from server, but received %c",
beresp); beresp);
@ -3618,19 +3620,22 @@ keep_going: /* We will come back to here until there is
* version 14, the server also used the old protocol for * version 14, the server also used the old protocol for
* errors that happened before processing the startup packet.) * errors that happened before processing the startup packet.)
*/ */
if (beresp == 'R' && (msgLength < 8 || msgLength > 2000)) if (beresp == PqMsg_AuthenticationRequest &&
(msgLength < 8 || msgLength > 2000))
{ {
libpq_append_conn_error(conn, "received invalid authentication request"); libpq_append_conn_error(conn, "received invalid authentication request");
goto error_return; goto error_return;
} }
if (beresp == 'v' && (msgLength < 8 || msgLength > 2000)) if (beresp == PqMsg_NegotiateProtocolVersion &&
(msgLength < 8 || msgLength > 2000))
{ {
libpq_append_conn_error(conn, "received invalid protocol negotiation message"); libpq_append_conn_error(conn, "received invalid protocol negotiation message");
goto error_return; goto error_return;
} }
#define MAX_ERRLEN 30000 #define MAX_ERRLEN 30000
if (beresp == 'E' && (msgLength < 8 || msgLength > MAX_ERRLEN)) if (beresp == PqMsg_ErrorResponse &&
(msgLength < 8 || msgLength > MAX_ERRLEN))
{ {
/* Handle error from a pre-3.0 server */ /* Handle error from a pre-3.0 server */
conn->inCursor = conn->inStart + 1; /* reread data */ conn->inCursor = conn->inStart + 1; /* reread data */
@ -3693,7 +3698,7 @@ keep_going: /* We will come back to here until there is
} }
/* Handle errors. */ /* Handle errors. */
if (beresp == 'E') if (beresp == PqMsg_ErrorResponse)
{ {
if (pqGetErrorNotice3(conn, true)) if (pqGetErrorNotice3(conn, true))
{ {
@ -3770,7 +3775,7 @@ keep_going: /* We will come back to here until there is
goto error_return; goto error_return;
} }
else if (beresp == 'v') else if (beresp == PqMsg_NegotiateProtocolVersion)
{ {
if (pqGetNegotiateProtocolVersion3(conn)) if (pqGetNegotiateProtocolVersion3(conn))
{ {
@ -4540,7 +4545,7 @@ sendTerminateConn(PGconn *conn)
* Try to send "close connection" message to backend. Ignore any * Try to send "close connection" message to backend. Ignore any
* error. * error.
*/ */
pqPutMsgStart('X', conn); pqPutMsgStart(PqMsg_Terminate, conn);
pqPutMsgEnd(conn); pqPutMsgEnd(conn);
(void) pqFlush(conn); (void) pqFlush(conn);
} }

View File

@ -1458,7 +1458,7 @@ PQsendQueryInternal(PGconn *conn, const char *query, bool newQuery)
/* Send the query message(s) */ /* Send the query message(s) */
/* construct the outgoing Query message */ /* construct the outgoing Query message */
if (pqPutMsgStart('Q', conn) < 0 || if (pqPutMsgStart(PqMsg_Query, conn) < 0 ||
pqPuts(query, conn) < 0 || pqPuts(query, conn) < 0 ||
pqPutMsgEnd(conn) < 0) pqPutMsgEnd(conn) < 0)
{ {
@ -1571,7 +1571,7 @@ PQsendPrepare(PGconn *conn,
return 0; /* error msg already set */ return 0; /* error msg already set */
/* construct the Parse message */ /* construct the Parse message */
if (pqPutMsgStart('P', conn) < 0 || if (pqPutMsgStart(PqMsg_Parse, conn) < 0 ||
pqPuts(stmtName, conn) < 0 || pqPuts(stmtName, conn) < 0 ||
pqPuts(query, conn) < 0) pqPuts(query, conn) < 0)
goto sendFailed; goto sendFailed;
@ -1599,7 +1599,7 @@ PQsendPrepare(PGconn *conn,
/* Add a Sync, unless in pipeline mode. */ /* Add a Sync, unless in pipeline mode. */
if (conn->pipelineStatus == PQ_PIPELINE_OFF) if (conn->pipelineStatus == PQ_PIPELINE_OFF)
{ {
if (pqPutMsgStart('S', conn) < 0 || if (pqPutMsgStart(PqMsg_Sync, conn) < 0 ||
pqPutMsgEnd(conn) < 0) pqPutMsgEnd(conn) < 0)
goto sendFailed; goto sendFailed;
} }
@ -1784,7 +1784,7 @@ PQsendQueryGuts(PGconn *conn,
if (command) if (command)
{ {
/* construct the Parse message */ /* construct the Parse message */
if (pqPutMsgStart('P', conn) < 0 || if (pqPutMsgStart(PqMsg_Parse, conn) < 0 ||
pqPuts(stmtName, conn) < 0 || pqPuts(stmtName, conn) < 0 ||
pqPuts(command, conn) < 0) pqPuts(command, conn) < 0)
goto sendFailed; goto sendFailed;
@ -1808,7 +1808,7 @@ PQsendQueryGuts(PGconn *conn,
} }
/* Construct the Bind message */ /* Construct the Bind message */
if (pqPutMsgStart('B', conn) < 0 || if (pqPutMsgStart(PqMsg_Bind, conn) < 0 ||
pqPuts("", conn) < 0 || pqPuts("", conn) < 0 ||
pqPuts(stmtName, conn) < 0) pqPuts(stmtName, conn) < 0)
goto sendFailed; goto sendFailed;
@ -1874,14 +1874,14 @@ PQsendQueryGuts(PGconn *conn,
goto sendFailed; goto sendFailed;
/* construct the Describe Portal message */ /* construct the Describe Portal message */
if (pqPutMsgStart('D', conn) < 0 || if (pqPutMsgStart(PqMsg_Describe, conn) < 0 ||
pqPutc('P', conn) < 0 || pqPutc('P', conn) < 0 ||
pqPuts("", conn) < 0 || pqPuts("", conn) < 0 ||
pqPutMsgEnd(conn) < 0) pqPutMsgEnd(conn) < 0)
goto sendFailed; goto sendFailed;
/* construct the Execute message */ /* construct the Execute message */
if (pqPutMsgStart('E', conn) < 0 || if (pqPutMsgStart(PqMsg_Execute, conn) < 0 ||
pqPuts("", conn) < 0 || pqPuts("", conn) < 0 ||
pqPutInt(0, 4, conn) < 0 || pqPutInt(0, 4, conn) < 0 ||
pqPutMsgEnd(conn) < 0) pqPutMsgEnd(conn) < 0)
@ -1890,7 +1890,7 @@ PQsendQueryGuts(PGconn *conn,
/* construct the Sync message if not in pipeline mode */ /* construct the Sync message if not in pipeline mode */
if (conn->pipelineStatus == PQ_PIPELINE_OFF) if (conn->pipelineStatus == PQ_PIPELINE_OFF)
{ {
if (pqPutMsgStart('S', conn) < 0 || if (pqPutMsgStart(PqMsg_Sync, conn) < 0 ||
pqPutMsgEnd(conn) < 0) pqPutMsgEnd(conn) < 0)
goto sendFailed; goto sendFailed;
} }
@ -2422,7 +2422,7 @@ PQdescribePrepared(PGconn *conn, const char *stmt)
{ {
if (!PQexecStart(conn)) if (!PQexecStart(conn))
return NULL; return NULL;
if (!PQsendTypedCommand(conn, 'D', 'S', stmt)) if (!PQsendTypedCommand(conn, PqMsg_Describe, 'S', stmt))
return NULL; return NULL;
return PQexecFinish(conn); return PQexecFinish(conn);
} }
@ -2441,7 +2441,7 @@ PQdescribePortal(PGconn *conn, const char *portal)
{ {
if (!PQexecStart(conn)) if (!PQexecStart(conn))
return NULL; return NULL;
if (!PQsendTypedCommand(conn, 'D', 'P', portal)) if (!PQsendTypedCommand(conn, PqMsg_Describe, 'P', portal))
return NULL; return NULL;
return PQexecFinish(conn); return PQexecFinish(conn);
} }
@ -2456,7 +2456,7 @@ PQdescribePortal(PGconn *conn, const char *portal)
int int
PQsendDescribePrepared(PGconn *conn, const char *stmt) PQsendDescribePrepared(PGconn *conn, const char *stmt)
{ {
return PQsendTypedCommand(conn, 'D', 'S', stmt); return PQsendTypedCommand(conn, PqMsg_Describe, 'S', stmt);
} }
/* /*
@ -2469,7 +2469,7 @@ PQsendDescribePrepared(PGconn *conn, const char *stmt)
int int
PQsendDescribePortal(PGconn *conn, const char *portal) PQsendDescribePortal(PGconn *conn, const char *portal)
{ {
return PQsendTypedCommand(conn, 'D', 'P', portal); return PQsendTypedCommand(conn, PqMsg_Describe, 'P', portal);
} }
/* /*
@ -2488,7 +2488,7 @@ PQclosePrepared(PGconn *conn, const char *stmt)
{ {
if (!PQexecStart(conn)) if (!PQexecStart(conn))
return NULL; return NULL;
if (!PQsendTypedCommand(conn, 'C', 'S', stmt)) if (!PQsendTypedCommand(conn, PqMsg_Close, 'S', stmt))
return NULL; return NULL;
return PQexecFinish(conn); return PQexecFinish(conn);
} }
@ -2506,7 +2506,7 @@ PQclosePortal(PGconn *conn, const char *portal)
{ {
if (!PQexecStart(conn)) if (!PQexecStart(conn))
return NULL; return NULL;
if (!PQsendTypedCommand(conn, 'C', 'P', portal)) if (!PQsendTypedCommand(conn, PqMsg_Close, 'P', portal))
return NULL; return NULL;
return PQexecFinish(conn); return PQexecFinish(conn);
} }
@ -2521,7 +2521,7 @@ PQclosePortal(PGconn *conn, const char *portal)
int int
PQsendClosePrepared(PGconn *conn, const char *stmt) PQsendClosePrepared(PGconn *conn, const char *stmt)
{ {
return PQsendTypedCommand(conn, 'C', 'S', stmt); return PQsendTypedCommand(conn, PqMsg_Close, 'S', stmt);
} }
/* /*
@ -2534,7 +2534,7 @@ PQsendClosePrepared(PGconn *conn, const char *stmt)
int int
PQsendClosePortal(PGconn *conn, const char *portal) PQsendClosePortal(PGconn *conn, const char *portal)
{ {
return PQsendTypedCommand(conn, 'C', 'P', portal); return PQsendTypedCommand(conn, PqMsg_Close, 'P', portal);
} }
/* /*
@ -2542,8 +2542,8 @@ PQsendClosePortal(PGconn *conn, const char *portal)
* Common code to send a Describe or Close command * Common code to send a Describe or Close command
* *
* Available options for "command" are * Available options for "command" are
* 'C' for Close; or * PqMsg_Close for Close; or
* 'D' for Describe. * PqMsg_Describe for Describe.
* *
* Available options for "type" are * Available options for "type" are
* 'S' to run a command on a prepared statement; or * 'S' to run a command on a prepared statement; or
@ -2577,17 +2577,17 @@ PQsendTypedCommand(PGconn *conn, char command, char type, const char *target)
/* construct the Sync message */ /* construct the Sync message */
if (conn->pipelineStatus == PQ_PIPELINE_OFF) if (conn->pipelineStatus == PQ_PIPELINE_OFF)
{ {
if (pqPutMsgStart('S', conn) < 0 || if (pqPutMsgStart(PqMsg_Sync, conn) < 0 ||
pqPutMsgEnd(conn) < 0) pqPutMsgEnd(conn) < 0)
goto sendFailed; goto sendFailed;
} }
/* remember if we are doing a Close or a Describe */ /* remember if we are doing a Close or a Describe */
if (command == 'C') if (command == PqMsg_Close)
{ {
entry->queryclass = PGQUERY_CLOSE; entry->queryclass = PGQUERY_CLOSE;
} }
else if (command == 'D') else if (command == PqMsg_Describe)
{ {
entry->queryclass = PGQUERY_DESCRIBE; entry->queryclass = PGQUERY_DESCRIBE;
} }
@ -2696,7 +2696,7 @@ PQputCopyData(PGconn *conn, const char *buffer, int nbytes)
return pqIsnonblocking(conn) ? 0 : -1; return pqIsnonblocking(conn) ? 0 : -1;
} }
/* Send the data (too simple to delegate to fe-protocol files) */ /* Send the data (too simple to delegate to fe-protocol files) */
if (pqPutMsgStart('d', conn) < 0 || if (pqPutMsgStart(PqMsg_CopyData, conn) < 0 ||
pqPutnchar(buffer, nbytes, conn) < 0 || pqPutnchar(buffer, nbytes, conn) < 0 ||
pqPutMsgEnd(conn) < 0) pqPutMsgEnd(conn) < 0)
return -1; return -1;
@ -2731,7 +2731,7 @@ PQputCopyEnd(PGconn *conn, const char *errormsg)
if (errormsg) if (errormsg)
{ {
/* Send COPY FAIL */ /* Send COPY FAIL */
if (pqPutMsgStart('f', conn) < 0 || if (pqPutMsgStart(PqMsg_CopyFail, conn) < 0 ||
pqPuts(errormsg, conn) < 0 || pqPuts(errormsg, conn) < 0 ||
pqPutMsgEnd(conn) < 0) pqPutMsgEnd(conn) < 0)
return -1; return -1;
@ -2739,7 +2739,7 @@ PQputCopyEnd(PGconn *conn, const char *errormsg)
else else
{ {
/* Send COPY DONE */ /* Send COPY DONE */
if (pqPutMsgStart('c', conn) < 0 || if (pqPutMsgStart(PqMsg_CopyDone, conn) < 0 ||
pqPutMsgEnd(conn) < 0) pqPutMsgEnd(conn) < 0)
return -1; return -1;
} }
@ -2751,7 +2751,7 @@ PQputCopyEnd(PGconn *conn, const char *errormsg)
if (conn->cmd_queue_head && if (conn->cmd_queue_head &&
conn->cmd_queue_head->queryclass != PGQUERY_SIMPLE) conn->cmd_queue_head->queryclass != PGQUERY_SIMPLE)
{ {
if (pqPutMsgStart('S', conn) < 0 || if (pqPutMsgStart(PqMsg_Sync, conn) < 0 ||
pqPutMsgEnd(conn) < 0) pqPutMsgEnd(conn) < 0)
return -1; return -1;
} }
@ -3263,7 +3263,7 @@ PQpipelineSync(PGconn *conn)
entry->query = NULL; entry->query = NULL;
/* construct the Sync message */ /* construct the Sync message */
if (pqPutMsgStart('S', conn) < 0 || if (pqPutMsgStart(PqMsg_Sync, conn) < 0 ||
pqPutMsgEnd(conn) < 0) pqPutMsgEnd(conn) < 0)
goto sendFailed; goto sendFailed;
@ -3311,7 +3311,7 @@ PQsendFlushRequest(PGconn *conn)
return 0; return 0;
} }
if (pqPutMsgStart('H', conn) < 0 || if (pqPutMsgStart(PqMsg_Flush, conn) < 0 ||
pqPutMsgEnd(conn) < 0) pqPutMsgEnd(conn) < 0)
{ {
return 0; return 0;

View File

@ -34,8 +34,13 @@
* than a couple of kilobytes). * than a couple of kilobytes).
*/ */
#define VALID_LONG_MESSAGE_TYPE(id) \ #define VALID_LONG_MESSAGE_TYPE(id) \
((id) == 'T' || (id) == 'D' || (id) == 'd' || (id) == 'V' || \ ((id) == PqMsg_CopyData || \
(id) == 'E' || (id) == 'N' || (id) == 'A') (id) == PqMsg_DataRow || \
(id) == PqMsg_ErrorResponse || \
(id) == PqMsg_FunctionCallResponse || \
(id) == PqMsg_NoticeResponse || \
(id) == PqMsg_NotificationResponse || \
(id) == PqMsg_RowDescription)
static void handleSyncLoss(PGconn *conn, char id, int msgLength); static void handleSyncLoss(PGconn *conn, char id, int msgLength);
@ -140,12 +145,12 @@ pqParseInput3(PGconn *conn)
* from config file due to SIGHUP), but otherwise we hold off until * from config file due to SIGHUP), but otherwise we hold off until
* BUSY state. * BUSY state.
*/ */
if (id == 'A') if (id == PqMsg_NotificationResponse)
{ {
if (getNotify(conn)) if (getNotify(conn))
return; return;
} }
else if (id == 'N') else if (id == PqMsg_NoticeResponse)
{ {
if (pqGetErrorNotice3(conn, false)) if (pqGetErrorNotice3(conn, false))
return; return;
@ -165,12 +170,12 @@ pqParseInput3(PGconn *conn)
* it is about to close the connection, so we don't want to just * it is about to close the connection, so we don't want to just
* discard it...) * discard it...)
*/ */
if (id == 'E') if (id == PqMsg_ErrorResponse)
{ {
if (pqGetErrorNotice3(conn, false /* treat as notice */ )) if (pqGetErrorNotice3(conn, false /* treat as notice */ ))
return; return;
} }
else if (id == 'S') else if (id == PqMsg_ParameterStatus)
{ {
if (getParameterStatus(conn)) if (getParameterStatus(conn))
return; return;
@ -192,7 +197,7 @@ pqParseInput3(PGconn *conn)
*/ */
switch (id) switch (id)
{ {
case 'C': /* command complete */ case PqMsg_CommandComplete:
if (pqGets(&conn->workBuffer, conn)) if (pqGets(&conn->workBuffer, conn))
return; return;
if (!pgHavePendingResult(conn)) if (!pgHavePendingResult(conn))
@ -210,13 +215,12 @@ pqParseInput3(PGconn *conn)
CMDSTATUS_LEN); CMDSTATUS_LEN);
conn->asyncStatus = PGASYNC_READY; conn->asyncStatus = PGASYNC_READY;
break; break;
case 'E': /* error return */ case PqMsg_ErrorResponse:
if (pqGetErrorNotice3(conn, true)) if (pqGetErrorNotice3(conn, true))
return; return;
conn->asyncStatus = PGASYNC_READY; conn->asyncStatus = PGASYNC_READY;
break; break;
case 'Z': /* sync response, backend is ready for new case PqMsg_ReadyForQuery:
* query */
if (getReadyForQuery(conn)) if (getReadyForQuery(conn))
return; return;
if (conn->pipelineStatus != PQ_PIPELINE_OFF) if (conn->pipelineStatus != PQ_PIPELINE_OFF)
@ -246,7 +250,7 @@ pqParseInput3(PGconn *conn)
conn->asyncStatus = PGASYNC_IDLE; conn->asyncStatus = PGASYNC_IDLE;
} }
break; break;
case 'I': /* empty query */ case PqMsg_EmptyQueryResponse:
if (!pgHavePendingResult(conn)) if (!pgHavePendingResult(conn))
{ {
conn->result = PQmakeEmptyPGresult(conn, conn->result = PQmakeEmptyPGresult(conn,
@ -259,7 +263,7 @@ pqParseInput3(PGconn *conn)
} }
conn->asyncStatus = PGASYNC_READY; conn->asyncStatus = PGASYNC_READY;
break; break;
case '1': /* Parse Complete */ case PqMsg_ParseComplete:
/* If we're doing PQprepare, we're done; else ignore */ /* If we're doing PQprepare, we're done; else ignore */
if (conn->cmd_queue_head && if (conn->cmd_queue_head &&
conn->cmd_queue_head->queryclass == PGQUERY_PREPARE) conn->cmd_queue_head->queryclass == PGQUERY_PREPARE)
@ -277,10 +281,10 @@ pqParseInput3(PGconn *conn)
conn->asyncStatus = PGASYNC_READY; conn->asyncStatus = PGASYNC_READY;
} }
break; break;
case '2': /* Bind Complete */ case PqMsg_BindComplete:
/* Nothing to do for this message type */ /* Nothing to do for this message type */
break; break;
case '3': /* Close Complete */ case PqMsg_CloseComplete:
/* If we're doing PQsendClose, we're done; else ignore */ /* If we're doing PQsendClose, we're done; else ignore */
if (conn->cmd_queue_head && if (conn->cmd_queue_head &&
conn->cmd_queue_head->queryclass == PGQUERY_CLOSE) conn->cmd_queue_head->queryclass == PGQUERY_CLOSE)
@ -298,11 +302,11 @@ pqParseInput3(PGconn *conn)
conn->asyncStatus = PGASYNC_READY; conn->asyncStatus = PGASYNC_READY;
} }
break; break;
case 'S': /* parameter status */ case PqMsg_ParameterStatus:
if (getParameterStatus(conn)) if (getParameterStatus(conn))
return; return;
break; break;
case 'K': /* secret key data from the backend */ case PqMsg_BackendKeyData:
/* /*
* This is expected only during backend startup, but it's * This is expected only during backend startup, but it's
@ -314,7 +318,7 @@ pqParseInput3(PGconn *conn)
if (pqGetInt(&(conn->be_key), 4, conn)) if (pqGetInt(&(conn->be_key), 4, conn))
return; return;
break; break;
case 'T': /* Row Description */ case PqMsg_RowDescription:
if (conn->error_result || if (conn->error_result ||
(conn->result != NULL && (conn->result != NULL &&
conn->result->resultStatus == PGRES_FATAL_ERROR)) conn->result->resultStatus == PGRES_FATAL_ERROR))
@ -346,7 +350,7 @@ pqParseInput3(PGconn *conn)
return; return;
} }
break; break;
case 'n': /* No Data */ case PqMsg_NoData:
/* /*
* NoData indicates that we will not be seeing a * NoData indicates that we will not be seeing a
@ -374,11 +378,11 @@ pqParseInput3(PGconn *conn)
conn->asyncStatus = PGASYNC_READY; conn->asyncStatus = PGASYNC_READY;
} }
break; break;
case 't': /* Parameter Description */ case PqMsg_ParameterDescription:
if (getParamDescriptions(conn, msgLength)) if (getParamDescriptions(conn, msgLength))
return; return;
break; break;
case 'D': /* Data Row */ case PqMsg_DataRow:
if (conn->result != NULL && if (conn->result != NULL &&
conn->result->resultStatus == PGRES_TUPLES_OK) conn->result->resultStatus == PGRES_TUPLES_OK)
{ {
@ -405,24 +409,24 @@ pqParseInput3(PGconn *conn)
conn->inCursor += msgLength; conn->inCursor += msgLength;
} }
break; break;
case 'G': /* Start Copy In */ case PqMsg_CopyInResponse:
if (getCopyStart(conn, PGRES_COPY_IN)) if (getCopyStart(conn, PGRES_COPY_IN))
return; return;
conn->asyncStatus = PGASYNC_COPY_IN; conn->asyncStatus = PGASYNC_COPY_IN;
break; break;
case 'H': /* Start Copy Out */ case PqMsg_CopyOutResponse:
if (getCopyStart(conn, PGRES_COPY_OUT)) if (getCopyStart(conn, PGRES_COPY_OUT))
return; return;
conn->asyncStatus = PGASYNC_COPY_OUT; conn->asyncStatus = PGASYNC_COPY_OUT;
conn->copy_already_done = 0; conn->copy_already_done = 0;
break; break;
case 'W': /* Start Copy Both */ case PqMsg_CopyBothResponse:
if (getCopyStart(conn, PGRES_COPY_BOTH)) if (getCopyStart(conn, PGRES_COPY_BOTH))
return; return;
conn->asyncStatus = PGASYNC_COPY_BOTH; conn->asyncStatus = PGASYNC_COPY_BOTH;
conn->copy_already_done = 0; conn->copy_already_done = 0;
break; break;
case 'd': /* Copy Data */ case PqMsg_CopyData:
/* /*
* If we see Copy Data, just silently drop it. This would * If we see Copy Data, just silently drop it. This would
@ -431,7 +435,7 @@ pqParseInput3(PGconn *conn)
*/ */
conn->inCursor += msgLength; conn->inCursor += msgLength;
break; break;
case 'c': /* Copy Done */ case PqMsg_CopyDone:
/* /*
* If we see Copy Done, just silently drop it. This is * If we see Copy Done, just silently drop it. This is
@ -1692,21 +1696,21 @@ getCopyDataMessage(PGconn *conn)
*/ */
switch (id) switch (id)
{ {
case 'A': /* NOTIFY */ case PqMsg_NotificationResponse:
if (getNotify(conn)) if (getNotify(conn))
return 0; return 0;
break; break;
case 'N': /* NOTICE */ case PqMsg_NoticeResponse:
if (pqGetErrorNotice3(conn, false)) if (pqGetErrorNotice3(conn, false))
return 0; return 0;
break; break;
case 'S': /* ParameterStatus */ case PqMsg_ParameterStatus:
if (getParameterStatus(conn)) if (getParameterStatus(conn))
return 0; return 0;
break; break;
case 'd': /* Copy Data, pass it back to caller */ case PqMsg_CopyData:
return msgLength; return msgLength;
case 'c': case PqMsg_CopyDone:
/* /*
* If this is a CopyDone message, exit COPY_OUT mode and let * If this is a CopyDone message, exit COPY_OUT mode and let
@ -1929,7 +1933,7 @@ pqEndcopy3(PGconn *conn)
if (conn->asyncStatus == PGASYNC_COPY_IN || if (conn->asyncStatus == PGASYNC_COPY_IN ||
conn->asyncStatus == PGASYNC_COPY_BOTH) conn->asyncStatus == PGASYNC_COPY_BOTH)
{ {
if (pqPutMsgStart('c', conn) < 0 || if (pqPutMsgStart(PqMsg_CopyDone, conn) < 0 ||
pqPutMsgEnd(conn) < 0) pqPutMsgEnd(conn) < 0)
return 1; return 1;
@ -1940,7 +1944,7 @@ pqEndcopy3(PGconn *conn)
if (conn->cmd_queue_head && if (conn->cmd_queue_head &&
conn->cmd_queue_head->queryclass != PGQUERY_SIMPLE) conn->cmd_queue_head->queryclass != PGQUERY_SIMPLE)
{ {
if (pqPutMsgStart('S', conn) < 0 || if (pqPutMsgStart(PqMsg_Sync, conn) < 0 ||
pqPutMsgEnd(conn) < 0) pqPutMsgEnd(conn) < 0)
return 1; return 1;
} }
@ -2023,7 +2027,7 @@ pqFunctionCall3(PGconn *conn, Oid fnid,
/* PQfn already validated connection state */ /* PQfn already validated connection state */
if (pqPutMsgStart('F', conn) < 0 || /* function call msg */ if (pqPutMsgStart(PqMsg_FunctionCall, conn) < 0 ||
pqPutInt(fnid, 4, conn) < 0 || /* function id */ pqPutInt(fnid, 4, conn) < 0 || /* function id */
pqPutInt(1, 2, conn) < 0 || /* # of format codes */ pqPutInt(1, 2, conn) < 0 || /* # of format codes */
pqPutInt(1, 2, conn) < 0 || /* format code: BINARY */ pqPutInt(1, 2, conn) < 0 || /* format code: BINARY */

View File

@ -562,110 +562,120 @@ pqTraceOutputMessage(PGconn *conn, const char *message, bool toServer)
switch (id) switch (id)
{ {
case '1': case PqMsg_ParseComplete:
fprintf(conn->Pfdebug, "ParseComplete"); fprintf(conn->Pfdebug, "ParseComplete");
/* No message content */ /* No message content */
break; break;
case '2': case PqMsg_BindComplete:
fprintf(conn->Pfdebug, "BindComplete"); fprintf(conn->Pfdebug, "BindComplete");
/* No message content */ /* No message content */
break; break;
case '3': case PqMsg_CloseComplete:
fprintf(conn->Pfdebug, "CloseComplete"); fprintf(conn->Pfdebug, "CloseComplete");
/* No message content */ /* No message content */
break; break;
case 'A': /* Notification Response */ case PqMsg_NotificationResponse:
pqTraceOutputA(conn->Pfdebug, message, &logCursor, regress); pqTraceOutputA(conn->Pfdebug, message, &logCursor, regress);
break; break;
case 'B': /* Bind */ case PqMsg_Bind:
pqTraceOutputB(conn->Pfdebug, message, &logCursor); pqTraceOutputB(conn->Pfdebug, message, &logCursor);
break; break;
case 'c': case PqMsg_CopyDone:
fprintf(conn->Pfdebug, "CopyDone"); fprintf(conn->Pfdebug, "CopyDone");
/* No message content */ /* No message content */
break; break;
case 'C': /* Close(F) or Command Complete(B) */ case PqMsg_CommandComplete:
/* Close(F) and CommandComplete(B) use the same identifier. */
Assert(PqMsg_Close == PqMsg_CommandComplete);
pqTraceOutputC(conn->Pfdebug, toServer, message, &logCursor); pqTraceOutputC(conn->Pfdebug, toServer, message, &logCursor);
break; break;
case 'd': /* Copy Data */ case PqMsg_CopyData:
/* Drop COPY data to reduce the overhead of logging. */ /* Drop COPY data to reduce the overhead of logging. */
break; break;
case 'D': /* Describe(F) or Data Row(B) */ case PqMsg_Describe:
/* Describe(F) and DataRow(B) use the same identifier. */
Assert(PqMsg_Describe == PqMsg_DataRow);
pqTraceOutputD(conn->Pfdebug, toServer, message, &logCursor); pqTraceOutputD(conn->Pfdebug, toServer, message, &logCursor);
break; break;
case 'E': /* Execute(F) or Error Response(B) */ case PqMsg_Execute:
/* Execute(F) and ErrorResponse(B) use the same identifier. */
Assert(PqMsg_Execute == PqMsg_ErrorResponse);
pqTraceOutputE(conn->Pfdebug, toServer, message, &logCursor, pqTraceOutputE(conn->Pfdebug, toServer, message, &logCursor,
regress); regress);
break; break;
case 'f': /* Copy Fail */ case PqMsg_CopyFail:
pqTraceOutputf(conn->Pfdebug, message, &logCursor); pqTraceOutputf(conn->Pfdebug, message, &logCursor);
break; break;
case 'F': /* Function Call */ case PqMsg_FunctionCall:
pqTraceOutputF(conn->Pfdebug, message, &logCursor, regress); pqTraceOutputF(conn->Pfdebug, message, &logCursor, regress);
break; break;
case 'G': /* Start Copy In */ case PqMsg_CopyInResponse:
pqTraceOutputG(conn->Pfdebug, message, &logCursor); pqTraceOutputG(conn->Pfdebug, message, &logCursor);
break; break;
case 'H': /* Flush(F) or Start Copy Out(B) */ case PqMsg_Flush:
/* Flush(F) and CopyOutResponse(B) use the same identifier */
Assert(PqMsg_CopyOutResponse == PqMsg_Flush);
if (!toServer) if (!toServer)
pqTraceOutputH(conn->Pfdebug, message, &logCursor); pqTraceOutputH(conn->Pfdebug, message, &logCursor);
else else
fprintf(conn->Pfdebug, "Flush"); /* no message content */ fprintf(conn->Pfdebug, "Flush"); /* no message content */
break; break;
case 'I': case PqMsg_EmptyQueryResponse:
fprintf(conn->Pfdebug, "EmptyQueryResponse"); fprintf(conn->Pfdebug, "EmptyQueryResponse");
/* No message content */ /* No message content */
break; break;
case 'K': /* secret key data from the backend */ case PqMsg_BackendKeyData:
pqTraceOutputK(conn->Pfdebug, message, &logCursor, regress); pqTraceOutputK(conn->Pfdebug, message, &logCursor, regress);
break; break;
case 'n': case PqMsg_NoData:
fprintf(conn->Pfdebug, "NoData"); fprintf(conn->Pfdebug, "NoData");
/* No message content */ /* No message content */
break; break;
case 'N': case PqMsg_NoticeResponse:
pqTraceOutputNR(conn->Pfdebug, "NoticeResponse", message, pqTraceOutputNR(conn->Pfdebug, "NoticeResponse", message,
&logCursor, regress); &logCursor, regress);
break; break;
case 'P': /* Parse */ case PqMsg_Parse:
pqTraceOutputP(conn->Pfdebug, message, &logCursor, regress); pqTraceOutputP(conn->Pfdebug, message, &logCursor, regress);
break; break;
case 'Q': /* Query */ case PqMsg_Query:
pqTraceOutputQ(conn->Pfdebug, message, &logCursor); pqTraceOutputQ(conn->Pfdebug, message, &logCursor);
break; break;
case 'R': /* Authentication */ case PqMsg_AuthenticationRequest:
pqTraceOutputR(conn->Pfdebug, message, &logCursor); pqTraceOutputR(conn->Pfdebug, message, &logCursor);
break; break;
case 's': case PqMsg_PortalSuspended:
fprintf(conn->Pfdebug, "PortalSuspended"); fprintf(conn->Pfdebug, "PortalSuspended");
/* No message content */ /* No message content */
break; break;
case 'S': /* Parameter Status(B) or Sync(F) */ case PqMsg_Sync:
/* Parameter Status(B) and Sync(F) use the same identifier */
Assert(PqMsg_ParameterStatus == PqMsg_Sync);
if (!toServer) if (!toServer)
pqTraceOutputS(conn->Pfdebug, message, &logCursor); pqTraceOutputS(conn->Pfdebug, message, &logCursor);
else else
fprintf(conn->Pfdebug, "Sync"); /* no message content */ fprintf(conn->Pfdebug, "Sync"); /* no message content */
break; break;
case 't': /* Parameter Description */ case PqMsg_ParameterDescription:
pqTraceOutputt(conn->Pfdebug, message, &logCursor, regress); pqTraceOutputt(conn->Pfdebug, message, &logCursor, regress);
break; break;
case 'T': /* Row Description */ case PqMsg_RowDescription:
pqTraceOutputT(conn->Pfdebug, message, &logCursor, regress); pqTraceOutputT(conn->Pfdebug, message, &logCursor, regress);
break; break;
case 'v': /* Negotiate Protocol Version */ case PqMsg_NegotiateProtocolVersion:
pqTraceOutputv(conn->Pfdebug, message, &logCursor); pqTraceOutputv(conn->Pfdebug, message, &logCursor);
break; break;
case 'V': /* Function Call response */ case PqMsg_FunctionCallResponse:
pqTraceOutputV(conn->Pfdebug, message, &logCursor); pqTraceOutputV(conn->Pfdebug, message, &logCursor);
break; break;
case 'W': /* Start Copy Both */ case PqMsg_CopyBothResponse:
pqTraceOutputW(conn->Pfdebug, message, &logCursor, length); pqTraceOutputW(conn->Pfdebug, message, &logCursor, length);
break; break;
case 'X': case PqMsg_Terminate:
fprintf(conn->Pfdebug, "Terminate"); fprintf(conn->Pfdebug, "Terminate");
/* No message content */ /* No message content */
break; break;
case 'Z': /* Ready For Query */ case PqMsg_ReadyForQuery:
pqTraceOutputZ(conn->Pfdebug, message, &logCursor); pqTraceOutputZ(conn->Pfdebug, message, &logCursor);
break; break;
default: default:

View File

@ -614,6 +614,8 @@ sub CopyIncludeFiles
'src/include/', 'c.h', 'port.h', 'postgres_fe.h'); 'src/include/', 'c.h', 'port.h', 'postgres_fe.h');
lcopy('src/include/libpq/pqcomm.h', $target . '/include/internal/libpq/') lcopy('src/include/libpq/pqcomm.h', $target . '/include/internal/libpq/')
|| croak 'Could not copy pqcomm.h'; || croak 'Could not copy pqcomm.h';
lcopy('src/include/libpq/protocol.h', $target . '/include/internal/libpq/')
|| croak 'Could not copy protocol.h';
CopyFiles( CopyFiles(
'Server headers', 'Server headers',