From 405c93009d7e9309b4ad63e1c40a555c9bc41f1c Mon Sep 17 00:00:00 2001
From: Aleksander Alekseev <aleksander@timescale.com>
Date: Tue, 16 Jul 2024 15:33:18 +0300
Subject: [PATCH v2 2/3] Introduce PqMsg enum.

Previously we passed PqMsg_* as regular char's. There are two problems with
this approach:

1. Lack of type-safety. One can pass a wrong char value and the code would
   compile.
2. Some authors passed PqMsg_DataRow while others passed 'D' which made
   the code inconsistent and difficult to search.

This patch mitigates both problems by using enum instead of char's.

Aleksander Alekseev, reviewed by TODO FIXME
Discussion: TODO FIXME
---
 src/backend/access/common/printtup.c |  1 -
 src/backend/commands/explain.c       |  1 -
 src/backend/libpq/pqformat.c         |  8 +--
 src/include/libpq/pqformat.h         |  9 +--
 src/include/libpq/protocol.h         | 91 ++++++++++++++--------------
 5 files changed, 55 insertions(+), 55 deletions(-)

diff --git a/src/backend/access/common/printtup.c b/src/backend/access/common/printtup.c
index c78cc39308..1e67aea3b1 100644
--- a/src/backend/access/common/printtup.c
+++ b/src/backend/access/common/printtup.c
@@ -17,7 +17,6 @@
 
 #include "access/printtup.h"
 #include "libpq/pqformat.h"
-#include "libpq/protocol.h"
 #include "tcop/pquery.h"
 #include "utils/lsyscache.h"
 #include "utils/memdebug.h"
diff --git a/src/backend/commands/explain.c b/src/backend/commands/explain.c
index 5771aabf40..4cd01bbbc3 100644
--- a/src/backend/commands/explain.c
+++ b/src/backend/commands/explain.c
@@ -21,7 +21,6 @@
 #include "foreign/fdwapi.h"
 #include "jit/jit.h"
 #include "libpq/pqformat.h"
-#include "libpq/protocol.h"
 #include "nodes/extensible.h"
 #include "nodes/makefuncs.h"
 #include "nodes/nodeFuncs.h"
diff --git a/src/backend/libpq/pqformat.c b/src/backend/libpq/pqformat.c
index aa9433bb3b..e908144f44 100644
--- a/src/backend/libpq/pqformat.c
+++ b/src/backend/libpq/pqformat.c
@@ -85,7 +85,7 @@
  * --------------------------------
  */
 void
