From 45733bb77f3ad2b7665e52c9e24b3aa11699f56e Mon Sep 17 00:00:00 2001
From: Dave Cramer <davecramer@gmail.com>
Date: Thu, 20 Apr 2023 15:40:03 -0400
Subject: [PATCH] Created protocol.h Protocol.h has defines for every protocol
 message both backend and frontend Instead of using hardcoded values for each
 protocol message use defines to make code easier to read

remove redundant comments

define CLOSE_PORTAL and CLOSE_PREPARED subcommands
fix some erroneous uses of DATA_ROW_RESPONSE which should have been DESCRIBE_REQUEST
use the names in the requests .

prepend PQMSG_REQ and PQMSG_RESP to commands and responses respectively
---
 src/backend/access/common/printsimple.c       |  5 +-
 src/backend/access/transam/parallel.c         | 17 ++--
 src/backend/backup/basebackup_copy.c          | 17 ++--
 src/backend/commands/async.c                  |  3 +-
 src/backend/commands/copyfromparse.c          | 23 +++---
 src/backend/commands/copyto.c                 |  5 +-
 src/backend/libpq/auth-sasl.c                 |  3 +-
 src/backend/libpq/auth.c                      |  9 ++-
 src/backend/postmaster/postmaster.c           |  3 +-
 src/backend/replication/walsender.c           | 19 ++---
 src/backend/tcop/dest.c                       |  5 +-
 src/backend/tcop/fastpath.c                   |  3 +-
 src/backend/tcop/postgres.c                   | 77 ++++++++++---------
 src/backend/utils/activity/backend_progress.c |  3 +-
 src/backend/utils/error/elog.c                |  3 +-
 src/backend/utils/misc/guc.c                  |  3 +-
 src/include/protocol.h                        | 61 +++++++++++++++
 src/interfaces/libpq/fe-auth.c                |  3 +-
 src/interfaces/libpq/fe-connect.c             | 15 ++--
 src/interfaces/libpq/fe-exec.c                | 53 ++++++-------
 src/interfaces/libpq/fe-protocol3.c           | 66 ++++++++--------
 src/interfaces/libpq/fe-trace.c               | 61 +++++++--------
 22 files changed, 270 insertions(+), 187 deletions(-)
 create mode 100644 src/include/protocol.h

diff --git a/src/backend/access/common/printsimple.c b/src/backend/access/common/printsimple.c
index ef818228ac..e7dc125f82 100644
--- a/src/backend/access/common/printsimple.c
+++ b/src/backend/access/common/printsimple.c
@@ -21,6 +21,7 @@
 #include "access/printsimple.h"
 #include "catalog/pg_type.h"
 #include "libpq/pqformat.h"
+#include "protocol.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_RESP_ROW_DESCRIPTION);
 	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_RESP_DATA_ROW);
 	pq_sendint16(&buf, tupdesc->natts);
 
 	for (i = 0; i < tupdesc->natts; ++i)
diff --git a/src/backend/access/transam/parallel.c b/src/backend/access/transam/parallel.c
index 1738aecf1f..6deb1a697f 100644
--- a/src/backend/access/transam/parallel.c
+++ b/src/backend/access/transam/parallel.c
@@ -33,6 +33,7 @@
 #include "miscadmin.h"
 #include "optimizer/optimizer.h"
 #include "pgstat.h"
+#include "protocol.h"
 #include "storage/ipc.h"
 #include "storage/predicate.h"
 #include "storage/sinval.h"
