Introduce macros for protocol characters.
authorNathan Bossart <[email protected]>
Wed, 23 Aug 2023 02:16:12 +0000 (19:16 -0700)
committerNathan Bossart <[email protected]>
Wed, 23 Aug 2023 02:16:12 +0000 (19:16 -0700)
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

25 files changed:
src/backend/access/common/printsimple.c
src/backend/access/transam/parallel.c
src/backend/backup/basebackup_copy.c
src/backend/commands/async.c
src/backend/commands/copyfromparse.c
src/backend/commands/copyto.c
src/backend/libpq/auth-sasl.c
src/backend/libpq/auth.c
src/backend/postmaster/postmaster.c
src/backend/replication/walsender.c
src/backend/tcop/dest.c
src/backend/tcop/fastpath.c
src/backend/tcop/postgres.c
src/backend/utils/error/elog.c
src/backend/utils/misc/guc.c
src/include/Makefile
src/include/libpq/pqcomm.h
src/include/libpq/protocol.h[new file with mode: 0644]
src/include/meson.build
src/interfaces/libpq/fe-auth.c
src/interfaces/libpq/fe-connect.c
src/interfaces/libpq/fe-exec.c
src/interfaces/libpq/fe-protocol3.c
src/interfaces/libpq/fe-trace.c
src/tools/msvc/Install.pm

index ef818228acb395a7fd4ac96606c7113fed5aa2c9..675b744db20770cf3a76a55b87b24c39b576f007 100644 (file)
@@ -20,6 +20,7 @@
 
 #include "access/printsimple.h"
 #include "catalog/pg_type.h"
+#include "libpq/protocol.h"
 #include "libpq/pqformat.h"
 #include "utils/builtins.h"
 
@@ -32,7 +33,7 @@ printsimple_startup(DestReceiver *self, int operation, TupleDesc tupdesc)
    StringInfoData buf;
    int         i;
 
-   pq_beginmessage(&buf, 'T'); /* RowDescription */
+   pq_beginmessage(&buf, PqMsg_RowDescription);
    pq_sendint16(&buf, tupdesc->natts);
 
    for (i = 0; i < tupdesc->natts; ++i)
@@ -65,7 +66,7 @@ printsimple(TupleTableSlot *slot, DestReceiver *self)
    slot_getallattrs(slot);
 
    /* Prepare and send message */
-   pq_beginmessage(&buf, 'D');
+   pq_beginmessage(&buf, PqMsg_DataRow);
    pq_sendint16(&buf, tupdesc->natts);
 
    for (i = 0; i < tupdesc->natts; ++i)