-pq_beginmessage(StringInfo buf, char msgtype)
+pq_beginmessage(StringInfo buf, PqMsg msgtype)
 {
 	initStringInfo(buf);
 
@@ -106,7 +106,7 @@ pq_beginmessage(StringInfo buf, char msgtype)
  * --------------------------------
  */
 void
-pq_beginmessage_reuse(StringInfo buf, char msgtype)
+pq_beginmessage_reuse(StringInfo buf, PqMsg msgtype)
 {
 	resetStringInfo(buf);
 
@@ -364,7 +364,7 @@ pq_endtypsend(StringInfo buf)
  * --------------------------------
  */
 void
-pq_puttextmessage(char msgtype, const char *str)
+pq_puttextmessage(PqMsg msgtype, const char *str)
 {
 	int			slen = strlen(str);
 	char	   *p;
@@ -385,7 +385,7 @@ pq_puttextmessage(char msgtype, const char *str)
  * --------------------------------
  */
 void
-pq_putemptymessage(char msgtype)
+pq_putemptymessage(PqMsg msgtype)
 {
 	(void) pq_putmessage(msgtype, NULL, 0);
 }
diff --git a/src/include/libpq/pqformat.h b/src/include/libpq/pqformat.h
index 7f48cbded9..f9e785e6a5 100644
--- a/src/include/libpq/pqformat.h
+++ b/src/include/libpq/pqformat.h
@@ -13,12 +13,13 @@
 #ifndef PQFORMAT_H
 #define PQFORMAT_H
 
+#include "protocol.h"
 #include "lib/stringinfo.h"
 #include "mb/pg_wchar.h"
 #include "port/pg_bswap.h"
 
-extern void pq_beginmessage(StringInfo buf, char msgtype);
-extern void pq_beginmessage_reuse(StringInfo buf, char msgtype);
+extern void pq_beginmessage(StringInfo buf, PqMsg msgtype);
+extern void pq_beginmessage_reuse(StringInfo buf, PqMsg msgtype);
 extern void pq_endmessage(StringInfo buf);
 extern void pq_endmessage_reuse(StringInfo buf);
 
@@ -191,8 +192,8 @@ pq_sendint(StringInfo buf, uint32 i, int b)
 extern void pq_begintypsend(StringInfo buf);
 extern bytea *pq_endtypsend(StringInfo buf);
 
-extern void pq_puttextmessage(char msgtype, const char *str);
-extern void pq_putemptymessage(char msgtype);
+extern void pq_puttextmessage(PqMsg msgtype, const char *str);
+extern void pq_putemptymessage(PqMsg msgtype);
 
 extern int	pq_getmsgbyte(StringInfo msg);
 extern unsigned int pq_getmsgint(StringInfo msg, int b);
diff --git a/src/include/libpq/protocol.h b/src/include/libpq/protocol.h
index 8c0f095edf..840a049d04 100644
--- a/src/include/libpq/protocol.h
+++ b/src/include/libpq/protocol.h
@@ -14,57 +14,58 @@
 #ifndef PROTOCOL_H
 #define PROTOCOL_H
 
-/* These are the request codes sent by the frontend. */
+typedef enum PqMsg
+{
+	/* 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'
+	PqMsg_Bind = 'B',
+	PqMsg_Close = 'C',
+	PqMsg_Describe = 'D',
+	PqMsg_Execute = 'E',
+	PqMsg_FunctionCall = 'F',
+	PqMsg_Flush = 'H',
+	PqMsg_Parse = 'P',
+	PqMsg_Query = 'Q',
+	PqMsg_Sync = 'S',
+	PqMsg_Terminate = 'X',
+	PqMsg_CopyFail = 'f',
+	PqMsg_GSSResponse = 'p',
+	PqMsg_PasswordMessage = 'p',
+	PqMsg_SASLInitialResponse = 'p',
+	PqMsg_SASLResponse = 'p',
 
+	/* These are the response codes sent by the backend. */
 
-/* These are the response codes sent by the backend. */
+	PqMsg_ParseComplete = '1',
+	PqMsg_BindComplete = '2',
+	PqMsg_CloseComplete = '3',
+	PqMsg_NotificationResponse = 'A',
+	PqMsg_CommandComplete = 'C',
+	PqMsg_DataRow = 'D',
+	PqMsg_ErrorResponse = 'E',
+	PqMsg_CopyInResponse = 'G',
+	PqMsg_CopyOutResponse = 'H',
+	PqMsg_EmptyQueryResponse = 'I',
+	PqMsg_BackendKeyData = 'K',
+	PqMsg_NoticeResponse = 'N',
+	PqMsg_Progress = 'P',
+	PqMsg_AuthenticationRequest = 'R',
+	PqMsg_ParameterStatus = 'S',
+	PqMsg_RowDescription = 'T',
+	PqMsg_FunctionCallResponse = 'V',
+	PqMsg_CopyBothResponse = 'W',
+	PqMsg_ReadyForQuery = 'Z',
+	PqMsg_NoData = 'n',
+	PqMsg_PortalSuspended = 's',
+	PqMsg_ParameterDescription = 't',
+	PqMsg_NegotiateProtocolVersion = 'v',
 
-#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_Progress              'P'
-#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. */
 
+	PqMsg_CopyDone = 'c',
+	PqMsg_CopyData = 'd',
 
-/* These are the codes sent by both the frontend and backend. */
-
-#define PqMsg_CopyDone				'c'
-#define PqMsg_CopyData				'd'
-
+}			PqMsg;
 
 /* These are the authentication request codes sent by the backend. */
 
-- 
2.45.2

