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 streaming */
-               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 streaming */
-       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 streaming.
                                 * Reply with CopyDone, if we had not sent that already.
                                 */
-                       case 'c':
+                       case PqMsg_CopyDone:
                                if (!streamingDoneSending)
                                {
                                        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',