From 52ba9ed63a7b2d06cfc50626e08edc98425b3ff7 Mon Sep 17 00:00:00 2001
From: Hari Babu <kommi.haribabu@gmail.com>
Date: Sat, 24 Mar 2018 01:16:19 +1100
Subject: [PATCH] PQhost to return connected host and hostaddr details

Earlier PQhost doesn't return the connected host details
when the connection type is CHT_HOST_ADDRESS instead it
returns the provided all connection host parameter values
or the default host details, this can lead to confusion.

It is better to provide the actual host or hostaddr details of
the connected host irrespective of the connection type.
when both host and hostaddr are specified in the connection
string, host parameter value is returned.

Similarly PQport is also changed to return the connection
port of NULL instead of all the ports specified in the connection
string.
---
 doc/src/sgml/libpq.sgml           | 16 +++++++++++++---
 src/interfaces/libpq/fe-connect.c | 37 ++++++++++++++++++++-----------------
 2 files changed, 33 insertions(+), 20 deletions(-)

diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml
index 1fd5dd9fca..2c97015748 100644
--- a/doc/src/sgml/libpq.sgml
+++ b/doc/src/sgml/libpq.sgml
@@ -1692,7 +1692,7 @@ char *PQpass(const PGconn *conn);
 
      <listitem>
       <para>
-       Returns the server host name of the connection.
+       Returns the server host name or host address of the connection.
        This can be a host name, an IP address, or a directory path if the
        connection is via Unix socket.  (The path case can be distinguished
        because it will always be an absolute path, beginning
@@ -1701,6 +1701,15 @@ char *PQpass(const PGconn *conn);
 char *PQhost(const PGconn *conn);
 </synopsis>
       </para>
+      
+      <para>
+       PQHost returns NULL when the connection is not established or
+       status of the connection is not <literal>CONNECTION_OK</literal>.
+       
+       when both <literal>host</literal> and <literal>hostaddr</literal>
+       parameters are specified in the connection string, the connection
+       <literal>host</literal> parameter is returned.
+      </para>
      </listitem>
     </varlistentry>
 
@@ -1714,8 +1723,9 @@ char *PQhost(const PGconn *conn);
 
      <listitem>
       <para>
-       Returns the port of the connection.
-
+       Returns the port of the connection or NULL (if the connection is not
+       established or status of the connection is not <literal>CONNECTION_OK</literal>).
+       
 <synopsis>
 char *PQport(const PGconn *conn);
 </synopsis>
diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
index 39c19998c2..628a663b30 100644
--- a/src/interfaces/libpq/fe-connect.c
+++ b/src/interfaces/libpq/fe-connect.c
@@ -6015,31 +6015,34 @@ PQpass(const PGconn *conn)
 char *
 PQhost(const PGconn *conn)
 {
-	if (!conn)
+	if (!conn ||
+		!conn->connhost ||
+		(conn->status != CONNECTION_OK))
 		return NULL;
-	if (conn->connhost != NULL &&
-		conn->connhost[conn->whichhost].type != CHT_HOST_ADDRESS)
+
+	if (conn->connhost[conn->whichhost].host != NULL &&
+		conn->connhost[conn->whichhost].host[0] != '\0')
 		return conn->connhost[conn->whichhost].host;
-	else if (conn->pghost != NULL && conn->pghost[0] != '\0')
-		return conn->pghost;
-	else
-	{
-#ifdef HAVE_UNIX_SOCKETS
-		return DEFAULT_PGSOCKET_DIR;
-#else
-		return DefaultHost;
-#endif
-	}
+	else if (conn->connhost[conn->whichhost].hostaddr != NULL &&
+			 conn->connhost[conn->whichhost].hostaddr[0] != '\0')
+		return conn->connhost[conn->whichhost].hostaddr;
+
+	/*
+	 * conn structure should have at least one "host" or "hostaddr" defined.
+	 * so the following code is not reachable.
+	 */
+	Assert(0);
 }
 
 char *
 PQport(const PGconn *conn)
 {
-	if (!conn)
+	if (!conn ||
+		!conn->connhost ||
+		(conn->status != CONNECTION_OK))
 		return NULL;
-	if (conn->connhost != NULL)
-		return conn->connhost[conn->whichhost].port;
-	return conn->pgport;
+
+	return conn->connhost[conn->whichhost].port;
 }
 
 char *
-- 
2.16.1.windows.4