@@ -1127,7 +1128,7 @@ HandleParallelMessage(ParallelContext *pcxt, int i, StringInfo msg)
 
 	switch (msgtype)
 	{
-		case 'K':				/* BackendKeyData */
+		case PQMSG_REQ_BACKEND_KEY_DATA:
 			{
 				int32		pid = pq_getmsgint(msg, 4);
 
@@ -1137,8 +1138,8 @@ HandleParallelMessage(ParallelContext *pcxt, int i, StringInfo msg)
 				break;
 			}
 
-		case 'E':				/* ErrorResponse */
-		case 'N':				/* NoticeResponse */
+		case PQMSG_RESP_ERROR:
+		case PQMSG_RESP_NOTICE:
 			{
 				ErrorData	edata;
 				ErrorContextCallback *save_error_context_stack;
@@ -1183,7 +1184,7 @@ HandleParallelMessage(ParallelContext *pcxt, int i, StringInfo msg)
 				break;
 			}
 
-		case 'A':				/* NotifyResponse */
+		case PQMSG_RESP_NOTIFY:
 			{
 				/* Propagate NotifyResponse. */
 				int32		pid;
@@ -1200,7 +1201,7 @@ HandleParallelMessage(ParallelContext *pcxt, int i, StringInfo msg)
 				break;
 			}
 
-		case 'P':				/* Parallel progress reporting */
+		case PQMSG_RESP_PARALLEL_PROGRESS:
 			{
 				/*
 				 * Only incremental progress reporting is currently supported.
@@ -1217,7 +1218,7 @@ HandleParallelMessage(ParallelContext *pcxt, int i, StringInfo msg)
 				break;
 			}
 
-		case 'X':				/* Terminate, indicating clean exit */
+		case PQMSG_REQ_TERMINATE:	/* Terminate, indicating clean exit */
 			{
 				shm_mq_detach(pcxt->worker[i].error_mqh);
 				pcxt->worker[i].error_mqh = NULL;
@@ -1372,7 +1373,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_REQ_BACKEND_KEY_DATA);
 	pq_sendint32(&msgbuf, (int32) MyProcPid);
 	pq_sendint32(&msgbuf, (int32) MyCancelKey);
 	pq_endmessage(&msgbuf);
@@ -1550,7 +1551,7 @@ ParallelWorkerMain(Datum main_arg)
 	DetachSession();
 
 	/* Report success. */
-	pq_putmessage('X', NULL, 0);
+	pq_putmessage(PQMSG_REQ_TERMINATE, NULL, 0);
 }
 
 /*
diff --git a/src/backend/backup/basebackup_copy.c b/src/backend/backup/basebackup_copy.c
index 1db80cde1b..44547bfa4d 100644
--- a/src/backend/backup/basebackup_copy.c
+++ b/src/backend/backup/basebackup_copy.c
@@ -32,6 +32,7 @@
 #include "executor/executor.h"
 #include "libpq/libpq.h"
 #include "libpq/pqformat.h"
+#include "protocol.h"
 #include "tcop/dest.h"
 #include "utils/builtins.h"
 #include "utils/timestamp.h"
@@ -169,7 +170,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_REQ_COPY_DATA);
 	pq_sendbyte(&buf, 'n');		/* New archive */
 	pq_sendstring(&buf, archive_name);
 	pq_sendstring(&buf, ti->path == NULL ? "" : ti->path);
@@ -220,8 +221,8 @@ bbsink_copystream_archive_contents(bbsink *sink, size_t len)
 		{
 			mysink->last_progress_report_time = now;
 
-			pq_beginmessage(&buf, 'd'); /* CopyData */
-			pq_sendbyte(&buf, 'p'); /* Progress report */
+			pq_beginmessage(&buf, PQMSG_REQ_COPY_DATA);
+			pq_sendbyte(&buf, PQMSG_REQ_COPY_PROGRESS);
 			pq_sendint64(&buf, state->bytes_done);
 			pq_endmessage(&buf);
 			pq_flush_if_writable();
@@ -246,8 +247,8 @@ 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_sendbyte(&buf, 'p');		/* Progress report */
+	pq_beginmessage(&buf, PQMSG_REQ_COPY_DATA);
+	pq_sendbyte(&buf, PQMSG_REQ_COPY_PROGRESS);
 	pq_sendint64(&buf, state->bytes_done);
 	pq_endmessage(&buf);
 	pq_flush_if_writable();
@@ -261,7 +262,7 @@ bbsink_copystream_begin_manifest(bbsink *sink)
 {
 	StringInfoData buf;
 
-	pq_beginmessage(&buf, 'd'); /* CopyData */
+	pq_beginmessage(&buf, PQMSG_REQ_COPY_DATA);
 	pq_sendbyte(&buf, 'm');		/* Manifest */
 	pq_endmessage(&buf);
 }
@@ -318,7 +319,7 @@ SendCopyOutResponse(void)
 {
 	StringInfoData buf;
 
-	pq_beginmessage(&buf, 'H');
+	pq_beginmessage(&buf, PQMSG_RESP_COPY_OUT);
 	pq_sendbyte(&buf, 0);		/* overall format */
 	pq_sendint16(&buf, 0);		/* natts */
 	pq_endmessage(&buf);
@@ -330,7 +331,7 @@ SendCopyOutResponse(void)
 static void
 SendCopyDone(void)
 {
-	pq_putemptymessage('c');
+	pq_putemptymessage(PQMSG_REQ_COPY_DONE);
 }
 
 /*
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index ef909cf4e0..e8de47bd41 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -141,6 +141,7 @@
 #include "libpq/libpq.h"
 #include "libpq/pqformat.h"
 #include "miscadmin.h"
+#include "protocol.h"
 #include "storage/ipc.h"
 #include "storage/lmgr.h"
 #include "storage/proc.h"
@@ -2281,7 +2282,7 @@ NotifyMyFrontEnd(const char *channel, const char *payload, int32 srcPid)
 	{
 		StringInfoData buf;
 
-		pq_beginmessage(&buf, 'A');
+		pq_beginmessage(&buf, PQMSG_RESP_NOTIFY);
 		pq_sendint32(&buf, srcPid);
 		pq_sendstring(&buf, channel);
 		pq_sendstring(&buf, payload);
diff --git a/src/backend/commands/copyfromparse.c b/src/backend/commands/copyfromparse.c
index 232768a6e1..7bae4a55c2 100644
--- a/src/backend/commands/copyfromparse.c
+++ b/src/backend/commands/copyfromparse.c
@@ -72,6 +72,7 @@
 #include "miscadmin.h"
 #include "pgstat.h"
 #include "port/pg_bswap.h"
+#include "protocol.h"
 #include "utils/builtins.h"
 #include "utils/memutils.h"
 #include "utils/rel.h"
@@ -174,7 +175,7 @@ ReceiveCopyBegin(CopyFromState cstate)
 	int16		format = (cstate->opts.binary ? 1 : 0);
 	int			i;
 
-	pq_beginmessage(&buf, 'G');
+	pq_beginmessage(&buf, PQMSG_RESP_COPY_IN);
 	pq_sendbyte(&buf, format);	/* overall format */
 	pq_sendint16(&buf, natts);
 	for (i = 0; i < natts; i++)
@@ -279,13 +280,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_REQ_COPY_DATA:
 							maxmsglen = PQ_LARGE_MESSAGE_LIMIT;
 							break;
-						case 'c':	/* CopyDone */
-						case 'f':	/* CopyFail */
-						case 'H':	/* Flush */
-						case 'S':	/* Sync */
+						case PQMSG_REQ_COPY_DONE:
+						case PQMSG_REQ_COPY_FAIL:
+						case PQMSG_REQ_FLUSH_DATA:
+						case PQMSG_REQ_SYNC_DATA:
 							maxmsglen = PQ_SMALL_MESSAGE_LIMIT;
 							break;
 						default:
@@ -305,20 +306,20 @@ CopyGetData(CopyFromState cstate, void *databuf, int minread, int maxread)
 					/* ... and process it */
 					switch (mtype)
 					{
-						case 'd':	/* CopyData */
+						case PQMSG_REQ_COPY_DATA:
 							break;
-						case 'c':	/* CopyDone */
+						case PQMSG_REQ_COPY_DONE:
 							/* COPY IN correctly terminated by frontend */
 							cstate->raw_reached_eof = true;
 							return bytesread;
-						case 'f':	/* CopyFail */
+						case PQMSG_REQ_COPY_FAIL:
 							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_REQ_FLUSH_DATA:
+						case PQMSG_REQ_SYNC_DATA:
 
 							/*
 							 * Ignore Flush/Sync for the convenience of client
diff --git a/src/backend/commands/copyto.c b/src/backend/commands/copyto.c
index 9e4b2437a5..f11b295787 100644
--- a/src/backend/commands/copyto.c
+++ b/src/backend/commands/copyto.c
@@ -34,6 +34,7 @@
 #include "miscadmin.h"
 #include "optimizer/optimizer.h"
 #include "pgstat.h"
+#include "protocol.h"
 #include "rewrite/rewriteHandler.h"
 #include "storage/fd.h"
 #include "tcop/tcopprot.h"
@@ -144,7 +145,7 @@ SendCopyBegin(CopyToState cstate)
 	int16		format = (cstate->opts.binary ? 1 : 0);
 	int			i;
 
-	pq_beginmessage(&buf, 'H');
+	pq_beginmessage(&buf, PQMSG_RESP_COPY_OUT);
 	pq_sendbyte(&buf, format);	/* overall format */
 	pq_sendint16(&buf, natts);
 	for (i = 0; i < natts; i++)
@@ -159,7 +160,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_REQ_COPY_DONE);
 }
 
 /*----------
diff --git a/src/backend/libpq/auth-sasl.c b/src/backend/libpq/auth-sasl.c
index 684680897b..6c2948a1dd 100644
--- a/src/backend/libpq/auth-sasl.c
+++ b/src/backend/libpq/auth-sasl.c
@@ -19,6 +19,7 @@
 #include "libpq/libpq.h"
 #include "libpq/pqformat.h"
 #include "libpq/sasl.h"
+#include "protocol.h"
 
 /*
  * Maximum accepted size of SASL messages.
@@ -87,7 +88,7 @@ CheckSASLAuth(const pg_be_sasl_mech *mech, Port *port, char *shadow_pass,
 	{
 		pq_startmsgread();
 		mtype = pq_getbyte();
-		if (mtype != 'p')
+		if (mtype != PQMSG_RESP_GSS)
 		{
 			/* Only log error if client didn't disconnect. */
 			if (mtype != EOF)
diff --git a/src/backend/libpq/auth.c b/src/backend/libpq/auth.c
index 315a24bb3f..61dfbb9a99 100644
--- a/src/backend/libpq/auth.c
+++ b/src/backend/libpq/auth.c
@@ -34,6 +34,7 @@
 #include "libpq/scram.h"
 #include "miscadmin.h"
 #include "port/pg_bswap.h"
+#include "protocol.h"
 #include "postmaster/postmaster.h"
 #include "replication/walsender.h"
 #include "storage/ipc.h"
@@ -665,7 +666,7 @@ sendAuthRequest(Port *port, AuthRequest areq, const char *extradata, int extrale
 
 	CHECK_FOR_INTERRUPTS();
 
-	pq_beginmessage(&buf, 'R');
+	pq_beginmessage(&buf, PQMSG_REQ_AUTHENTICATION);
 	pq_sendint32(&buf, (int32) areq);
 	if (extralen > 0)
 		pq_sendbytes(&buf, extradata, extralen);
@@ -698,7 +699,7 @@ recv_password_packet(Port *port)
 
 	/* Expect 'p' message type */
 	mtype = pq_getbyte();
-	if (mtype != 'p')
+	if (mtype != PQMSG_RESP_PASSWORD)
 	{
 		/*
 		 * If the client just disconnects without offering a password, don't
@@ -961,7 +962,7 @@ pg_GSS_recvauth(Port *port)
 		CHECK_FOR_INTERRUPTS();
 
 		mtype = pq_getbyte();
-		if (mtype != 'p')
+		if (mtype != PQMSG_RESP_GSS)
 		{
 			/* Only log error if client didn't disconnect. */
 			if (mtype != EOF)
@@ -1232,7 +1233,7 @@ pg_SSPI_recvauth(Port *port)
 	{
 		pq_startmsgread();
 		mtype = pq_getbyte();
-		if (mtype != 'p')
+		if (mtype != PQMSG_RESP_GSS)
 		{
 			if (sspictx != NULL)
 			{
diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c
index 9c8ec779f9..52c15bebb7 100644
--- a/src/backend/postmaster/postmaster.c
+++ b/src/backend/postmaster/postmaster.c
@@ -114,6 +114,7 @@
 #include "postmaster/pgarch.h"
 #include "postmaster/postmaster.h"
 #include "postmaster/syslogger.h"
+#include "protocol.h"
 #include "replication/logicallauncher.h"
 #include "replication/walsender.h"
 #include "storage/fd.h"
@@ -2357,7 +2358,7 @@ SendNegotiateProtocolVersion(List *unrecognized_protocol_options)
 	StringInfoData buf;
 	ListCell   *lc;
 
-	pq_beginmessage(&buf, 'v'); /* NegotiateProtocolVersion */
+	pq_beginmessage(&buf, PQMSG_RESP_NEGOTIATE_PROTOCOL);
 	pq_sendint32(&buf, PG_PROTOCOL_LATEST);
 	pq_sendint32(&buf, list_length(unrecognized_protocol_options));
 	foreach(lc, unrecognized_protocol_options)
diff --git a/src/backend/replication/walsender.c b/src/backend/replication/walsender.c
index d27ef2985d..4bc2a1018c 100644
--- a/src/backend/replication/walsender.c
+++ b/src/backend/replication/walsender.c
@@ -69,6 +69,7 @@
 #include "nodes/replnodes.h"
 #include "pgstat.h"
 #include "postmaster/interrupt.h"
+#include "protocol.h"
 #include "replication/decode.h"
 #include "replication/logical.h"
 #include "replication/slot.h"
@@ -603,7 +604,7 @@ SendTimeLineHistory(TimeLineHistoryCmd *cmd)
 	dest->rStartup(dest, CMD_SELECT, tupdesc);
 
 	/* Send a DataRow message */
-	pq_beginmessage(&buf, 'D');
+	pq_beginmessage(&buf, PQMSG_RESP_DATA_ROW);
 	pq_sendint16(&buf, 2);		/* # of columns */
 	len = strlen(histfname);
 	pq_sendint32(&buf, len);	/* col1 len */
@@ -801,7 +802,7 @@ StartReplication(StartReplicationCmd *cmd)
 		WalSndSetState(WALSNDSTATE_CATCHUP);
 
 		/* Send a CopyBothResponse message, and start streaming */
-		pq_beginmessage(&buf, 'W');
+		pq_beginmessage(&buf, PQMSG_RESP_COPY_BOTH);
 		pq_sendbyte(&buf, 0);
 		pq_sendint16(&buf, 0);
 		pq_endmessage(&buf);
@@ -1294,7 +1295,7 @@ StartLogicalReplication(StartReplicationCmd *cmd)
 	WalSndSetState(WALSNDSTATE_CATCHUP);
 
 	/* Send a CopyBothResponse message, and start streaming */
-	pq_beginmessage(&buf, 'W');
+	pq_beginmessage(&buf, PQMSG_RESP_COPY_BOTH);
 	pq_sendbyte(&buf, 0);
 	pq_sendint16(&buf, 0);
 	pq_endmessage(&buf);
@@ -1923,11 +1924,11 @@ ProcessRepliesIfAny(void)
 		/* Validate message type and set packet size limit */
 		switch (firstchar)
 		{
-			case 'd':
+			case PQMSG_REQ_COPY_DATA:
 				maxmsglen = PQ_LARGE_MESSAGE_LIMIT;
 				break;
-			case 'c':
-			case 'X':
+			case PQMSG_REQ_COPY_DONE:
+			case PQMSG_REQ_TERMINATE:
 				maxmsglen = PQ_SMALL_MESSAGE_LIMIT;
 				break;
 			default:
@@ -1955,7 +1956,7 @@ ProcessRepliesIfAny(void)
 				/*
 				 * 'd' means a standby reply wrapped in a CopyData packet.
 				 */
-			case 'd':
+			case PQMSG_REQ_COPY_DATA:
 				ProcessStandbyMessage();
 				received = true;
 				break;
@@ -1964,7 +1965,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_REQ_COPY_DONE:
 				if (!streamingDoneSending)
 				{
 					pq_putmessage_noblock('c', NULL, 0);
@@ -1978,7 +1979,7 @@ ProcessRepliesIfAny(void)
 				/*
 				 * 'X' means that the standby is closing down the socket.
 				 */
-			case 'X':
+			case PQMSG_REQ_TERMINATE:
 				proc_exit(0);
 
 			default:
diff --git a/src/backend/tcop/dest.c b/src/backend/tcop/dest.c
index c0406e2ee5..a9bb80ac91 100644
--- a/src/backend/tcop/dest.c
+++ b/src/backend/tcop/dest.c
@@ -39,6 +39,7 @@
 #include "executor/tstoreReceiver.h"
 #include "libpq/libpq.h"
 #include "libpq/pqformat.h"
+#include "protocol.h"
 #include "utils/portal.h"
 
 
@@ -220,7 +221,7 @@ NullCommand(CommandDest dest)
 		case DestRemoteSimple:
 
 			/* Tell the FE that we saw an empty query string */
-			pq_putemptymessage('I');
+			pq_putemptymessage(PQMSG_RESP_EMPTY_QUERY);
 			break;
 
 		case DestNone:
@@ -258,7 +259,7 @@ ReadyForQuery(CommandDest dest)
 			{
 				StringInfoData buf;
 
-				pq_beginmessage(&buf, 'Z');
+				pq_beginmessage(&buf, PQMSG_RESP_READY_FOR_QUERY);
 				pq_sendbyte(&buf, TransactionBlockStatusCode());
 				pq_endmessage(&buf);
 			}
diff --git a/src/backend/tcop/fastpath.c b/src/backend/tcop/fastpath.c
index 2f70ebd5fa..384e53a651 100644
--- a/src/backend/tcop/fastpath.c
+++ b/src/backend/tcop/fastpath.c
@@ -27,6 +27,7 @@
 #include "mb/pg_wchar.h"
 #include "miscadmin.h"
 #include "port/pg_bswap.h"
+#include "protocol.h"
 #include "tcop/fastpath.h"
 #include "tcop/tcopprot.h"
 #include "utils/acl.h"
@@ -69,7 +70,7 @@ SendFunctionResult(Datum retval, bool isnull, Oid rettype, int16 format)
 {
 	StringInfoData buf;
 
-	pq_beginmessage(&buf, 'V');
+	pq_beginmessage(&buf, PQMSG_RESP_FUNCTION_CALL);
 
 	if (isnull)
 	{
diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c
index 36cc99ec9c..dd8cce7a9a 100644
--- a/src/backend/tcop/postgres.c
+++ b/src/backend/tcop/postgres.c
@@ -55,6 +55,7 @@
 #include "postmaster/autovacuum.h"
 #include "postmaster/interrupt.h"
 #include "postmaster/postmaster.h"
+#include "protocol.h"
 #include "replication/logicallauncher.h"
 #include "replication/logicalworker.h"
 #include "replication/slot.h"
@@ -402,37 +403,37 @@ SocketBackend(StringInfo inBuf)
 	 */
 	switch (qtype)
 	{
-		case 'Q':				/* simple query */
+		case PQMSG_REQ_SIMPLE_QUERY:
 			maxmsglen = PQ_LARGE_MESSAGE_LIMIT;
 			doing_extended_query_message = false;
 			break;
 
-		case 'F':				/* fastpath function call */
+		case PQMSG_REQ_FUNCTION_CALL:
 			maxmsglen = PQ_LARGE_MESSAGE_LIMIT;
 			doing_extended_query_message = false;
 			break;
 
-		case 'X':				/* terminate */
+		case PQMSG_REQ_TERMINATE:
 			maxmsglen = PQ_SMALL_MESSAGE_LIMIT;
 			doing_extended_query_message = false;
 			ignore_till_sync = false;
 			break;
 
-		case 'B':				/* bind */
-		case 'P':				/* parse */
+		case PQMSG_REQ_BIND :
+		case PQMSG_REQ_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_REQ_CLOSE:
+		case PQMSG_REQ_DESCRIBE:
+		case PQMSG_REQ_EXECUTE:
+		case PQMSG_REQ_FLUSH_DATA:
 			maxmsglen = PQ_SMALL_MESSAGE_LIMIT;
 			doing_extended_query_message = true;
 			break;
 
-		case 'S':				/* sync */
+		case PQMSG_REQ_SYNC_DATA:
 			maxmsglen = PQ_SMALL_MESSAGE_LIMIT;
 			/* stop any active skip-till-Sync */
 			ignore_till_sync = false;
@@ -440,13 +441,13 @@ SocketBackend(StringInfo inBuf)
 			doing_extended_query_message = false;
 			break;
 
-		case 'd':				/* copy data */
+		case PQMSG_REQ_COPY_DATA:
 			maxmsglen = PQ_LARGE_MESSAGE_LIMIT;
 			doing_extended_query_message = false;
 			break;
 
-		case 'c':				/* copy done */
-		case 'f':				/* copy fail */
+		case PQMSG_REQ_COPY_DONE:
+		case PQMSG_REQ_COPY_FAIL:
 			maxmsglen = PQ_SMALL_MESSAGE_LIMIT;
 			doing_extended_query_message = false;
 			break;
@@ -1589,7 +1590,7 @@ exec_parse_message(const char *query_string,	/* string to execute */
 	 * Send ParseComplete.
 	 */
 	if (whereToSendOutput == DestRemote)
-		pq_putemptymessage('1');
+		pq_putemptymessage(PQMSG_RESP_PARSE_COMPLETE);
 
 	/*
 	 * Emit duration logging if appropriate.
@@ -2047,7 +2048,7 @@ exec_bind_message(StringInfo input_message)
 	 * Send BindComplete.
 	 */
 	if (whereToSendOutput == DestRemote)
-		pq_putemptymessage('2');
+		pq_putemptymessage(PQMSG_RESP_BIND_COMPLETE);
 
 	/*
 	 * Emit duration logging if appropriate.
@@ -2290,7 +2291,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_RESP_PORTAL_SUSPENDED);
 
 		/*
 		 * Set XACT_FLAGS_PIPELINING whenever we suspend an Execute message,
@@ -2683,7 +2684,7 @@ exec_describe_statement_message(const char *stmt_name)
 								  NULL);
 	}
 	else
-		pq_putemptymessage('n');	/* NoData */
+		pq_putemptymessage(PQMSG_RESP_NO_DATA);
 }
 
 /*
@@ -2736,7 +2737,7 @@ exec_describe_portal_message(const char *portal_name)
 								  FetchPortalTargetList(portal),
 								  portal->formats);
 	else
-		pq_putemptymessage('n');	/* NoData */
+		pq_putemptymessage(PQMSG_RESP_NO_DATA);
 }
 
 
@@ -4239,7 +4240,7 @@ PostgresMain(const char *dbname, const char *username)
 	{
 		StringInfoData buf;
 
-		pq_beginmessage(&buf, 'K');
+		pq_beginmessage(&buf, PQMSG_REQ_BACKEND_KEY_DATA);
 		pq_sendint32(&buf, (int32) MyProcPid);
 		pq_sendint32(&buf, (int32) MyCancelKey);
 		pq_endmessage(&buf);
@@ -4618,7 +4619,7 @@ PostgresMain(const char *dbname, const char *username)
 
 		switch (firstchar)
 		{
-			case 'Q':			/* simple query */
+			case PQMSG_REQ_SIMPLE_QUERY:
 				{
 					const char *query_string;
 
@@ -4642,7 +4643,7 @@ PostgresMain(const char *dbname, const char *username)
 				}
 				break;
 
-			case 'P':			/* parse */
+			case PQMSG_REQ_PARSE:
 				{
 					const char *stmt_name;
 					const char *query_string;
@@ -4672,7 +4673,7 @@ PostgresMain(const char *dbname, const char *username)
 				}
 				break;
 
-			case 'B':			/* bind */
+			case PQMSG_REQ_BIND:
 				forbidden_in_wal_sender(firstchar);
 
 				/* Set statement_timestamp() */
@@ -4687,7 +4688,7 @@ PostgresMain(const char *dbname, const char *username)
 				/* exec_bind_message does valgrind_report_error_query */
 				break;
 
-			case 'E':			/* execute */
+			case PQMSG_REQ_EXECUTE:
 				{
 					const char *portal_name;
 					int			max_rows;
@@ -4707,7 +4708,7 @@ PostgresMain(const char *dbname, const char *username)
 				}
 				break;
 
-			case 'F':			/* fastpath function call */
+			case PQMSG_REQ_FUNCTION_CALL:
 				forbidden_in_wal_sender(firstchar);
 
 				/* Set statement_timestamp() */
@@ -4742,7 +4743,7 @@ PostgresMain(const char *dbname, const char *username)
 				send_ready_for_query = true;
 				break;
 
-			case 'C':			/* close */
+			case PQMSG_REQ_CLOSE:
 				{
 					int			close_type;
 					const char *close_target;
@@ -4755,7 +4756,7 @@ PostgresMain(const char *dbname, const char *username)
 
 					switch (close_type)
 					{
-						case 'S':
+						case PREPARED_SUB_COMMAND:
 							if (close_target[0] != '\0')
 								DropPreparedStatement(close_target, false);
 							else
@@ -4764,7 +4765,7 @@ PostgresMain(const char *dbname, const char *username)
 								drop_unnamed_stmt();
 							}
 							break;
-						case 'P':
+						case PORTAL_SUB_COMMAND:
 							{
 								Portal		portal;
 
@@ -4782,13 +4783,13 @@ PostgresMain(const char *dbname, const char *username)
 					}
 
 					if (whereToSendOutput == DestRemote)
-						pq_putemptymessage('3');	/* CloseComplete */
+						pq_putemptymessage(PQMSG_RESP_CLOSE_COMPLETE);
 
 					valgrind_report_error_query("CLOSE message");
 				}
 				break;
 
-			case 'D':			/* describe */
+			case PQMSG_REQ_DESCRIBE:
 				{
 					int			describe_type;
 					const char *describe_target;
@@ -4804,10 +4805,10 @@ PostgresMain(const char *dbname, const char *username)
 
 					switch (describe_type)
 					{
-						case 'S':
+						case PREPARED_SUB_COMMAND:
 							exec_describe_statement_message(describe_target);
 							break;
-						case 'P':
+						case PORTAL_SUB_COMMAND:
 							exec_describe_portal_message(describe_target);
 							break;
 						default:
@@ -4822,13 +4823,13 @@ PostgresMain(const char *dbname, const char *username)
 				}
 				break;
 
-			case 'H':			/* flush */
+			case PQMSG_REQ_FLUSH_DATA:
 				pq_getmsgend(&input_message);
 				if (whereToSendOutput == DestRemote)
 					pq_flush();
 				break;
 
-			case 'S':			/* sync */
+			case PQMSG_REQ_SYNC_DATA:
 				pq_getmsgend(&input_message);
 				finish_xact_command();
 				valgrind_report_error_query("SYNC message");
@@ -4847,7 +4848,7 @@ PostgresMain(const char *dbname, const char *username)
 
 				/* FALLTHROUGH */
 
-			case 'X':
+			case PQMSG_REQ_TERMINATE:
 
 				/*
 				 * Reset whereToSendOutput to prevent ereport from attempting
@@ -4865,9 +4866,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_REQ_COPY_DATA:
+			case PQMSG_REQ_COPY_DONE:
+			case PQMSG_REQ_COPY_FAIL:
 
 				/*
 				 * Accept but ignore these messages, per protocol spec; we
@@ -4897,7 +4898,7 @@ forbidden_in_wal_sender(char firstchar)
 {
 	if (am_walsender)
 	{
-		if (firstchar == 'F')
+		if (firstchar == PQMSG_REQ_FUNCTION_CALL)
 			ereport(ERROR,
 					(errcode(ERRCODE_PROTOCOL_VIOLATION),
 					 errmsg("fastpath function calls not supported in a replication connection")));
diff --git a/src/backend/utils/activity/backend_progress.c b/src/backend/utils/activity/backend_progress.c
index 67447ef03a..6200433594 100644
--- a/src/backend/utils/activity/backend_progress.c
+++ b/src/backend/utils/activity/backend_progress.c
@@ -10,6 +10,7 @@
  */
 #include "postgres.h"
 
+#include "protocol.h"
 #include "access/parallel.h"
 #include "libpq/pqformat.h"
 #include "port/atomics.h"		/* for memory barriers */
@@ -102,7 +103,7 @@ pgstat_progress_parallel_incr_param(int index, int64 incr)
 
 		initStringInfo(&progress_message);
 
-		pq_beginmessage(&progress_message, 'P');
+		pq_beginmessage(&progress_message, PQMSG_RESP_PARALLEL_PROGRESS);
 		pq_sendint32(&progress_message, index);
 		pq_sendint64(&progress_message, incr);
 		pq_endmessage(&progress_message);
diff --git a/src/backend/utils/error/elog.c b/src/backend/utils/error/elog.c
index 5898100acb..2e94ef096a 100644
--- a/src/backend/utils/error/elog.c
+++ b/src/backend/utils/error/elog.c
@@ -77,6 +77,7 @@
 #include "postmaster/bgworker.h"
 #include "postmaster/postmaster.h"
 #include "postmaster/syslogger.h"
+#include "protocol.h"
 #include "storage/ipc.h"
 #include "storage/proc.h"
 #include "tcop/tcopprot.h"
@@ -3465,7 +3466,7 @@ 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');
+		pq_beginmessage(&msgbuf, (edata->elevel < ERROR) ? PQMSG_RESP_NOTICE : PQMSG_RESP_ERROR);
 
 		sev = error_severity(edata->elevel);
 		pq_sendbyte(&msgbuf, PG_DIAG_SEVERITY);
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index 5308896c87..1b9632942e 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -37,6 +37,7 @@
 #include "libpq/pqformat.h"
 #include "parser/scansup.h"
 #include "port/pg_bitutils.h"
+#include "protocol.h"
 #include "storage/fd.h"
 #include "storage/lwlock.h"
 #include "storage/shmem.h"
@@ -2593,7 +2594,7 @@ ReportGUCOption(struct config_generic *record)
 	{
 		StringInfoData msgbuf;
 
-		pq_beginmessage(&msgbuf, 'S');
+		pq_beginmessage(&msgbuf, PQMSG_RESP_PARAMETER_STATUS);
 		pq_sendstring(&msgbuf, record->name);
 		pq_sendstring(&msgbuf, val);
 		pq_endmessage(&msgbuf);
diff --git a/src/include/protocol.h b/src/include/protocol.h
new file mode 100644
index 0000000000..0540b36264
--- /dev/null
+++ b/src/include/protocol.h
@@ -0,0 +1,61 @@
+/*-------------------------------------------------------------------------
+ *
+ * protocol.h
+ *	  Exports from postmaster/postmaster.c.
+ *
+ * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group
+ *
+ * src/include/protocol.h
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef _PROTOCOL_H
+#define _PROTOCOL_H
+
+#define PQMSG_REQ_BIND              'B'
+#define PQMSG_REQ_CLOSE             'C'
+#define PQMSG_REQ_DESCRIBE          'D'
+#define PQMSG_REQ_EXECUTE           'E'
+#define PQMSG_REQ_FUNCTION_CALL     'F'
+#define PQMSG_REQ_FLUSH_DATA        'H'
+#define PQMSG_REQ_BACKEND_KEY_DATA  'K'
+#define PQMSG_REQ_PARSE             'P'
+#define PQMSG_REQ_AUTHENTICATION    'R'
+#define PQMSG_REQ_SYNC_DATA         'S'
+#define PQMSG_REQ_SIMPLE_QUERY      'Q'
+#define PQMSG_REQ_TERMINATE         'X'
+#define PQMSG_REQ_COPY_FAIL         'f'
+#define PQMSG_REQ_COPY_DONE         'c'
+#define PQMSG_REQ_COPY_DATA         'd'
+#define PQMSG_REQ_COPY_PROGRESS     'p'
+#define PREPARED_SUB_COMMAND        'S'
+#define PORTAL_SUB_COMMAND          'P'
+
+
+/*
+Responses
+*/
+#define PQMSG_RESP_PARSE_COMPLETE   '1'
+#define PQMSG_RESP_BIND_COMPLETE    '2'
+#define PQMSG_RESP_CLOSE_COMPLETE   '3'
+#define PQMSG_RESP_NOTIFY           'A'
+#define PQMSG_RESP_COMMAND_COMPLETE 'C'
+#define PQMSG_RESP_DATA_ROW         'D'
+#define PQMSG_RESP_ERROR            'E'
+#define PQMSG_RESP_COPY_IN          'G'
+#define PQMSG_RESP_COPY_OUT         'H'
+#define PQMSG_RESP_EMPTY_QUERY      'I'
+#define PQMSG_RESP_NOTICE           'N'
+#define PQMSG_RESP_PARALLEL_PROGRESS 'P'
+#define PQMSG_RESP_FUNCTION_CALL    'V'
+#define PQMSG_RESP_PARAMETER_STATUS 'S'
+#define PQMSG_RESP_ROW_DESCRIPTION  'T'
+#define PQMSG_RESP_COPY_BOTH        'W'
+#define PQMSG_RESP_READY_FOR_QUERY  'Z'
+#define PQMSG_RESP_NO_DATA          'n'
+#define PQMSG_RESP_PASSWORD         'p'
+#define PQMSG_RESP_GSS              'p'
+#define PQMSG_RESP_PORTAL_SUSPENDED 's'
+#define PQMSG_RESP_PARAMETER_DESCRIPTION 't'
+#define PQMSG_RESP_NEGOTIATE_PROTOCOL    'v'
+#endif
\ No newline at end of file
diff --git a/src/interfaces/libpq/fe-auth.c b/src/interfaces/libpq/fe-auth.c
index 887ca5e9e1..1980e745dd 100644
--- a/src/interfaces/libpq/fe-auth.c
+++ b/src/interfaces/libpq/fe-auth.c
@@ -43,6 +43,7 @@
 #include "fe-auth.h"
 #include "fe-auth-sasl.h"
 #include "libpq-fe.h"
+#include "protocol.h"
 
 #ifdef ENABLE_GSS
 /*
@@ -586,7 +587,7 @@ pg_SASL_init(PGconn *conn, int payloadlen)
 	/*
 	 * Build a SASLInitialResponse message, and send it.
 	 */
-	if (pqPutMsgStart('p', conn))
+	if (pqPutMsgStart(PQMSG_RESP_GSS, conn))
 		goto error;
 	if (pqPuts(selected_mechanism, conn))
 		goto error;
diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
index 837c5321aa..18f27b3cd0 100644
--- a/src/interfaces/libpq/fe-connect.c
+++ b/src/interfaces/libpq/fe-connect.c
@@ -32,6 +32,7 @@
 #include "mb/pg_wchar.h"
 #include "pg_config_paths.h"
 #include "port/pg_bswap.h"
+#include "protocol.h"
 
 #ifdef WIN32
 #include "win32.h"
@@ -3591,7 +3592,7 @@ 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_REQ_AUTHENTICATION || beresp == PQMSG_RESP_NEGOTIATE_PROTOCOL || beresp == PQMSG_RESP_ERROR))
 				{
 					libpq_append_conn_error(conn, "expected authentication request from server, but received %c",
 											beresp);
@@ -3618,19 +3619,19 @@ 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_REQ_AUTHENTICATION && (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_RESP_NEGOTIATE_PROTOCOL && (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_RESP_ERROR && (msgLength < 8 || msgLength > MAX_ERRLEN))
 				{
 					/* Handle error from a pre-3.0 server */
 					conn->inCursor = conn->inStart + 1; /* reread data */
@@ -3693,7 +3694,7 @@ keep_going:						/* We will come back to here until there is
 				}
 
 				/* Handle errors. */
-				if (beresp == 'E')
+				if (beresp == PQMSG_RESP_ERROR)
 				{
 					if (pqGetErrorNotice3(conn, true))
 					{
@@ -3770,7 +3771,7 @@ keep_going:						/* We will come back to here until there is
 
 					goto error_return;
 				}
-				else if (beresp == 'v')
+				else if (beresp == PQMSG_RESP_NEGOTIATE_PROTOCOL)
 				{
 					if (pqGetNegotiateProtocolVersion3(conn))
 					{
@@ -4540,7 +4541,7 @@ sendTerminateConn(PGconn *conn)
 		 * Try to send "close connection" message to backend. Ignore any
 		 * error.
 		 */
-		pqPutMsgStart('X', conn);
+		pqPutMsgStart(PQMSG_REQ_TERMINATE, conn);
 		pqPutMsgEnd(conn);
 		(void) pqFlush(conn);
 	}
diff --git a/src/interfaces/libpq/fe-exec.c b/src/interfaces/libpq/fe-exec.c
index a868284ff8..e105132173 100644
--- a/src/interfaces/libpq/fe-exec.c
+++ b/src/interfaces/libpq/fe-exec.c
@@ -27,6 +27,7 @@
 #include "libpq-fe.h"
 #include "libpq-int.h"
 #include "mb/pg_wchar.h"
+#include "protocol.h"
 
 /* keep this in same order as ExecStatusType in libpq-fe.h */
 char	   *const pgresStatus[] = {
@@ -1458,7 +1459,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_REQ_SIMPLE_QUERY, conn) < 0 ||
 		pqPuts(query, conn) < 0 ||
 		pqPutMsgEnd(conn) < 0)
 	{
@@ -1571,7 +1572,7 @@ PQsendPrepare(PGconn *conn,
 		return 0;				/* error msg already set */
 
 	/* construct the Parse message */
-	if (pqPutMsgStart('P', conn) < 0 ||
+	if (pqPutMsgStart(PQMSG_REQ_PARSE, conn) < 0 ||
 		pqPuts(stmtName, conn) < 0 ||
 		pqPuts(query, conn) < 0)
 		goto sendFailed;
@@ -1599,7 +1600,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_REQ_SYNC_DATA, conn) < 0 ||
 			pqPutMsgEnd(conn) < 0)
 			goto sendFailed;
 	}
@@ -1784,7 +1785,7 @@ PQsendQueryGuts(PGconn *conn,
 	if (command)
 	{
 		/* construct the Parse message */
-		if (pqPutMsgStart('P', conn) < 0 ||
+		if (pqPutMsgStart(PQMSG_REQ_PARSE, conn) < 0 ||
 			pqPuts(stmtName, conn) < 0 ||
 			pqPuts(command, conn) < 0)
 			goto sendFailed;
@@ -1808,7 +1809,7 @@ PQsendQueryGuts(PGconn *conn,
 	}
 
 	/* Construct the Bind message */
-	if (pqPutMsgStart('B', conn) < 0 ||
+	if (pqPutMsgStart(PQMSG_REQ_BIND, conn) < 0 ||
 		pqPuts("", conn) < 0 ||
 		pqPuts(stmtName, conn) < 0)
 		goto sendFailed;
@@ -1874,14 +1875,14 @@ PQsendQueryGuts(PGconn *conn,
 		goto sendFailed;
 
 	/* construct the Describe Portal message */
-	if (pqPutMsgStart('D', conn) < 0 ||
-		pqPutc('P', conn) < 0 ||
+	if (pqPutMsgStart(PQMSG_REQ_DESCRIBE, conn) < 0 ||
+		pqPutc(PORTAL_SUB_COMMAND, conn) < 0 ||
 		pqPuts("", conn) < 0 ||
 		pqPutMsgEnd(conn) < 0)
 		goto sendFailed;
 
 	/* construct the Execute message */
-	if (pqPutMsgStart('E', conn) < 0 ||
+	if (pqPutMsgStart(PQMSG_REQ_EXECUTE, conn) < 0 ||
 		pqPuts("", conn) < 0 ||
 		pqPutInt(0, 4, conn) < 0 ||
 		pqPutMsgEnd(conn) < 0)
@@ -1890,7 +1891,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_REQ_SYNC_DATA, conn) < 0 ||
 			pqPutMsgEnd(conn) < 0)
 			goto sendFailed;
 	}
@@ -2422,7 +2423,7 @@ PQdescribePrepared(PGconn *conn, const char *stmt)
 {
 	if (!PQexecStart(conn))
 		return NULL;
-	if (!PQsendTypedCommand(conn, 'D', 'S', stmt))
+	if (!PQsendTypedCommand(conn, PQMSG_REQ_DESCRIBE, PREPARED_SUB_COMMAND, stmt))
 		return NULL;
 	return PQexecFinish(conn);
 }
@@ -2441,7 +2442,7 @@ PQdescribePortal(PGconn *conn, const char *portal)
 {
 	if (!PQexecStart(conn))
 		return NULL;
-	if (!PQsendTypedCommand(conn, 'D', 'P', portal))
+	if (!PQsendTypedCommand(conn, PQMSG_REQ_DESCRIBE, PORTAL_SUB_COMMAND, portal))
 		return NULL;
 	return PQexecFinish(conn);
 }
@@ -2456,7 +2457,7 @@ PQdescribePortal(PGconn *conn, const char *portal)
 int
 PQsendDescribePrepared(PGconn *conn, const char *stmt)
 {
-	return PQsendTypedCommand(conn, 'D', 'S', stmt);
+	return PQsendTypedCommand(conn, PQMSG_REQ_DESCRIBE, PREPARED_SUB_COMMAND, stmt);
 }
 
 /*
@@ -2469,7 +2470,7 @@ PQsendDescribePrepared(PGconn *conn, const char *stmt)
 int
 PQsendDescribePortal(PGconn *conn, const char *portal)
 {
-	return PQsendTypedCommand(conn, 'D', 'P', portal);
+	return PQsendTypedCommand(conn, PQMSG_REQ_DESCRIBE, PORTAL_SUB_COMMAND, portal);
 }
 
 /*
@@ -2488,7 +2489,7 @@ PQclosePrepared(PGconn *conn, const char *stmt)
 {
 	if (!PQexecStart(conn))
 		return NULL;
-	if (!PQsendTypedCommand(conn, 'C', 'S', stmt))
+	if (!PQsendTypedCommand(conn, PQMSG_REQ_CLOSE, PREPARED_SUB_COMMAND, stmt))
 		return NULL;
 	return PQexecFinish(conn);
 }
@@ -2506,7 +2507,7 @@ PQclosePortal(PGconn *conn, const char *portal)
 {
 	if (!PQexecStart(conn))
 		return NULL;
-	if (!PQsendTypedCommand(conn, 'C', 'P', portal))
+	if (!PQsendTypedCommand(conn, PQMSG_REQ_CLOSE, PORTAL_SUB_COMMAND, portal))
 		return NULL;
 	return PQexecFinish(conn);
 }
@@ -2521,7 +2522,7 @@ PQclosePortal(PGconn *conn, const char *portal)
 int
 PQsendClosePrepared(PGconn *conn, const char *stmt)
 {
-	return PQsendTypedCommand(conn, 'C', 'S', stmt);
+	return PQsendTypedCommand(conn, PQMSG_REQ_CLOSE, PREPARED_SUB_COMMAND, stmt);
 }
 
 /*
@@ -2534,7 +2535,7 @@ PQsendClosePrepared(PGconn *conn, const char *stmt)
 int
 PQsendClosePortal(PGconn *conn, const char *portal)
 {
-	return PQsendTypedCommand(conn, 'C', 'P', portal);
+	return PQsendTypedCommand(conn, PQMSG_REQ_CLOSE, PORTAL_SUB_COMMAND, portal);
 }
 
 /*
@@ -2577,17 +2578,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_REQ_SYNC_DATA, conn) < 0 ||
 			pqPutMsgEnd(conn) < 0)
 			goto sendFailed;
 	}
 
 	/* remember if we are doing a Close or a Describe */
-	if (command == 'C')
+	if (command == PQMSG_REQ_CLOSE)
 	{
 		entry->queryclass = PGQUERY_CLOSE;
 	}
-	else if (command == 'D')
+	else if (command == PQMSG_REQ_DESCRIBE)
 	{
 		entry->queryclass = PGQUERY_DESCRIBE;
 	}
@@ -2696,7 +2697,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_REQ_COPY_DATA, conn) < 0 ||
 			pqPutnchar(buffer, nbytes, conn) < 0 ||
 			pqPutMsgEnd(conn) < 0)
 			return -1;
@@ -2731,7 +2732,7 @@ PQputCopyEnd(PGconn *conn, const char *errormsg)
 	if (errormsg)
 	{
 		/* Send COPY FAIL */
-		if (pqPutMsgStart('f', conn) < 0 ||
+		if (pqPutMsgStart(PQMSG_REQ_COPY_FAIL, conn) < 0 ||
 			pqPuts(errormsg, conn) < 0 ||
 			pqPutMsgEnd(conn) < 0)
 			return -1;
@@ -2739,7 +2740,7 @@ PQputCopyEnd(PGconn *conn, const char *errormsg)
 	else
 	{
 		/* Send COPY DONE */
-		if (pqPutMsgStart('c', conn) < 0 ||
+		if (pqPutMsgStart(PQMSG_REQ_COPY_DONE, conn) < 0 ||
 			pqPutMsgEnd(conn) < 0)
 			return -1;
 	}
@@ -2751,7 +2752,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_REQ_SYNC_DATA, conn) < 0 ||
 			pqPutMsgEnd(conn) < 0)
 			return -1;
 	}
@@ -3263,7 +3264,7 @@ PQpipelineSync(PGconn *conn)
 	entry->query = NULL;
 
 	/* construct the Sync message */
-	if (pqPutMsgStart('S', conn) < 0 ||
+	if (pqPutMsgStart(PQMSG_REQ_SYNC_DATA, conn) < 0 ||
 		pqPutMsgEnd(conn) < 0)
 		goto sendFailed;
 
@@ -3311,7 +3312,7 @@ PQsendFlushRequest(PGconn *conn)
 		return 0;
 	}
 
-	if (pqPutMsgStart('H', conn) < 0 ||
+	if (pqPutMsgStart(PQMSG_REQ_FLUSH_DATA, conn) < 0 ||
 		pqPutMsgEnd(conn) < 0)
 	{
 		return 0;
diff --git a/src/interfaces/libpq/fe-protocol3.c b/src/interfaces/libpq/fe-protocol3.c
index 7bc6355d17..8de12f4aca 100644
--- a/src/interfaces/libpq/fe-protocol3.c
+++ b/src/interfaces/libpq/fe-protocol3.c
@@ -28,14 +28,16 @@
 #include "libpq-int.h"
 #include "mb/pg_wchar.h"
 #include "port/pg_bswap.h"
+#include "protocol.h"
 
 /*
  * This macro lists the backend message types that could be "long" (more
  * 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_RESP_ROW_DESCRIPTION || (id) == PQMSG_RESP_DATA_ROW || (id) == PQMSG_REQ_COPY_DATA || \
+	 (id) == PQMSG_RESP_FUNCTION_CALL ||  (id) == PQMSG_RESP_ERROR || (id) == PQMSG_RESP_NOTICE || \
+	 (id) == PQMSG_RESP_NOTIFY)
 
 
 static void handleSyncLoss(PGconn *conn, char id, int msgLength);
@@ -140,12 +142,12 @@ pqParseInput3(PGconn *conn)
 		 * from config file due to SIGHUP), but otherwise we hold off until
 		 * BUSY state.
 		 */
-		if (id == 'A')
+		if (id == PQMSG_RESP_NOTIFY)
 		{
 			if (getNotify(conn))
 				return;
 		}
-		else if (id == 'N')
+		else if (id == PQMSG_RESP_NOTICE)
 		{
 			if (pqGetErrorNotice3(conn, false))
 				return;
@@ -165,12 +167,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_RESP_ERROR)
 			{
 				if (pqGetErrorNotice3(conn, false /* treat as notice */ ))
 					return;
 			}
-			else if (id == 'S')
+			else if (id == PQMSG_RESP_PARAMETER_STATUS)
 			{
 				if (getParameterStatus(conn))
 					return;
@@ -192,7 +194,7 @@ pqParseInput3(PGconn *conn)
 			 */
 			switch (id)
 			{
-				case 'C':		/* command complete */
+				case PQMSG_RESP_COMMAND_COMPLETE:
 					if (pqGets(&conn->workBuffer, conn))
 						return;
 					if (!pgHavePendingResult(conn))
@@ -210,12 +212,12 @@ pqParseInput3(PGconn *conn)
 								CMDSTATUS_LEN);
 					conn->asyncStatus = PGASYNC_READY;
 					break;
-				case 'E':		/* error return */
+				case PQMSG_RESP_ERROR:
 					if (pqGetErrorNotice3(conn, true))
 						return;
 					conn->asyncStatus = PGASYNC_READY;
 					break;
-				case 'Z':		/* sync response, backend is ready for new
+				case PQMSG_RESP_READY_FOR_QUERY:		/* sync response, backend is ready for new
 								 * query */
 					if (getReadyForQuery(conn))
 						return;
@@ -246,7 +248,7 @@ pqParseInput3(PGconn *conn)
 						conn->asyncStatus = PGASYNC_IDLE;
 					}
 					break;
-				case 'I':		/* empty query */
+				case PQMSG_RESP_EMPTY_QUERY:
 					if (!pgHavePendingResult(conn))
 					{
 						conn->result = PQmakeEmptyPGresult(conn,
@@ -259,7 +261,7 @@ pqParseInput3(PGconn *conn)
 					}
 					conn->asyncStatus = PGASYNC_READY;
 					break;
-				case '1':		/* Parse Complete */
+				case PQMSG_RESP_PARSE_COMPLETE:
 					/* If we're doing PQprepare, we're done; else ignore */
 					if (conn->cmd_queue_head &&
 						conn->cmd_queue_head->queryclass == PGQUERY_PREPARE)
@@ -277,10 +279,10 @@ pqParseInput3(PGconn *conn)
 						conn->asyncStatus = PGASYNC_READY;
 					}
 					break;
-				case '2':		/* Bind Complete */
+				case PQMSG_RESP_BIND_COMPLETE:
 					/* Nothing to do for this message type */
 					break;
-				case '3':		/* Close Complete */
+				case PQMSG_RESP_CLOSE_COMPLETE:
 					/* If we're doing PQsendClose, we're done; else ignore */
 					if (conn->cmd_queue_head &&
 						conn->cmd_queue_head->queryclass == PGQUERY_CLOSE)
@@ -298,11 +300,11 @@ pqParseInput3(PGconn *conn)
 						conn->asyncStatus = PGASYNC_READY;
 					}
 					break;
-				case 'S':		/* parameter status */
+				case PQMSG_RESP_PARAMETER_STATUS:
 					if (getParameterStatus(conn))
 						return;
 					break;
-				case 'K':		/* secret key data from the backend */
+				case PQMSG_REQ_BACKEND_KEY_DATA:		/* secret key data from the backend */
 
 					/*
 					 * This is expected only during backend startup, but it's
@@ -314,7 +316,7 @@ pqParseInput3(PGconn *conn)
 					if (pqGetInt(&(conn->be_key), 4, conn))
 						return;
 					break;
-				case 'T':		/* Row Description */
+				case PQMSG_RESP_ROW_DESCRIPTION:
 					if (conn->error_result ||
 						(conn->result != NULL &&
 						 conn->result->resultStatus == PGRES_FATAL_ERROR))
@@ -346,7 +348,7 @@ pqParseInput3(PGconn *conn)
 						return;
 					}
 					break;
-				case 'n':		/* No Data */
+				case PQMSG_RESP_NO_DATA:
 
 					/*
 					 * NoData indicates that we will not be seeing a
@@ -374,11 +376,11 @@ pqParseInput3(PGconn *conn)
 						conn->asyncStatus = PGASYNC_READY;
 					}
 					break;
-				case 't':		/* Parameter Description */
+				case PQMSG_RESP_PARAMETER_DESCRIPTION:
 					if (getParamDescriptions(conn, msgLength))
 						return;
 					break;
-				case 'D':		/* Data Row */
+				case PQMSG_RESP_DATA_ROW:
 					if (conn->result != NULL &&
 						conn->result->resultStatus == PGRES_TUPLES_OK)
 					{
@@ -405,24 +407,24 @@ pqParseInput3(PGconn *conn)
 						conn->inCursor += msgLength;
 					}
 					break;
-				case 'G':		/* Start Copy In */
+				case PQMSG_RESP_COPY_IN:
 					if (getCopyStart(conn, PGRES_COPY_IN))
 						return;
 					conn->asyncStatus = PGASYNC_COPY_IN;
 					break;
-				case 'H':		/* Start Copy Out */
+				case PQMSG_RESP_COPY_OUT:
 					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_RESP_COPY_BOTH:
 					if (getCopyStart(conn, PGRES_COPY_BOTH))
 						return;
 					conn->asyncStatus = PGASYNC_COPY_BOTH;
 					conn->copy_already_done = 0;
 					break;
-				case 'd':		/* Copy Data */
+				case PQMSG_REQ_COPY_DATA:
 
 					/*
 					 * If we see Copy Data, just silently drop it.  This would
@@ -431,7 +433,7 @@ pqParseInput3(PGconn *conn)
 					 */
 					conn->inCursor += msgLength;
 					break;
-				case 'c':		/* Copy Done */
+				case PQMSG_REQ_COPY_DONE:
 
 					/*
 					 * If we see Copy Done, just silently drop it.  This is
@@ -1692,21 +1694,21 @@ getCopyDataMessage(PGconn *conn)
 		 */
 		switch (id)
 		{
-			case 'A':			/* NOTIFY */
+			case PQMSG_RESP_NOTIFY:
 				if (getNotify(conn))
 					return 0;
 				break;
-			case 'N':			/* NOTICE */
+			case PQMSG_RESP_NOTICE:
 				if (pqGetErrorNotice3(conn, false))
 					return 0;
 				break;
-			case 'S':			/* ParameterStatus */
+			case PQMSG_RESP_PARAMETER_STATUS:
 				if (getParameterStatus(conn))
 					return 0;
 				break;
-			case 'd':			/* Copy Data, pass it back to caller */
+			case PQMSG_REQ_COPY_DATA:			/* Copy Data, pass it back to caller */
 				return msgLength;
-			case 'c':
+			case PQMSG_REQ_COPY_DONE:
 
 				/*
 				 * If this is a CopyDone message, exit COPY_OUT mode and let
@@ -1929,7 +1931,7 @@ pqEndcopy3(PGconn *conn)
 	if (conn->asyncStatus == PGASYNC_COPY_IN ||
 		conn->asyncStatus == PGASYNC_COPY_BOTH)
 	{
-		if (pqPutMsgStart('c', conn) < 0 ||
+		if (pqPutMsgStart(PQMSG_REQ_COPY_DONE, conn) < 0 ||
 			pqPutMsgEnd(conn) < 0)
 			return 1;
 
@@ -1940,7 +1942,7 @@ pqEndcopy3(PGconn *conn)
 		if (conn->cmd_queue_head &&
 			conn->cmd_queue_head->queryclass != PGQUERY_SIMPLE)
 		{
-			if (pqPutMsgStart('S', conn) < 0 ||
+			if (pqPutMsgStart(PQMSG_REQ_SYNC_DATA, conn) < 0 ||
 				pqPutMsgEnd(conn) < 0)
 				return 1;
 		}
@@ -2023,7 +2025,7 @@ pqFunctionCall3(PGconn *conn, Oid fnid,
 
 	/* PQfn already validated connection state */
 
-	if (pqPutMsgStart('F', conn) < 0 || /* function call msg */
+	if (pqPutMsgStart(PQMSG_REQ_FUNCTION_CALL, conn) < 0 || /* function call msg */
 		pqPutInt(fnid, 4, conn) < 0 ||	/* function id */
 		pqPutInt(1, 2, conn) < 0 || /* # of format codes */
 		pqPutInt(1, 2, conn) < 0 || /* format code: BINARY */
diff --git a/src/interfaces/libpq/fe-trace.c b/src/interfaces/libpq/fe-trace.c
index 402784f40e..83c3328444 100644
--- a/src/interfaces/libpq/fe-trace.c
+++ b/src/interfaces/libpq/fe-trace.c
@@ -28,6 +28,7 @@
 #include "libpq-fe.h"
 #include "libpq-int.h"
 #include "port/pg_bswap.h"
+#include "protocol.h"
 
 
 /* Enable tracing */
@@ -562,110 +563,110 @@ pqTraceOutputMessage(PGconn *conn, const char *message, bool toServer)
 
 	switch (id)
 	{
-		case '1':
+		case PQMSG_RESP_PARSE_COMPLETE:
 			fprintf(conn->Pfdebug, "ParseComplete");
 			/* No message content */
 			break;
-		case '2':
+		case PQMSG_RESP_BIND_COMPLETE:
 			fprintf(conn->Pfdebug, "BindComplete");
 			/* No message content */
 			break;
-		case '3':
+		case PQMSG_RESP_CLOSE_COMPLETE:
 			fprintf(conn->Pfdebug, "CloseComplete");
 			/* No message content */
 			break;
-		case 'A':				/* Notification Response */
+		case PQMSG_RESP_NOTIFY:
 			pqTraceOutputA(conn->Pfdebug, message, &logCursor, regress);
 			break;
-		case 'B':				/* Bind */
+		case PQMSG_REQ_BIND:
 			pqTraceOutputB(conn->Pfdebug, message, &logCursor);
 			break;
-		case 'c':
+		case PQMSG_REQ_COPY_DONE:
 			fprintf(conn->Pfdebug, "CopyDone");
 			/* No message content */
 			break;
-		case 'C':				/* Close(F) or Command Complete(B) */
+		case PQMSG_RESP_COMMAND_COMPLETE:				/* Close(F) or Command Complete(B) */
 			pqTraceOutputC(conn->Pfdebug, toServer, message, &logCursor);
 			break;
-		case 'd':				/* Copy Data */
+		case PQMSG_REQ_COPY_DATA:
 			/* Drop COPY data to reduce the overhead of logging. */
 			break;
-		case 'D':				/* Describe(F) or Data Row(B) */
+		case PQMSG_REQ_DESCRIBE:		/* Describe(F) or Data Row(B) */
 			pqTraceOutputD(conn->Pfdebug, toServer, message, &logCursor);
 			break;
-		case 'E':				/* Execute(F) or Error Response(B) */
+		case PQMSG_REQ_EXECUTE:		/* Execute(F) or Error Response(B) */
 			pqTraceOutputE(conn->Pfdebug, toServer, message, &logCursor,
 						   regress);
 			break;
-		case 'f':				/* Copy Fail */
+		case PQMSG_REQ_COPY_FAIL:
 			pqTraceOutputf(conn->Pfdebug, message, &logCursor);
 			break;
-		case 'F':				/* Function Call */
+		case PQMSG_REQ_FUNCTION_CALL:
 			pqTraceOutputF(conn->Pfdebug, message, &logCursor, regress);
 			break;
-		case 'G':				/* Start Copy In */
+		case PQMSG_RESP_COPY_IN:
 			pqTraceOutputG(conn->Pfdebug, message, &logCursor);
 			break;
-		case 'H':				/* Flush(F) or Start Copy Out(B) */
+		case PQMSG_REQ_FLUSH_DATA:	/* Flush(F) or Start Copy Out(B) */
 			if (!toServer)
 				pqTraceOutputH(conn->Pfdebug, message, &logCursor);
 			else
 				fprintf(conn->Pfdebug, "Flush");	/* no message content */
 			break;
-		case 'I':
+		case PQMSG_RESP_EMPTY_QUERY:
 			fprintf(conn->Pfdebug, "EmptyQueryResponse");
 			/* No message content */
 			break;
-		case 'K':				/* secret key data from the backend */
+		case PQMSG_REQ_BACKEND_KEY_DATA:		/* secret key data from the backend */
 			pqTraceOutputK(conn->Pfdebug, message, &logCursor, regress);
 			break;
-		case 'n':
+		case PQMSG_RESP_NO_DATA:
 			fprintf(conn->Pfdebug, "NoData");
 			/* No message content */
 			break;
-		case 'N':
+		case PQMSG_RESP_NOTICE:
 			pqTraceOutputNR(conn->Pfdebug, "NoticeResponse", message,
 							&logCursor, regress);
 			break;
-		case 'P':				/* Parse */
+		case PQMSG_REQ_PARSE:
 			pqTraceOutputP(conn->Pfdebug, message, &logCursor, regress);
 			break;
-		case 'Q':				/* Query */
+		case PQMSG_REQ_SIMPLE_QUERY:
 			pqTraceOutputQ(conn->Pfdebug, message, &logCursor);
 			break;
-		case 'R':				/* Authentication */
+		case PQMSG_REQ_AUTHENTICATION:
 			pqTraceOutputR(conn->Pfdebug, message, &logCursor);
 			break;
-		case 's':
+		case PQMSG_RESP_PORTAL_SUSPENDED:
 			fprintf(conn->Pfdebug, "PortalSuspended");
 			/* No message content */
 			break;
-		case 'S':				/* Parameter Status(B) or Sync(F) */
+		case PQMSG_REQ_SYNC_DATA:	/* Parameter Status(B) or Sync(F) */
 			if (!toServer)
 				pqTraceOutputS(conn->Pfdebug, message, &logCursor);
 			else
 				fprintf(conn->Pfdebug, "Sync"); /* no message content */
 			break;
-		case 't':				/* Parameter Description */
+		case PQMSG_RESP_PARAMETER_DESCRIPTION:
 			pqTraceOutputt(conn->Pfdebug, message, &logCursor, regress);
 			break;
-		case 'T':				/* Row Description */
+		case PQMSG_RESP_ROW_DESCRIPTION:
 			pqTraceOutputT(conn->Pfdebug, message, &logCursor, regress);
 			break;
-		case 'v':				/* Negotiate Protocol Version */
+		case PQMSG_RESP_NEGOTIATE_PROTOCOL:
 			pqTraceOutputv(conn->Pfdebug, message, &logCursor);
 			break;
-		case 'V':				/* Function Call response */
+		case PQMSG_RESP_FUNCTION_CALL:
 			pqTraceOutputV(conn->Pfdebug, message, &logCursor);
 			break;
-		case 'W':				/* Start Copy Both */
+		case PQMSG_RESP_COPY_BOTH:
 			pqTraceOutputW(conn->Pfdebug, message, &logCursor, length);
 			break;
-		case 'X':
+		case PQMSG_REQ_TERMINATE:
 			fprintf(conn->Pfdebug, "Terminate");
 			/* No message content */
 			break;
-		case 'Z':				/* Ready For Query */
+		case PQMSG_RESP_READY_FOR_QUERY:
 			pqTraceOutputZ(conn->Pfdebug, message, &logCursor);
 			break;
 		default:
-- 
2.37.1 (Apple Git-137.1)

