From 78f4a84f095b623bb238f3595d24b4a0fe366b7c Mon Sep 17 00:00:00 2001
From: Hari Babu <kommi.haribabu@gmail.com>
Date: Mon, 8 Jan 2018 12:03:46 +1100
Subject: [PATCH 1/2] Addition of new libpq API PQeffectiveconninfo

PQeffectiveConninfo is a new API which is similar like
PQconninfo, but it provides the effectively used connection
options in the current connection. As of now the connection
options host, hostaddr and port number can change according
to the connection and rest of the parameters are same.
---
 doc/src/sgml/libpq.sgml           | 25 +++++++++++++++++
 src/interfaces/libpq/exports.txt  |  1 +
 src/interfaces/libpq/fe-connect.c | 56 +++++++++++++++++++++++++++++++++++++++
 src/interfaces/libpq/libpq-fe.h   |  3 +++
 4 files changed, 85 insertions(+)

diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml
index 4e4645136c..c85094fa98 100644
--- a/doc/src/sgml/libpq.sgml
+++ b/doc/src/sgml/libpq.sgml
@@ -541,6 +541,31 @@ PQconninfoOption *PQconninfo(PGconn *conn);
      </listitem>
     </varlistentry>
 
+    <varlistentry id="libpq-pqeffectiveconninfo">
+     <term><function>PQeffectiveConninfo</function><indexterm><primary>PQeffectiveConninfo</primary></indexterm></term>
+     <listitem>
+      <para>
+       Returns the effective connection options used by a live connection.
+<synopsis>
+PQconninfoOption *PQeffectiveConninfo(PGconn *conn);
+</synopsis>
+      </para>
+
+      <para>
+       Returns a connection options array similar like <function>PQconninfo</function>.
+       But this function returns the effective connection options and the
+       values that were used to connect to the server. As of now the connection
+       options host name, host IP address and port numbers can change according
+       to the effective connection to the server. The return value points to an
+       array of <structname>PQconninfoOption</structname> structures, which ends
+       with an entry having a null <structfield>keyword</structfield> pointer.
+       All notes above for <function>PQconndefaults</function> also apply to the
+       result of <function>PQeffectiveConninfo</function>.
+      </para>
+
+     </listitem>
+    </varlistentry>
+
 
     <varlistentry id="libpq-pqconninfoparse">
      <term><function>PQconninfoParse</function><indexterm><primary>PQconninfoParse</primary></indexterm></term>
diff --git a/src/interfaces/libpq/exports.txt b/src/interfaces/libpq/exports.txt
index d6a38d0df8..1ca9029bdd 100644
--- a/src/interfaces/libpq/exports.txt
+++ b/src/interfaces/libpq/exports.txt
@@ -172,3 +172,4 @@ PQsslAttribute            169
 PQsetErrorContextVisibility 170
 PQresultVerboseErrorMessage 171
 PQencryptPasswordConn     172
+PQeffectiveConninfo       173
diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
index 8d543334ae..a1dd8040d2 100644
--- a/src/interfaces/libpq/fe-connect.c
+++ b/src/interfaces/libpq/fe-connect.c
@@ -5960,6 +5960,62 @@ PQconninfo(PGconn *conn)
 	return connOptions;
 }
 
+/*
+ * Return the effective connection options used for the connection
+ *
+ * This function is similar like PQconninfo, but it provides the
+ * effectively used connection options in the current connection.
+ *
+ * As of now the connection options host, hostaddr and port number
+ * can change according to the connection and rest of the parameters
+ * are same.
+ */
+PQconninfoOption *
+PQeffectiveConninfo(PGconn *conn)
+{
+	PQExpBufferData errorBuf;
+	PQconninfoOption *connOptions;
+
+	if (conn == NULL)
+		return NULL;
+
+	/* We don't actually report any errors here, but callees want a buffer */
+	initPQExpBuffer(&errorBuf);
+	if (PQExpBufferDataBroken(errorBuf))
+		return NULL;			/* out of memory already :-( */
+
+	connOptions = conninfo_init(&errorBuf);
+
+	if (connOptions != NULL)
+	{
+		const internalPQconninfoOption *option;
+
+		for (option = PQconninfoOptions; option->keyword; option++)
+		{
+			char	  **connmember;
+
+			if (option->connofs < 0)
+				continue;
+
+			if (strcmp(option->keyword, "host") == 0)
+				connmember = &conn->connhost[conn->whichhost].host;
+			else if (strcmp(option->keyword, "hostaddr") == 0)
+				connmember = &conn->connhost[conn->whichhost].hostaddr;
+			else if (strcmp(option->keyword, "port") == 0)
+				connmember = &conn->connhost[conn->whichhost].port;
+			else
+				connmember = (char **) ((char *) conn + option->connofs);
+
+			if (*connmember)
+				conninfo_storeval(connOptions, option->keyword, *connmember,
+								  &errorBuf, true, false);
+		}
+	}
+
+	termPQExpBuffer(&errorBuf);
+
+	return connOptions;
+}
 
 void
 PQconninfoFree(PQconninfoOption *connOptions)
diff --git a/src/interfaces/libpq/libpq-fe.h b/src/interfaces/libpq/libpq-fe.h
index ed9c806861..1a500dc2a3 100644
--- a/src/interfaces/libpq/libpq-fe.h
+++ b/src/interfaces/libpq/libpq-fe.h
@@ -281,6 +281,9 @@ extern PQconninfoOption *PQconninfoParse(const char *conninfo, char **errmsg);
 /* return the connection options used by a live connection */
 extern PQconninfoOption *PQconninfo(PGconn *conn);
 
+/* return the effective connection options used by a live connection */
+extern PQconninfoOption *PQeffectiveConninfo(PGconn *conn);
+
 /* free the data structure returned by PQconndefaults() or PQconninfoParse() */
 extern void PQconninfoFree(PQconninfoOption *connOptions);
 
-- 
2.15.0.windows.1

