From a4a6bc0b090f93772d88b17f02743ec87304f0f0 Mon Sep 17 00:00:00 2001
From: Hayato Kuroda <kuroda.hayato@fujitsu.com>
Date: Wed, 5 Apr 2023 06:10:51 +0000
Subject: [PATCH v40 3/3] Extend postgres_fdw_get_connections to return user
 name

---
 contrib/postgres_fdw/connection.c             | 10 ++++--
 .../postgres_fdw/expected/postgres_fdw.out    |  2 +-
 .../postgres_fdw/postgres_fdw--1.1--1.2.sql   |  8 +++++
 contrib/postgres_fdw/sql/postgres_fdw.sql     |  2 +-
 doc/src/sgml/postgres-fdw.sgml                | 32 +++++++++----------
 5 files changed, 34 insertions(+), 20 deletions(-)

diff --git a/contrib/postgres_fdw/connection.c b/contrib/postgres_fdw/connection.c
index ad1fd00289..39a0d72246 100644
--- a/contrib/postgres_fdw/connection.c
+++ b/contrib/postgres_fdw/connection.c
@@ -2058,7 +2058,7 @@ pgfdw_finish_abort_cleanup(List *pending_entries, List *cancel_requested,
 Datum
 postgres_fdw_get_connections(PG_FUNCTION_ARGS)
 {
-#define POSTGRES_FDW_GET_CONNECTIONS_COLS	2
+#define POSTGRES_FDW_GET_CONNECTIONS_COLS	3
 	ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
 	HASH_SEQ_STATUS scan;
 	ConnCacheEntry *entry;
@@ -2120,11 +2120,17 @@ postgres_fdw_get_connections(PG_FUNCTION_ARGS)
 
 			/* Show null, if no server name was found */
 			nulls[0] = true;
+			nulls[1] = true;
 		}
 		else
+		{
+			UserMapping *user = GetUserMappingFromOid(entry->key);
+
 			values[0] = CStringGetTextDatum(server->servername);
+			values[1] = CStringGetTextDatum(MappingUserName(user->userid));
+		}
 
-		values[1] = BoolGetDatum(!entry->invalidated);
+		values[2] = BoolGetDatum(!entry->invalidated);
 
 		tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc, values, nulls);
 	}
diff --git a/contrib/postgres_fdw/expected/postgres_fdw.out b/contrib/postgres_fdw/expected/postgres_fdw.out
index 566d37df60..7d4c2e5884 100644
--- a/contrib/postgres_fdw/expected/postgres_fdw.out
+++ b/contrib/postgres_fdw/expected/postgres_fdw.out
@@ -10349,7 +10349,7 @@ drop cascades to foreign table ft7
 -- List all the existing cached connections. loopback and loopback3
 -- should be output as invalid connections. Also the server name for
 -- loopback3 should be NULL because the server was dropped.
-SELECT * FROM postgres_fdw_get_connections() ORDER BY 1;
+SELECT server_name, valid FROM postgres_fdw_get_connections() ORDER BY 1;
  server_name | valid 
 -------------+-------
  loopback    | f
diff --git a/contrib/postgres_fdw/postgres_fdw--1.1--1.2.sql b/contrib/postgres_fdw/postgres_fdw--1.1--1.2.sql
index 78ee82cc74..8e6aa3e949 100644
--- a/contrib/postgres_fdw/postgres_fdw--1.1--1.2.sql
+++ b/contrib/postgres_fdw/postgres_fdw--1.1--1.2.sql
@@ -3,6 +3,14 @@
 -- complain if script is sourced in psql, rather than via ALTER EXTENSION
 \echo Use "ALTER EXTENSION postgres_fdw UPDATE TO '1.2'" to load this file. \quit
 
+DROP FUNCTION postgres_fdw_get_connections ();
+
+CREATE FUNCTION postgres_fdw_get_connections (OUT server_name text,
+    OUT user_name text, OUT valid boolean)
+RETURNS SETOF record
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT PARALLEL RESTRICTED;
+
 CREATE FUNCTION postgres_fdw_verify_connection (IN server_name text,
         IN user_name text)
 RETURNS bool
diff --git a/contrib/postgres_fdw/sql/postgres_fdw.sql b/contrib/postgres_fdw/sql/postgres_fdw.sql
index 7b3ae99511..d1bf46fd35 100644
--- a/contrib/postgres_fdw/sql/postgres_fdw.sql
+++ b/contrib/postgres_fdw/sql/postgres_fdw.sql
@@ -3326,7 +3326,7 @@ DROP SERVER loopback3 CASCADE;
 -- List all the existing cached connections. loopback and loopback3
 -- should be output as invalid connections. Also the server name for
 -- loopback3 should be NULL because the server was dropped.
-SELECT * FROM postgres_fdw_get_connections() ORDER BY 1;
+SELECT server_name, valid FROM postgres_fdw_get_connections() ORDER BY 1;
 -- The invalid connections get closed in pgfdw_xact_callback during commit.
 COMMIT;
 -- All cached connections were closed while committing above xact, so no
diff --git a/doc/src/sgml/postgres-fdw.sgml b/doc/src/sgml/postgres-fdw.sgml
index a01ad80c53..8cc32f09f4 100644
--- a/doc/src/sgml/postgres-fdw.sgml
+++ b/doc/src/sgml/postgres-fdw.sgml
@@ -777,27 +777,27 @@ OPTIONS (ADD password_required 'false');
 
   <variablelist>
    <varlistentry>
-    <term><function>postgres_fdw_get_connections(OUT server_name text, OUT valid boolean) returns setof record</function></term>
+    <term><function>postgres_fdw_get_connections(OUT server_name text, OUT user_name text, OUT valid boolean) returns setof record</function></term>
     <listitem>
      <para>
-      This function returns the foreign server names of all the open
-      connections that <filename>postgres_fdw</filename> established from
-      the local session to the foreign servers. It also returns whether
-      each connection is valid or not. <literal>false</literal> is returned
-      if the foreign server connection is used in the current local
-      transaction but its foreign server or user mapping is changed or
-      dropped (Note that server name of an invalid connection will be
-      <literal>NULL</literal> if the server is dropped),
-      and then such invalid connection will be closed at
-      the end of that transaction. <literal>true</literal> is returned
-      otherwise. If there are no open connections, no record is returned.
+      This function returns the foreign server names and user names of all the
+      open connections that <filename>postgres_fdw</filename> established from
+      the local session to the foreign servers. It also returns whether each
+      connection is valid or not. <literal>false</literal> is returned if the
+      foreign server connection is used in the current local transaction but
+      its foreign server or user mapping is changed or dropped (Note that
+      server name and user name of an invalid connection will be
+      <literal>NULL</literal> if the server is dropped), and then such invalid
+      connection will be closed at the end of that transaction.
+      <literal>true</literal> is returned otherwise. If there are no open
+      connections, no record is returned.
       Example usage of the function:
 <screen>
 postgres=# SELECT * FROM postgres_fdw_get_connections() ORDER BY 1;
- server_name | valid
--------------+-------
- loopback1   | t
- loopback2   | f
+ server_name | user_name | validvalid
+-------------+------------------------
+ loopback1   | postgres  | t
+ loopback2   |           | f
 </screen>
      </para>
     </listitem>
-- 
2.27.0

