From 3fdb3f11d99f4efb8e88b3c8888b4092694f45c7 Mon Sep 17 00:00:00 2001
From: Kyotaro Horiguchi <horikyoga.ntt@gmail.com>
Date: Fri, 13 Mar 2020 12:00:23 +0900
Subject: [PATCH 05/11] Fix interface of PQregisterEventProc

The function returns false for all kind of failures so the caller
cannot identify the cause of failure. Change the return value from
int(bool) to an enum.
---
 src/interfaces/libpq/libpq-events.c | 34 ++++++++++++++++++++++-------
 src/interfaces/libpq/libpq-events.h | 15 +++++++++++--
 2 files changed, 39 insertions(+), 10 deletions(-)

diff --git a/src/interfaces/libpq/libpq-events.c b/src/interfaces/libpq/libpq-events.c
index d050d7f3f2..6b594d910a 100644
--- a/src/interfaces/libpq/libpq-events.c
+++ b/src/interfaces/libpq/libpq-events.c
@@ -36,20 +36,31 @@
  * The function returns a non-zero if successful.  If the function fails,
  * zero is returned.
  */
-int
+PGRegEventResult
 PQregisterEventProc(PGconn *conn, PGEventProc proc,
 					const char *name, void *passThrough)
 {
 	int			i;
 	PGEventRegister regevt;
 
-	if (!proc || !conn || !name || !*name)
-		return false;			/* bad arguments */
+	if (!conn)
+		return PGEVTREG_BADARG;
+
+	if (!proc || !name || !*name)
+	{
+		printfPQExpBuffer(&conn->errorMessage,
+						  "bad argument in PQregisterEventProc");
+		return PGEVTREG_BADARG;
+	}
 
 	for (i = 0; i < conn->nEvents; i++)
 	{
 		if (conn->events[i].proc == proc)
-			return false;		/* already registered */
+		{
+			printfPQExpBuffer(&conn->errorMessage,
+							  "proc is already registered in PQregisterEventProc");
+			return PGEVTREG_ALREADY_REAGISTERED;
+		}
 	}
 
 	if (conn->nEvents >= conn->eventArraySize)
@@ -64,7 +75,10 @@ PQregisterEventProc(PGconn *conn, PGEventProc proc,
 			e = (PGEvent *) malloc(newSize * sizeof(PGEvent));
 
 		if (!e)
-			return false;
+		{
+			printfPQExpBuffer(&conn->errorMessage, "out of memory");
+			return PGEVTREG_OUT_OF_MEMORY;
+		}
 
 		conn->eventArraySize = newSize;
 		conn->events = e;
@@ -73,7 +87,10 @@ PQregisterEventProc(PGconn *conn, PGEventProc proc,
 	conn->events[conn->nEvents].proc = proc;
 	conn->events[conn->nEvents].name = strdup(name);
 	if (!conn->events[conn->nEvents].name)
-		return false;
+	{
+		printfPQExpBuffer(&conn->errorMessage, "out of memory");
+		return PGEVTREG_OUT_OF_MEMORY;
+	}
 	conn->events[conn->nEvents].passThrough = passThrough;
 	conn->events[conn->nEvents].data = NULL;
 	conn->events[conn->nEvents].resultInitialized = false;
@@ -84,10 +101,11 @@ PQregisterEventProc(PGconn *conn, PGEventProc proc,
 	{
 		conn->nEvents--;
 		free(conn->events[conn->nEvents].name);
-		return false;
+		printfPQExpBuffer(&conn->errorMessage, "proc rejected");
+		return PGEVTREG_PROC_REJECTED;
 	}
 
-	return true;
+	return PGEVTREG_SUCCESS;
 }
 
 /*
diff --git a/src/interfaces/libpq/libpq-events.h b/src/interfaces/libpq/libpq-events.h
index 5108a55cf6..7b07537c11 100644
--- a/src/interfaces/libpq/libpq-events.h
+++ b/src/interfaces/libpq/libpq-events.h
@@ -23,6 +23,16 @@ extern "C"
 {
 #endif
 
+/* PQregisterEventProc return value */
+typedef enum
+{
+	PGEVTREG_SUCCESS,
+	PGEVTREG_BADARG,
+	PGEVTREG_ALREADY_REAGISTERED,
+	PGEVTREG_OUT_OF_MEMORY,
+	PGEVTREG_PROC_REJECTED
+} PGRegEventResult;
+	
 /* Callback Event Ids */
 typedef enum
 {
@@ -69,8 +79,9 @@ typedef struct
 typedef int (*PGEventProc) (PGEventId evtId, void *evtInfo, void *passThrough);
 
 /* Registers an event proc with the given PGconn. */
-extern int	PQregisterEventProc(PGconn *conn, PGEventProc proc,
-								const char *name, void *passThrough);
+extern PGRegEventResult	PQregisterEventProc(PGconn *conn, PGEventProc proc,
+											const char *name,
+											void *passThrough);
 
 /* Sets the PGconn instance data for the provided proc to data. */
 extern int	PQsetInstanceData(PGconn *conn, PGEventProc proc, void *data);
-- 
2.18.2