index 1738aecf1f0d619540152f88db34c5f7cc2d5b2f..194a1207be6ef85878f21e41732af11d3821afac 100644 (file)
@@ -1127,7 +1127,7 @@ HandleParallelMessage(ParallelContext *pcxt, int i, StringInfo msg)
 
    switch (msgtype)
    {
-       case 'K':               /* BackendKeyData */
+       case PqMsg_BackendKeyData:
            {
                int32       pid = pq_getmsgint(msg, 4);
 
@@ -1137,8 +1137,8 @@ HandleParallelMessage(ParallelContext *pcxt, int i, StringInfo msg)
                break;
            }
 
-       case 'E':               /* ErrorResponse */
-       case 'N':               /* NoticeResponse */
+       case PqMsg_ErrorResponse:
+       case PqMsg_NoticeResponse:
            {
                ErrorData   edata;
                ErrorContextCallback *save_error_context_stack;
@@ -1183,7 +1183,7 @@ HandleParallelMessage(ParallelContext *pcxt, int i, StringInfo msg)
                break;
            }
 
-       case 'A':               /* NotifyResponse */
+       case PqMsg_NotificationResponse:
            {
                /* Propagate NotifyResponse. */
                int32       pid;
@@ -1217,7 +1217,7 @@ HandleParallelMessage(ParallelContext *pcxt, int i, StringInfo msg)
                break;
            }
 
-       case 'X':               /* Terminate, indicating clean exit */
+       case PqMsg_Terminate:
            {
                shm_mq_detach(pcxt->worker[i].error_mqh);
                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
     * in this case.
     */
-   pq_beginmessage(&msgbuf, 'K');
+   pq_beginmessage(&msgbuf, PqMsg_BackendKeyData);
    pq_sendint32(&msgbuf, (int32) MyProcPid);
    pq_sendint32(&msgbuf, (int32) MyCancelKey);
    pq_endmessage(&msgbuf);
@@ -1550,7 +1550,7 @@ ParallelWorkerMain(Datum main_arg)
    DetachSession();
 
    /* Report success. */
-   pq_putmessage('X', NULL, 0);
+   pq_putmessage(PqMsg_Terminate, NULL, 0);
 }
 
 /*
index 1db80cde1b2cf60bb2d64a83b7c702f8a0d41404..fee30c21e10a8e1e6910cad405d86e59a5519b7e 100644 (file)
@@ -152,7 +152,7 @@ bbsink_copystream_begin_backup(bbsink *sink)
    SendTablespaceList(state->tablespaces);
 
    /* Send a CommandComplete message */
-   pq_puttextmessage('C', "SELECT");
+   pq_puttextmessage(PqMsg_CommandComplete, "SELECT");
 
    /* Begin COPY stream. This will be used for all archives + manifest. */
    SendCopyOutResponse();
@@ -169,7 +169,7 @@ bbsink_copystream_begin_archive(bbsink *sink, const char *archive_name)
    StringInfoData buf;
 
    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_sendstring(&buf, archive_name);
    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;
 
-           pq_beginmessage(&buf, 'd'); /* CopyData */
+           pq_beginmessage(&buf, PqMsg_CopyData);
            pq_sendbyte(&buf, 'p'); /* Progress report */
            pq_sendint64(&buf, state->bytes_done);
            pq_endmessage(&buf);
@@ -246,7 +246,7 @@ bbsink_copystream_end_archive(bbsink *sink)
 
    mysink->bytes_done_at_last_time_check = state->bytes_done;
    mysink->last_progress_report_time = GetCurrentTimestamp();
-   pq_beginmessage(&buf, 'd'); /* CopyData */
+   pq_beginmessage(&buf, PqMsg_CopyData);
    pq_sendbyte(&buf, 'p');     /* Progress report */
    pq_sendint64(&buf, state->bytes_done);
    pq_endmessage(&buf);
@@ -261,7 +261,7 @@ bbsink_copystream_begin_manifest(bbsink *sink)
 {
    StringInfoData buf;
 
-   pq_beginmessage(&buf, 'd'); /* CopyData */
+   pq_beginmessage(&buf, PqMsg_CopyData);
    pq_sendbyte(&buf, 'm');     /* Manifest */
    pq_endmessage(&buf);
 }
@@ -318,7 +318,7 @@ SendCopyOutResponse(void)
 {
    StringInfoData buf;
 
-   pq_beginmessage(&buf, 'H');
+   pq_beginmessage(&buf, PqMsg_CopyOutResponse);
    pq_sendbyte(&buf, 0);       /* overall format */
    pq_sendint16(&buf, 0);      /* natts */
    pq_endmessage(&buf);
@@ -330,7 +330,7 @@ SendCopyOutResponse(void)
 static void
 SendCopyDone(void)
 {
-   pq_putemptymessage('c');
+   pq_putemptymessage(PqMsg_CopyDone);
 }
 
 /*
@@ -368,7 +368,7 @@ SendXlogRecPtrResult(XLogRecPtr ptr, TimeLineID tli)
    end_tup_output(tstate);
 
    /* Send a CommandComplete message */
-   pq_puttextmessage('C', "SELECT");
+   pq_puttextmessage(PqMsg_CommandComplete, "SELECT");
 }
 
 /*
index ef909cf4e082df33b72bab7c9986fa4150f69457..d148d10850af2c5d271ecf01acc14833d7301ad7 100644 (file)
@@ -2281,7 +2281,7 @@ NotifyMyFrontEnd(const char *channel, const char *payload, int32 srcPid)
    {
        StringInfoData buf;
 
-       pq_beginmessage(&buf, 'A');
+       pq_beginmessage(&buf, PqMsg_NotificationResponse);
        pq_sendint32(&buf, srcPid);
        pq_sendstring(&buf, channel);
        pq_sendstring(&buf, payload);
index 232768a6e139a5dbaa8df9e33cde37611b639bd3..f553734582f5e1e1c4157766f82f97b332d2d88f 100644 (file)
@@ -174,7 +174,7 @@ ReceiveCopyBegin(CopyFromState cstate)
    int16       format = (cstate->opts.binary ? 1 : 0);
    int         i;
 
-   pq_beginmessage(&buf, 'G');
+   pq_beginmessage(&buf, PqMsg_CopyInResponse);
    pq_sendbyte(&buf, format);  /* overall format */
    pq_sendint16(&buf, natts);
    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 */
                    switch (mtype)
                    {
-                       case 'd':   /* CopyData */
+                       case PqMsg_CopyData:
                            maxmsglen = PQ_LARGE_MESSAGE_LIMIT;
                            break;
-                       case 'c':   /* CopyDone */
-                       case 'f':   /* CopyFail */
-                       case 'H':   /* Flush */
-                       case 'S':   /* Sync */
+                       case PqMsg_CopyDone:
+                       case PqMsg_CopyFail:
+                       case PqMsg_Flush:
+                       case PqMsg_Sync:
                            maxmsglen = PQ_SMALL_MESSAGE_LIMIT;
                            break;
                        default:
@@ -305,20 +305,20 @@ CopyGetData(CopyFromState cstate, void *databuf, int minread, int maxread)
                    /* ... and process it */
                    switch (mtype)
                    {
-                       case 'd':   /* CopyData */
+                       case PqMsg_CopyData:
                            break;
-                       case 'c':   /* CopyDone */
+                       case PqMsg_CopyDone:
                            /* COPY IN correctly terminated by frontend */
                            cstate->raw_reached_eof = true;
                            return bytesread;
-                       case 'f':   /* CopyFail */
+                       case PqMsg_CopyFail:
                            ereport(ERROR,
                                    (errcode(ERRCODE_QUERY_CANCELED),
                                     errmsg("COPY from stdin failed: %s",
                                            pq_getmsgstring(cstate->fe_msgbuf))));
                            break;
-                       case 'H':   /* Flush */
-                       case 'S':   /* Sync */
+                       case PqMsg_Flush:
+                       case PqMsg_Sync:
 
                            /*
                             * Ignore Flush/Sync for the convenience of client
index 9e4b2437a572a5f0d84f7ba2dedf4c8b38b6771f..eaa3172793a48813e165a539cff5c8633faaf4ac 100644 (file)
@@ -144,7 +144,7 @@ SendCopyBegin(CopyToState cstate)
    int16       format = (cstate->opts.binary ? 1 : 0);
    int         i;
 
-   pq_beginmessage(&buf, 'H');
+   pq_beginmessage(&buf, PqMsg_CopyOutResponse);
    pq_sendbyte(&buf, format);  /* overall format */
    pq_sendint16(&buf, natts);
    for (i = 0; i < natts; i++)
@@ -159,7 +159,7 @@ SendCopyEnd(CopyToState cstate)
    /* Shouldn't have any unsent data */
    Assert(cstate->fe_msgbuf->len == 0);
    /* Send Copy Done message */
-   pq_putemptymessage('c');
+   pq_putemptymessage(PqMsg_CopyDone);
 }
 
 /*----------
@@ -247,7 +247,7 @@ CopySendEndOfRow(CopyToState cstate)
                CopySendChar(cstate, '\n');
 
            /* 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;
        case COPY_CALLBACK:
            cstate->data_dest_cb(fe_msgbuf->data, fe_msgbuf->len);
index 684680897bcd39031a13a92b6f75afa219669499..c535bc53835ffec3a5df404b357ea24b6c16b099 100644 (file)
@@ -87,7 +87,7 @@ CheckSASLAuth(const pg_be_sasl_mech *mech, Port *port, char *shadow_pass,
    {
        pq_startmsgread();
        mtype = pq_getbyte();
-       if (mtype != 'p')
+       if (mtype != PqMsg_SASLResponse)
        {
            /* Only log error if client didn't disconnect. */
            if (mtype != EOF)
index 315a24bb3f9ac05ee1d462d6252ead2d9c45fdf3..0356fe3e454e33f2eace34be04fafaf563400a53 100644 (file)
@@ -665,7 +665,7 @@ sendAuthRequest(Port *port, AuthRequest areq, const char *extradata, int extrale
 
    CHECK_FOR_INTERRUPTS();
 
-   pq_beginmessage(&buf, 'R');
+   pq_beginmessage(&buf, PqMsg_AuthenticationRequest);
    pq_sendint32(&buf, (int32) areq);
    if (extralen > 0)
        pq_sendbytes(&buf, extradata, extralen);
@@ -698,7 +698,7 @@ recv_password_packet(Port *port)
 
    /* Expect 'p' message type */
    mtype = pq_getbyte();
-   if (mtype != 'p')
+   if (mtype != PqMsg_PasswordMessage)
    {
        /*
         * If the client just disconnects without offering a password, don't
@@ -961,7 +961,7 @@ pg_GSS_recvauth(Port *port)
        CHECK_FOR_INTERRUPTS();
 
        mtype = pq_getbyte();
-       if (mtype != 'p')
+       if (mtype != PqMsg_GSSResponse)
        {
            /* Only log error if client didn't disconnect. */
            if (mtype != EOF)
@@ -1232,7 +1232,7 @@ pg_SSPI_recvauth(Port *port)
    {
        pq_startmsgread();
        mtype = pq_getbyte();
-       if (mtype != 'p')
+       if (mtype != PqMsg_GSSResponse)
        {
            if (sspictx != NULL)
            {
index 9c8ec779f9b9d1b522885c242d352d1b558694fc..07d376d77ec2ed976ac7cb8770b483557a948dc6 100644 (file)
@@ -2357,7 +2357,7 @@ SendNegotiateProtocolVersion(List *unrecognized_protocol_options)
    StringInfoData buf;
    ListCell   *lc;
 
-   pq_beginmessage(&buf, 'v'); /* NegotiateProtocolVersion */
+   pq_beginmessage(&buf, PqMsg_NegotiateProtocolVersion);
    pq_sendint32(&buf, PG_PROTOCOL_LATEST);
    pq_sendint32(&buf, list_length(unrecognized_protocol_options));
    foreach(lc, unrecognized_protocol_options)
index d27ef2985d7a91b10fd3ff98598c649374753a3b..80374c55be51b5147b159b3bd6a870367e6e5cc1 100644 (file)
@@ -603,7 +603,7 @@ SendTimeLineHistory(TimeLineHistoryCmd *cmd)
    dest->rStartup(dest, CMD_SELECT, tupdesc);
 
    /* Send a DataRow message */
-   pq_beginmessage(&buf, 'D');
+   pq_beginmessage(&buf, PqMsg_DataRow);
    pq_sendint16(&buf, 2);      /* # of columns */
    len = strlen(histfname);
    pq_sendint32(&buf, len);    /* col1 len */
@@ -801,7 +801,7 @@ StartReplication(StartReplicationCmd *cmd)
        WalSndSetState(WALSNDSTATE_CATCHUP);
 
        /* Send a CopyBothResponse message, and start  */
-       pq_beginmessage(&buf, 'W');
+       pq_beginmessage(&buf, PqMsg_CopyBothResponse);
        pq_sendbyte(&buf, 0);
        pq_sendint16(&buf, 0);
        pq_endmessage(&buf);
@@ -1294,7 +1294,7 @@ StartLogicalReplication(StartReplicationCmd *cmd)
    WalSndSetState(WALSNDSTATE_CATCHUP);
 
    /* Send a CopyBothResponse message, and start  */
-   pq_beginmessage(&buf, 'W');
+   pq_beginmessage(&buf, PqMsg_CopyBothResponse);
    pq_sendbyte(&buf, 0);
    pq_sendint16(&buf, 0);
    pq_endmessage(&buf);
@@ -1923,11 +1923,11 @@ ProcessRepliesIfAny(void)
        /* Validate message type and set packet size limit */
        switch (firstchar)
        {
-           case 'd':
+           case PqMsg_CopyData:
                maxmsglen = PQ_LARGE_MESSAGE_LIMIT;
                break;
-           case 'c':
-           case 'X':
+           case PqMsg_CopyDone:
+           case PqMsg_Terminate:
                maxmsglen = PQ_SMALL_MESSAGE_LIMIT;
                break;
            default:
@@ -1955,7 +1955,7 @@ ProcessRepliesIfAny(void)
                /*
                 * 'd' means a standby reply wrapped in a CopyData packet.
                 */
-           case 'd':
+           case PqMsg_CopyData:
                ProcessStandbyMessage();
                received = true;
                break;
@@ -1964,7 +1964,7 @@ ProcessRepliesIfAny(void)
                 * CopyDone means the standby requested to finish .
                 * Reply with CopyDone, if we had not sent that already.
                 */
-           case 'c':
+           case PqMsg_CopyDone:
                if (!DoneSending)
                {
                    pq_putmessage_noblock('c', NULL, 0);
@@ -1978,7 +1978,7 @@ ProcessRepliesIfAny(void)
                /*
                 * 'X' means that the standby is closing down the socket.
                 */
-           case 'X':
+           case PqMsg_Terminate:
                proc_exit(0);
 
            default:
index c0406e2ee550203f01307af9614637dabbc0b65d..06d1872b9acc4e341f31b6d065166d444e886963 100644 (file)
@@ -176,7 +176,7 @@ EndCommand(const QueryCompletion *qc, CommandDest dest, bool force_undecorated_o
 
            len = BuildQueryCompletionString(completionTag, qc,
                                             force_undecorated_output);
-           pq_putmessage('C', completionTag, len + 1);
+           pq_putmessage(PqMsg_Close, completionTag, len + 1);
 
        case DestNone:
        case DestDebug:
@@ -200,7 +200,7 @@ EndCommand(const QueryCompletion *qc, CommandDest dest, bool force_undecorated_o
 void
 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:
 
            /* Tell the FE that we saw an empty query string */
-           pq_putemptymessage('I');
+           pq_putemptymessage(PqMsg_EmptyQueryResponse);
            break;
 
        case DestNone:
@@ -258,7 +258,7 @@ ReadyForQuery(CommandDest dest)
            {
                StringInfoData buf;
 
-               pq_beginmessage(&buf, 'Z');
+               pq_beginmessage(&buf, PqMsg_ReadyForQuery);
                pq_sendbyte(&buf, TransactionBlockStatusCode());
                pq_endmessage(&buf);
            }
index 2f70ebd5fae625da59cba05ae94f8762544d3441..71f161dbe2482434d199f6e08ca46f13bea71155 100644 (file)
@@ -69,7 +69,7 @@ SendFunctionResult(Datum retval, bool isnull, Oid rettype, int16 format)
 {
    StringInfoData buf;
 
-   pq_beginmessage(&buf, 'V');
+   pq_beginmessage(&buf, PqMsg_FunctionCallResponse);
 
    if (isnull)
    {
index 36cc99ec9cf5124af257e1fed07afa19692557dd..e4756f8be21dd050d6967e7fda9234e884d080eb 100644 (file)
@@ -402,37 +402,37 @@ SocketBackend(StringInfo inBuf)
     */
    switch (qtype)
    {
-       case 'Q':               /* simple query */
+       case PqMsg_Query:
            maxmsglen = PQ_LARGE_MESSAGE_LIMIT;
            doing_extended_query_message = false;
            break;
 
-       case 'F':               /* fastpath function call */
+       case PqMsg_FunctionCall:
            maxmsglen = PQ_LARGE_MESSAGE_LIMIT;
            doing_extended_query_message = false;
            break;
 
-       case 'X':               /* terminate */
+       case PqMsg_Terminate:
            maxmsglen = PQ_SMALL_MESSAGE_LIMIT;
            doing_extended_query_message = false;
            ignore_till_sync = false;
            break;
 
-       case 'B':               /* bind */
-       case 'P':               /* parse */
+       case PqMsg_Bind:
+       case PqMsg_Parse:
            maxmsglen = PQ_LARGE_MESSAGE_LIMIT;
            doing_extended_query_message = true;
            break;
 
-       case 'C':               /* close */
-       case 'D':               /* describe */
-       case 'E':               /* execute */
-       case 'H':               /* flush */
+       case PqMsg_Close:
+       case PqMsg_Describe:
+       case PqMsg_Execute:
+       case PqMsg_Flush:
            maxmsglen = PQ_SMALL_MESSAGE_LIMIT;
            doing_extended_query_message = true;
            break;
 
-       case 'S':               /* sync */
+       case PqMsg_Sync:
            maxmsglen = PQ_SMALL_MESSAGE_LIMIT;
            /* stop any active skip-till-Sync */
            ignore_till_sync = false;
@@ -440,13 +440,13 @@ SocketBackend(StringInfo inBuf)
            doing_extended_query_message = false;
            break;
 
-       case 'd':               /* copy data */
+       case PqMsg_CopyData:
            maxmsglen = PQ_LARGE_MESSAGE_LIMIT;
            doing_extended_query_message = false;
            break;
 
-       case 'c':               /* copy done */
-       case 'f':               /* copy fail */
+       case PqMsg_CopyDone:
+       case PqMsg_CopyFail:
            maxmsglen = PQ_SMALL_MESSAGE_LIMIT;
            doing_extended_query_message = false;
            break;
@@ -1589,7 +1589,7 @@ exec_parse_message(const char *query_string,  /* string to execute */
     * Send ParseComplete.
     */
    if (whereToSendOutput == DestRemote)
-       pq_putemptymessage('1');
+       pq_putemptymessage(PqMsg_ParseComplete);
 
    /*
     * Emit duration logging if appropriate.
@@ -2047,7 +2047,7 @@ exec_bind_message(StringInfo input_message)
     * Send BindComplete.
     */
    if (whereToSendOutput == DestRemote)
-       pq_putemptymessage('2');
+       pq_putemptymessage(PqMsg_BindComplete);
 
    /*
     * 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 */
        if (whereToSendOutput == DestRemote)
-           pq_putemptymessage('s');
+           pq_putemptymessage(PqMsg_PortalSuspended);
 
        /*
         * Set XACT_FLAGS_PIPELINING whenever we suspend an Execute message,
@@ -2683,7 +2683,7 @@ exec_describe_statement_message(const char *stmt_name)
                                  NULL);
    }
    else
-       pq_putemptymessage('n');    /* NoData */
+       pq_putemptymessage(PqMsg_NoData);
 }
 
 /*
@@ -2736,7 +2736,7 @@ exec_describe_portal_message(const char *portal_name)
                                  FetchPortalTargetList(portal),
                                  portal->formats);
    else
-       pq_putemptymessage('n');    /* NoData */
+       pq_putemptymessage(PqMsg_NoData);
 }
 
 
@@ -4239,7 +4239,7 @@ PostgresMain(const char *dbname, const char *username)
    {
        StringInfoData buf;
 
-       pq_beginmessage(&buf, 'K');
+       pq_beginmessage(&buf, PqMsg_BackendKeyData);
        pq_sendint32(&buf, (int32) MyProcPid);
        pq_sendint32(&buf, (int32) MyCancelKey);
        pq_endmessage(&buf);
@@ -4618,7 +4618,7 @@ PostgresMain(const char *dbname, const char *username)
 
        switch (firstchar)
        {
-           case 'Q':           /* simple query */
+           case PqMsg_Query:
                {
                    const char *query_string;
 
@@ -4642,7 +4642,7 @@ PostgresMain(const char *dbname, const char *username)
                }
                break;
 
-           case 'P':           /* parse */
+           case PqMsg_Parse:
                {
                    const char *stmt_name;
                    const char *query_string;
@@ -4672,7 +4672,7 @@ PostgresMain(const char *dbname, const char *username)
                }
                break;
 
-           case 'B':           /* bind */
+           case PqMsg_Bind:
                forbidden_in_wal_sender(firstchar);
 
                /* Set statement_timestamp() */
@@ -4687,7 +4687,7 @@ PostgresMain(const char *dbname, const char *username)
                /* exec_bind_message does valgrind_report_error_query */
                break;
 
-           case 'E':           /* execute */
+           case PqMsg_Execute:
                {
                    const char *portal_name;
                    int         max_rows;
@@ -4707,7 +4707,7 @@ PostgresMain(const char *dbname, const char *username)
                }
                break;
 
-           case 'F':           /* fastpath function call */
+           case PqMsg_FunctionCall:
                forbidden_in_wal_sender(firstchar);
 
                /* Set statement_timestamp() */
@@ -4742,7 +4742,7 @@ PostgresMain(const char *dbname, const char *username)
                send_ready_for_query = true;
                break;
 
-           case 'C':           /* close */
+           case PqMsg_Close:
                {
                    int         close_type;
                    const char *close_target;
@@ -4782,13 +4782,13 @@ PostgresMain(const char *dbname, const char *username)
                    }
 
                    if (whereToSendOutput == DestRemote)
-                       pq_putemptymessage('3');    /* CloseComplete */
+                       pq_putemptymessage(PqMsg_CloseComplete);
 
                    valgrind_report_error_query("CLOSE message");
                }
                break;
 
-           case 'D':           /* describe */
+           case PqMsg_Describe:
                {
                    int         describe_type;
                    const char *describe_target;
@@ -4822,13 +4822,13 @@ PostgresMain(const char *dbname, const char *username)
                }
                break;
 
-           case 'H':           /* flush */
+           case PqMsg_Flush:
                pq_getmsgend(&input_message);
                if (whereToSendOutput == DestRemote)
                    pq_flush();
                break;
 
-           case 'S':           /* sync */
+           case PqMsg_Sync:
                pq_getmsgend(&input_message);
                finish_xact_command();
                valgrind_report_error_query("SYNC message");
@@ -4847,7 +4847,7 @@ PostgresMain(const char *dbname, const char *username)
 
                /* FALLTHROUGH */
 
-           case 'X':
+           case PqMsg_Terminate:
 
                /*
                 * Reset whereToSendOutput to prevent ereport from attempting
@@ -4865,9 +4865,9 @@ PostgresMain(const char *dbname, const char *username)
                 */
                proc_exit(0);
 
-           case 'd':           /* copy data */
-           case 'c':           /* copy done */
-           case 'f':           /* copy fail */
+           case PqMsg_CopyData:
+           case PqMsg_CopyDone:
+           case PqMsg_CopyFail:
 
                /*
                 * Accept but ignore these messages, per protocol spec; we
@@ -4897,7 +4897,7 @@ forbidden_in_wal_sender(char firstchar)
 {
    if (am_walsender)
    {
-       if (firstchar == 'F')
+       if (firstchar == PqMsg_FunctionCall)
            ereport(ERROR,
                    (errcode(ERRCODE_PROTOCOL_VIOLATION),
                     errmsg("fastpath function calls not supported in a replication connection")));
index 5898100acb6beb05d2a222eaa9e7e9db39f0a730..8e1f3e852118cb4584710ea720e0b6f4e814caba 100644 (file)
@@ -3465,7 +3465,10 @@ send_message_to_frontend(ErrorData *edata)
        char        tbuf[12];
 
        /* '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);
        pq_sendbyte(&msgbuf, PG_DIAG_SEVERITY);
index 99bb2fdd1906546eda51293c84db4d5de6fe5f53..84e7ad4d9072aebd07a954575af771fad6b67c53 100644 (file)
@@ -2593,7 +2593,7 @@ ReportGUCOption(struct config_generic *record)
    {
        StringInfoData msgbuf;
 
-       pq_beginmessage(&msgbuf, 'S');
+       pq_beginmessage(&msgbuf, PqMsg_ParameterStatus);
        pq_sendstring(&msgbuf, record->name);
        pq_sendstring(&msgbuf, val);
        pq_endmessage(&msgbuf);
index 5d213187e24bdcd86de31d6f6ff72852d36440a1..2d5242561cd197f92d4326eeb19277fc32420350 100644 (file)
@@ -40,6 +40,7 @@ install: all installdirs
    $(INSTALL_DATA) $(srcdir)/port.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/protocol.h '$(DESTDIR)$(includedir_internal)/libpq'
 # These headers are needed for server-side development
    $(INSTALL_DATA) pg_config.h     '$(DESTDIR)$(includedir_server)'
    $(INSTALL_DATA) pg_config_ext.h '$(DESTDIR)$(includedir_server)'
@@ -65,7 +66,7 @@ installdirs:
 
 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_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...
    rm -rf $(addprefix '$(DESTDIR)$(includedir_server)'/, $(SUBDIRS) *.h)
 
index 3da00f79839ff32fa8810bfeedcb10ce7b6634ab..46a0946b8b272ffdf70722a27ccb8409866e2f38 100644 (file)
 #include <netdb.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
 {
    struct sockaddr_storage addr;
@@ -112,23 +118,6 @@ typedef uint32 PacketLen;
 #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;
 
 
diff --git a/src/include/libpq/protocol.h b/src/include/libpq/protocol.h
new file mode 100644 (file)
index 0000000..cc46f4b
--- /dev/null
@@ -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 */
index d7e1ecd4c96d71c500944afe181009230e3bc38e..d50897c9fda845bac537cb50bcc323d4360755a0 100644 (file)
@@ -94,6 +94,7 @@ install_headers(
 
 install_headers(
   'libpq/pqcomm.h',
+  'libpq/protocol.h',
   install_dir: dir_include_internal / 'libpq',
 )
 
index 887ca5e9e1be78584d8e1358bec4653693ac832e..912aa14821db7b52c6478639bc6419c1a1c2813b 100644 (file)
@@ -586,7 +586,7 @@ pg_SASL_init(PGconn *conn, int payloadlen)
    /*
     * Build a SASLInitialResponse message, and send it.
     */
-   if (pqPutMsgStart('p', conn))
+   if (pqPutMsgStart(PqMsg_SASLInitialResponse, conn))
        goto error;
    if (pqPuts(selected_mechanism, conn))
        goto error;
index 837c5321aa1fab70490f5da62bc6439ba8fe5ddc..bf83a9b569759dad8d6c1f54baedfa24c97ecd09 100644 (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
                 * 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",
                                            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
                 * 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");
                    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");
                    goto error_return;
                }
 
 #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 */
                    conn->inCursor = conn->inStart + 1; /* reread data */
@@ -3693,7 +3698,7 @@ keep_going:                       /* We will come back to here until there is
                }
 
                /* Handle errors. */
-               if (beresp == 'E')
+               if (beresp == PqMsg_ErrorResponse)
                {
                    if (pqGetErrorNotice3(conn, true))
                    {
@@ -3770,7 +3775,7 @@ keep_going:                       /* We will come back to here until there is
 
                    goto error_return;
                }
-               else if (beresp == 'v')
+               else if (beresp == PqMsg_NegotiateProtocolVersion)
                {
                    if (pqGetNegotiateProtocolVersion3(conn))
                    {
@@ -4540,7 +4545,7 @@ sendTerminateConn(PGconn *conn)
         * Try to send "close connection" message to backend. Ignore any
         * error.
         */
-       pqPutMsgStart('X', conn);
+       pqPutMsgStart(PqMsg_Terminate, conn);
        pqPutMsgEnd(conn);
        (void) pqFlush(conn);
    }
index a868284ff87febb79a2b83f38c86d7324cd6ed7b..974d462d4b870b043b4f4af599e75686a013cca7 100644 (file)
@@ -1458,7 +1458,7 @@ PQsendQueryInternal(PGconn *conn, const char *query, bool newQuery)
 
    /* Send the query message(s) */
    /* construct the outgoing Query message */
-   if (pqPutMsgStart('Q', conn) < 0 ||
+   if (pqPutMsgStart(PqMsg_Query, conn) < 0 ||
        pqPuts(query, conn) < 0 ||
        pqPutMsgEnd(conn) < 0)
    {
@@ -1571,7 +1571,7 @@ PQsendPrepare(PGconn *conn,
        return 0;               /* error msg already set */
 
    /* construct the Parse message */
-   if (pqPutMsgStart('P', conn) < 0 ||
+   if (pqPutMsgStart(PqMsg_Parse, conn) < 0 ||
        pqPuts(stmtName, conn) < 0 ||
        pqPuts(query, conn) < 0)
        goto sendFailed;
@@ -1599,7 +1599,7 @@ PQsendPrepare(PGconn *conn,
    /* Add a Sync, unless in pipeline mode. */
    if (conn->pipelineStatus == PQ_PIPELINE_OFF)
    {
-       if (pqPutMsgStart('S', conn) < 0 ||
+       if (pqPutMsgStart(PqMsg_Sync, conn) < 0 ||
            pqPutMsgEnd(conn) < 0)
            goto sendFailed;
    }
@@ -1784,7 +1784,7 @@ PQsendQueryGuts(PGconn *conn,
    if (command)
    {
        /* construct the Parse message */
-       if (pqPutMsgStart('P', conn) < 0 ||
+       if (pqPutMsgStart(PqMsg_Parse, conn) < 0 ||
            pqPuts(stmtName, conn) < 0 ||
            pqPuts(command, conn) < 0)
            goto sendFailed;
@@ -1808,7 +1808,7 @@ PQsendQueryGuts(PGconn *conn,
    }
 
    /* Construct the Bind message */
-   if (pqPutMsgStart('B', conn) < 0 ||
+   if (pqPutMsgStart(PqMsg_Bind, conn) < 0 ||
        pqPuts("", conn) < 0 ||
        pqPuts(stmtName, conn) < 0)
        goto sendFailed;
@@ -1874,14 +1874,14 @@ PQsendQueryGuts(PGconn *conn,
        goto sendFailed;
 
    /* construct the Describe Portal message */
-   if (pqPutMsgStart('D', conn) < 0 ||
+   if (pqPutMsgStart(PqMsg_Describe, conn) < 0 ||
        pqPutc('P', conn) < 0 ||
        pqPuts("", conn) < 0 ||
        pqPutMsgEnd(conn) < 0)
        goto sendFailed;
 
    /* construct the Execute message */
-   if (pqPutMsgStart('E', conn) < 0 ||
+   if (pqPutMsgStart(PqMsg_Execute, conn) < 0 ||
        pqPuts("", conn) < 0 ||
        pqPutInt(0, 4, conn) < 0 ||
        pqPutMsgEnd(conn) < 0)
@@ -1890,7 +1890,7 @@ PQsendQueryGuts(PGconn *conn,
    /* construct the Sync message if not in pipeline mode */
    if (conn->pipelineStatus == PQ_PIPELINE_OFF)
    {
-       if (pqPutMsgStart('S', conn) < 0 ||
+       if (pqPutMsgStart(PqMsg_Sync, conn) < 0 ||
            pqPutMsgEnd(conn) < 0)
            goto sendFailed;
    }
@@ -2422,7 +2422,7 @@ PQdescribePrepared(PGconn *conn, const char *stmt)
 {
    if (!PQexecStart(conn))
        return NULL;
-   if (!PQsendTypedCommand(conn, 'D', 'S', stmt))
+   if (!PQsendTypedCommand(conn, PqMsg_Describe, 'S', stmt))
        return NULL;
    return PQexecFinish(conn);
 }
@@ -2441,7 +2441,7 @@ PQdescribePortal(PGconn *conn, const char *portal)
 {
    if (!PQexecStart(conn))
        return NULL;
-   if (!PQsendTypedCommand(conn, 'D', 'P', portal))
+   if (!PQsendTypedCommand(conn, PqMsg_Describe, 'P', portal))
        return NULL;
    return PQexecFinish(conn);
 }
@@ -2456,7 +2456,7 @@ PQdescribePortal(PGconn *conn, const char *portal)
 int
 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
 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))
        return NULL;
-   if (!PQsendTypedCommand(conn, 'C', 'S', stmt))
+   if (!PQsendTypedCommand(conn, PqMsg_Close, 'S', stmt))
        return NULL;
    return PQexecFinish(conn);
 }
@@ -2506,7 +2506,7 @@ PQclosePortal(PGconn *conn, const char *portal)
 {
    if (!PQexecStart(conn))
        return NULL;
-   if (!PQsendTypedCommand(conn, 'C', 'P', portal))
+   if (!PQsendTypedCommand(conn, PqMsg_Close, 'P', portal))
        return NULL;
    return PQexecFinish(conn);
 }
@@ -2521,7 +2521,7 @@ PQclosePortal(PGconn *conn, const char *portal)
 int
 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
 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
  *
  * Available options for "command" are
- *  'C' for Close; or
- *  'D' for Describe.
+ *  PqMsg_Close for Close; or
+ *  PqMsg_Describe for Describe.
  *
  * Available options for "type" are
  *  '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 */
    if (conn->pipelineStatus == PQ_PIPELINE_OFF)
    {
-       if (pqPutMsgStart('S', conn) < 0 ||
+       if (pqPutMsgStart(PqMsg_Sync, conn) < 0 ||
            pqPutMsgEnd(conn) < 0)
            goto sendFailed;
    }
 
    /* remember if we are doing a Close or a Describe */
-   if (command == 'C')
+   if (command == PqMsg_Close)
    {
        entry->queryclass = PGQUERY_CLOSE;
    }
-   else if (command == 'D')
+   else if (command == PqMsg_Describe)
    {
        entry->queryclass = PGQUERY_DESCRIBE;
    }
@@ -2696,7 +2696,7 @@ PQputCopyData(PGconn *conn, const char *buffer, int nbytes)
                return pqIsnonblocking(conn) ? 0 : -1;
        }
        /* 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 ||
            pqPutMsgEnd(conn) < 0)
            return -1;
@@ -2731,7 +2731,7 @@ PQputCopyEnd(PGconn *conn, const char *errormsg)
    if (errormsg)
    {
        /* Send COPY FAIL */
-       if (pqPutMsgStart('f', conn) < 0 ||
+       if (pqPutMsgStart(PqMsg_CopyFail, conn) < 0 ||
            pqPuts(errormsg, conn) < 0 ||
            pqPutMsgEnd(conn) < 0)
            return -1;
@@ -2739,7 +2739,7 @@ PQputCopyEnd(PGconn *conn, const char *errormsg)
    else
    {
        /* Send COPY DONE */
-       if (pqPutMsgStart('c', conn) < 0 ||
+       if (pqPutMsgStart(PqMsg_CopyDone, conn) < 0 ||
            pqPutMsgEnd(conn) < 0)
            return -1;
    }
@@ -2751,7 +2751,7 @@ PQputCopyEnd(PGconn *conn, const char *errormsg)
    if (conn->cmd_queue_head &&
        conn->cmd_queue_head->queryclass != PGQUERY_SIMPLE)
    {
-       if (pqPutMsgStart('S', conn) < 0 ||
+       if (pqPutMsgStart(PqMsg_Sync, conn) < 0 ||
            pqPutMsgEnd(conn) < 0)
            return -1;
    }
@@ -3263,7 +3263,7 @@ PQpipelineSync(PGconn *conn)
    entry->query = NULL;
 
    /* construct the Sync message */
-   if (pqPutMsgStart('S', conn) < 0 ||
+   if (pqPutMsgStart(PqMsg_Sync, conn) < 0 ||
        pqPutMsgEnd(conn) < 0)
        goto sendFailed;
 
@@ -3311,7 +3311,7 @@ PQsendFlushRequest(PGconn *conn)
        return 0;
    }
 
-   if (pqPutMsgStart('H', conn) < 0 ||
+   if (pqPutMsgStart(PqMsg_Flush, conn) < 0 ||
        pqPutMsgEnd(conn) < 0)
    {
        return 0;
index 7bc6355d17f912ae15d4e23c2b466a336b9c2821..5613c56b141f26ae0277884e82622f362d7410a9 100644 (file)
  * than a couple of kilobytes).
  */
 #define VALID_LONG_MESSAGE_TYPE(id) \
-   ((id) == 'T' || (id) == 'D' || (id) == 'd' || (id) == 'V' || \
-    (id) == 'E' || (id) == 'N' || (id) == 'A')
+   ((id) == PqMsg_CopyData || \
+    (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);
@@ -140,12 +145,12 @@ pqParseInput3(PGconn *conn)
         * from config file due to SIGHUP), but otherwise we hold off until
         * BUSY state.
         */
-       if (id == 'A')
+       if (id == PqMsg_NotificationResponse)
        {
            if (getNotify(conn))
                return;
        }
-       else if (id == 'N')
+       else if (id == PqMsg_NoticeResponse)
        {
            if (pqGetErrorNotice3(conn, false))
                return;
@@ -165,12 +170,12 @@ pqParseInput3(PGconn *conn)
             * it is about to close the connection, so we don't want to just
             * discard it...)
             */
-           if (id == 'E')
+           if (id == PqMsg_ErrorResponse)
            {
                if (pqGetErrorNotice3(conn, false /* treat as notice */ ))
                    return;
            }
-           else if (id == 'S')
+           else if (id == PqMsg_ParameterStatus)
            {
                if (getParameterStatus(conn))
                    return;
@@ -192,7 +197,7 @@ pqParseInput3(PGconn *conn)
             */
            switch (id)
            {
-               case 'C':       /* command complete */
+               case PqMsg_CommandComplete:
                    if (pqGets(&conn->workBuffer, conn))
                        return;
                    if (!pgHavePendingResult(conn))
@@ -210,13 +215,12 @@ pqParseInput3(PGconn *conn)
                                CMDSTATUS_LEN);
                    conn->asyncStatus = PGASYNC_READY;
                    break;
-               case 'E':       /* error return */
+               case PqMsg_ErrorResponse:
                    if (pqGetErrorNotice3(conn, true))
                        return;
                    conn->asyncStatus = PGASYNC_READY;
                    break;
-               case 'Z':       /* sync response, backend is ready for new
-                                * query */
+               case PqMsg_ReadyForQuery:
                    if (getReadyForQuery(conn))
                        return;
                    if (conn->pipelineStatus != PQ_PIPELINE_OFF)
@@ -246,7 +250,7 @@ pqParseInput3(PGconn *conn)
                        conn->asyncStatus = PGASYNC_IDLE;
                    }
                    break;
-               case 'I':       /* empty query */
+               case PqMsg_EmptyQueryResponse:
                    if (!pgHavePendingResult(conn))
                    {
                        conn->result = PQmakeEmptyPGresult(conn,
@@ -259,7 +263,7 @@ pqParseInput3(PGconn *conn)
                    }
                    conn->asyncStatus = PGASYNC_READY;
                    break;
-               case '1':       /* Parse Complete */
+               case PqMsg_ParseComplete:
                    /* If we're doing PQprepare, we're done; else ignore */
                    if (conn->cmd_queue_head &&
                        conn->cmd_queue_head->queryclass == PGQUERY_PREPARE)
@@ -277,10 +281,10 @@ pqParseInput3(PGconn *conn)
                        conn->asyncStatus = PGASYNC_READY;
                    }
                    break;
-               case '2':       /* Bind Complete */
+               case PqMsg_BindComplete:
                    /* Nothing to do for this message type */
                    break;
-               case '3':       /* Close Complete */
+               case PqMsg_CloseComplete:
                    /* If we're doing PQsendClose, we're done; else ignore */
                    if (conn->cmd_queue_head &&
                        conn->cmd_queue_head->queryclass == PGQUERY_CLOSE)
@@ -298,11 +302,11 @@ pqParseInput3(PGconn *conn)
                        conn->asyncStatus = PGASYNC_READY;
                    }
                    break;
-               case 'S':       /* parameter status */
+               case PqMsg_ParameterStatus:
                    if (getParameterStatus(conn))
                        return;
                    break;
-               case 'K':       /* secret key data from the backend */
+               case PqMsg_BackendKeyData:
 
                    /*
                     * This is expected only during backend startup, but it's
@@ -314,7 +318,7 @@ pqParseInput3(PGconn *conn)
                    if (pqGetInt(&(conn->be_key), 4, conn))
                        return;
                    break;
-               case 'T':       /* Row Description */
+               case PqMsg_RowDescription:
                    if (conn->error_result ||
                        (conn->result != NULL &&
                         conn->result->resultStatus == PGRES_FATAL_ERROR))
@@ -346,7 +350,7 @@ pqParseInput3(PGconn *conn)
                        return;
                    }
                    break;
-               case 'n':       /* No Data */
+               case PqMsg_NoData:
 
                    /*
                     * NoData indicates that we will not be seeing a
@@ -374,11 +378,11 @@ pqParseInput3(PGconn *conn)
                        conn->asyncStatus = PGASYNC_READY;
                    }
                    break;
-               case 't':       /* Parameter Description */
+               case PqMsg_ParameterDescription:
                    if (getParamDescriptions(conn, msgLength))
                        return;
                    break;
-               case 'D':       /* Data Row */
+               case PqMsg_DataRow:
                    if (conn->result != NULL &&
                        conn->result->resultStatus == PGRES_TUPLES_OK)
                    {
@@ -405,24 +409,24 @@ pqParseInput3(PGconn *conn)
                        conn->inCursor += msgLength;
                    }
                    break;
-               case 'G':       /* Start Copy In */
+               case PqMsg_CopyInResponse:
                    if (getCopyStart(conn, PGRES_COPY_IN))
                        return;
                    conn->asyncStatus = PGASYNC_COPY_IN;
                    break;
-               case 'H':       /* Start Copy Out */
+               case PqMsg_CopyOutResponse:
                    if (getCopyStart(conn, PGRES_COPY_OUT))
                        return;
                    conn->asyncStatus = PGASYNC_COPY_OUT;
                    conn->copy_already_done = 0;
                    break;
-               case 'W':       /* Start Copy Both */
+               case PqMsg_CopyBothResponse:
                    if (getCopyStart(conn, PGRES_COPY_BOTH))
                        return;
                    conn->asyncStatus = PGASYNC_COPY_BOTH;
                    conn->copy_already_done = 0;
                    break;
-               case 'd':       /* Copy Data */
+               case PqMsg_CopyData:
 
                    /*
                     * If we see Copy Data, just silently drop it.  This would
@@ -431,7 +435,7 @@ pqParseInput3(PGconn *conn)
                     */
                    conn->inCursor += msgLength;
                    break;
-               case 'c':       /* Copy Done */
+               case PqMsg_CopyDone:
 
                    /*
                     * If we see Copy Done, just silently drop it.  This is
@@ -1692,21 +1696,21 @@ getCopyDataMessage(PGconn *conn)
         */
        switch (id)
        {
-           case 'A':           /* NOTIFY */
+           case PqMsg_NotificationResponse:
                if (getNotify(conn))
                    return 0;
                break;
-           case 'N':           /* NOTICE */
+           case PqMsg_NoticeResponse:
                if (pqGetErrorNotice3(conn, false))
                    return 0;
                break;
-           case 'S':           /* ParameterStatus */
+           case PqMsg_ParameterStatus:
                if (getParameterStatus(conn))
                    return 0;
                break;
-           case 'd':           /* Copy Data, pass it back to caller */
+           case PqMsg_CopyData:
                return msgLength;
-           case 'c':
+           case PqMsg_CopyDone:
 
                /*
                 * 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 ||
        conn->asyncStatus == PGASYNC_COPY_BOTH)
    {
-       if (pqPutMsgStart('c', conn) < 0 ||
+       if (pqPutMsgStart(PqMsg_CopyDone, conn) < 0 ||
            pqPutMsgEnd(conn) < 0)
            return 1;
 
@@ -1940,7 +1944,7 @@ pqEndcopy3(PGconn *conn)
        if (conn->cmd_queue_head &&
            conn->cmd_queue_head->queryclass != PGQUERY_SIMPLE)
        {
-           if (pqPutMsgStart('S', conn) < 0 ||
+           if (pqPutMsgStart(PqMsg_Sync, conn) < 0 ||
                pqPutMsgEnd(conn) < 0)
                return 1;
        }
@@ -2023,7 +2027,7 @@ pqFunctionCall3(PGconn *conn, Oid fnid,
 
    /* 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(1, 2, conn) < 0 || /* # of format codes */
        pqPutInt(1, 2, conn) < 0 || /* format code: BINARY */
index 402784f40e3e1fa72aba7a64ab69acfc8892f301..b18e3deab6a2207b591614a16abcc4c48ebbae74 100644 (file)
@@ -562,110 +562,120 @@ pqTraceOutputMessage(PGconn *conn, const char *message, bool toServer)
 
    switch (id)
    {
-       case '1':
+       case PqMsg_ParseComplete:
            fprintf(conn->Pfdebug, "ParseComplete");
            /* No message content */
            break;
-       case '2':
+       case PqMsg_BindComplete:
            fprintf(conn->Pfdebug, "BindComplete");
            /* No message content */
            break;
-       case '3':
+       case PqMsg_CloseComplete:
            fprintf(conn->Pfdebug, "CloseComplete");
            /* No message content */
            break;
-       case 'A':               /* Notification Response */
+       case PqMsg_NotificationResponse:
            pqTraceOutputA(conn->Pfdebug, message, &logCursor, regress);
            break;
-       case 'B':               /* Bind */
+       case PqMsg_Bind:
            pqTraceOutputB(conn->Pfdebug, message, &logCursor);
            break;
-       case 'c':
+       case PqMsg_CopyDone:
            fprintf(conn->Pfdebug, "CopyDone");
            /* No message content */
            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);
            break;
-       case 'd':               /* Copy Data */
+       case PqMsg_CopyData:
            /* Drop COPY data to reduce the overhead of logging. */
            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);
            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,
                           regress);
            break;
-       case 'f':               /* Copy Fail */
+       case PqMsg_CopyFail:
            pqTraceOutputf(conn->Pfdebug, message, &logCursor);
            break;
-       case 'F':               /* Function Call */
+       case PqMsg_FunctionCall:
            pqTraceOutputF(conn->Pfdebug, message, &logCursor, regress);
            break;
-       case 'G':               /* Start Copy In */
+       case PqMsg_CopyInResponse:
            pqTraceOutputG(conn->Pfdebug, message, &logCursor);
            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)
                pqTraceOutputH(conn->Pfdebug, message, &logCursor);
            else
                fprintf(conn->Pfdebug, "Flush");    /* no message content */
            break;
-       case 'I':
+       case PqMsg_EmptyQueryResponse:
            fprintf(conn->Pfdebug, "EmptyQueryResponse");
            /* No message content */
            break;
-       case 'K':               /* secret key data from the backend */
+       case PqMsg_BackendKeyData:
            pqTraceOutputK(conn->Pfdebug, message, &logCursor, regress);
            break;
-       case 'n':
+       case PqMsg_NoData:
            fprintf(conn->Pfdebug, "NoData");
            /* No message content */
            break;
-       case 'N':
+       case PqMsg_NoticeResponse:
            pqTraceOutputNR(conn->Pfdebug, "NoticeResponse", message,
                            &logCursor, regress);
            break;
-       case 'P':               /* Parse */
+       case PqMsg_Parse:
            pqTraceOutputP(conn->Pfdebug, message, &logCursor, regress);
            break;
-       case 'Q':               /* Query */
+       case PqMsg_Query:
            pqTraceOutputQ(conn->Pfdebug, message, &logCursor);
            break;
-       case 'R':               /* Authentication */
+       case PqMsg_AuthenticationRequest:
            pqTraceOutputR(conn->Pfdebug, message, &logCursor);
            break;
-       case 's':
+       case PqMsg_PortalSuspended:
            fprintf(conn->Pfdebug, "PortalSuspended");
            /* No message content */
            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)
                pqTraceOutputS(conn->Pfdebug, message, &logCursor);
            else
                fprintf(conn->Pfdebug, "Sync"); /* no message content */
            break;
-       case 't':               /* Parameter Description */
+       case PqMsg_ParameterDescription:
            pqTraceOutputt(conn->Pfdebug, message, &logCursor, regress);
            break;
-       case 'T':               /* Row Description */
+       case PqMsg_RowDescription:
            pqTraceOutputT(conn->Pfdebug, message, &logCursor, regress);
            break;
-       case 'v':               /* Negotiate Protocol Version */
+       case PqMsg_NegotiateProtocolVersion:
            pqTraceOutputv(conn->Pfdebug, message, &logCursor);
            break;
-       case 'V':               /* Function Call response */
+       case PqMsg_FunctionCallResponse:
            pqTraceOutputV(conn->Pfdebug, message, &logCursor);
            break;
-       case 'W':               /* Start Copy Both */
+       case PqMsg_CopyBothResponse:
            pqTraceOutputW(conn->Pfdebug, message, &logCursor, length);
            break;
-       case 'X':
+       case PqMsg_Terminate:
            fprintf(conn->Pfdebug, "Terminate");
            /* No message content */
            break;
-       case 'Z':               /* Ready For Query */
+       case PqMsg_ReadyForQuery:
            pqTraceOutputZ(conn->Pfdebug, message, &logCursor);
            break;
        default:
index 05548d7c0aab8052c7e8b0197a9f3410d3a99abb..b6dd2c3bbacc5b4d496170fe4e27ae36642186de 100644 (file)
@@ -614,6 +614,8 @@ sub CopyIncludeFiles
        'src/include/', 'c.h', 'port.h', 'postgres_fe.h');
    lcopy('src/include/libpq/pqcomm.h', $target . '/include/internal/libpq/')
      || croak 'Could not copy pqcomm.h';
+   lcopy('src/include/libpq/protocol.h', $target . '/include/internal/libpq/')
+     || croak 'Could not copy protocol.h';
 
    CopyFiles(
        'Server headers',