aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--contrib/postgres_fdw/connection.c57
-rw-r--r--contrib/postgres_fdw/expected/postgres_fdw.out16
-rw-r--r--contrib/postgres_fdw/postgres_fdw--1.1--1.2.sql3
-rw-r--r--contrib/postgres_fdw/sql/postgres_fdw.sql8
-rw-r--r--doc/src/sgml/postgres-fdw.sgml23
5 files changed, 81 insertions, 26 deletions
diff --git a/contrib/postgres_fdw/connection.c b/contrib/postgres_fdw/connection.c
index 12d1fec0e82..2e5303eac12 100644
--- a/contrib/postgres_fdw/connection.c
+++ b/contrib/postgres_fdw/connection.c
@@ -1997,8 +1997,8 @@ pgfdw_finish_abort_cleanup(List *pending_entries, List *cancel_requested,
/* Number of output arguments (columns) for various API versions */
#define POSTGRES_FDW_GET_CONNECTIONS_COLS_V1_1 2
-#define POSTGRES_FDW_GET_CONNECTIONS_COLS_V1_2 4
-#define POSTGRES_FDW_GET_CONNECTIONS_COLS 4 /* maximum of above */
+#define POSTGRES_FDW_GET_CONNECTIONS_COLS_V1_2 5
+#define POSTGRES_FDW_GET_CONNECTIONS_COLS 5 /* maximum of above */
/*
* Internal function used by postgres_fdw_get_connections variants.
@@ -2014,10 +2014,13 @@ pgfdw_finish_abort_cleanup(List *pending_entries, List *cancel_requested,
*
* For API version 1.2 and later, this function takes an input parameter
* to check a connection status and returns the following
- * additional values along with the two values from version 1.1:
+ * additional values along with the three values from version 1.1:
*
+ * - user_name - the local user name of the active connection. In case the
+ * user mapping is dropped but the connection is still active, then the
+ * user name will be NULL in the output.
* - used_in_xact - true if the connection is used in the current transaction.
- * - closed: true if the connection is closed.
+ * - closed - true if the connection is closed.
*
* No records are returned when there are no cached connections at all.
*/
@@ -2056,6 +2059,7 @@ postgres_fdw_get_connections_internal(FunctionCallInfo fcinfo,
ForeignServer *server;
Datum values[POSTGRES_FDW_GET_CONNECTIONS_COLS] = {0};
bool nulls[POSTGRES_FDW_GET_CONNECTIONS_COLS] = {0};
+ int i = 0;
/* We only look for open remote connections */
if (!entry->conn)
@@ -2100,28 +2104,61 @@ postgres_fdw_get_connections_internal(FunctionCallInfo fcinfo,
Assert(entry->conn && entry->xact_depth > 0 && entry->invalidated);
/* Show null, if no server name was found */
- nulls[0] = true;
+ nulls[i++] = true;
}
else
- values[0] = CStringGetTextDatum(server->servername);
+ values[i++] = CStringGetTextDatum(server->servername);
- values[1] = BoolGetDatum(!entry->invalidated);
+ if (api_version >= PGFDW_V1_2)
+ {
+ HeapTuple tp;
+
+ /* Use the system cache to obtain the user mapping */
+ tp = SearchSysCache1(USERMAPPINGOID, ObjectIdGetDatum(entry->key));
+
+ /*
+ * Just like in the foreign server case, user mappings can also be
+ * dropped in the current explicit transaction. Therefore, the
+ * similar check as in the server case is required.
+ */
+ if (!HeapTupleIsValid(tp))
+ {
+ /*
+ * If we reach here, this entry must have been invalidated in
+ * pgfdw_inval_callback, same as in the server case.
+ */
+ Assert(entry->conn && entry->xact_depth > 0 &&
+ entry->invalidated);
+
+ nulls[i++] = true;
+ }
+ else
+ {
+ Oid userid;
+
+ userid = ((Form_pg_user_mapping) GETSTRUCT(tp))->umuser;
+ values[i++] = CStringGetTextDatum(MappingUserName(userid));
+ ReleaseSysCache(tp);
+ }
+ }
+
+ values[i++] = BoolGetDatum(!entry->invalidated);
if (api_version >= PGFDW_V1_2)
{
bool check_conn = PG_GETARG_BOOL(0);
/* Is this connection used in the current transaction? */
- values[2] = BoolGetDatum(entry->xact_depth > 0);
+ values[i++] = BoolGetDatum(entry->xact_depth > 0);
/*
* If a connection status check is requested and supported, return
* whether the connection is closed. Otherwise, return NULL.
*/
if (check_conn && pgfdw_conn_checkable())
- values[3] = BoolGetDatum(pgfdw_conn_check(entry->conn) != 0);
+ values[i++] = BoolGetDatum(pgfdw_conn_check(entry->conn) != 0);
else
- nulls[3] = true;
+ nulls[i++] = true;
}
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 f3eb055e2c7..f2bcd6aa98c 100644
--- a/contrib/postgres_fdw/expected/postgres_fdw.out
+++ b/contrib/postgres_fdw/expected/postgres_fdw.out
@@ -10472,13 +10472,15 @@ NOTICE: drop cascades to 2 other objects
DETAIL: drop cascades to user mapping for public on server loopback3
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;
- server_name | valid | used_in_xact | closed
--------------+-------+--------------+--------
- loopback | f | t |
- | f | t |
+-- should be output as invalid connections. Also the server name and user name
+-- for loopback3 should be NULL because both server and user mapping were
+-- dropped.
+SELECT server_name, user_name = CURRENT_USER as "user_name = CURRENT_USER", valid, used_in_xact, closed
+FROM postgres_fdw_get_connections() ORDER BY 1;
+ server_name | user_name = CURRENT_USER | valid | used_in_xact | closed
+-------------+--------------------------+-------+--------------+--------
+ loopback | t | f | t |
+ | | f | t |
(2 rows)
-- The invalid connections get closed in pgfdw_xact_callback during commit.
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 0d406c6028a..81aad4fcdaa 100644
--- a/contrib/postgres_fdw/postgres_fdw--1.1--1.2.sql
+++ b/contrib/postgres_fdw/postgres_fdw--1.1--1.2.sql
@@ -11,7 +11,8 @@ DROP FUNCTION postgres_fdw_get_connections ();
CREATE FUNCTION postgres_fdw_get_connections (
IN check_conn boolean DEFAULT false, OUT server_name text,
- OUT valid boolean, OUT used_in_xact boolean, OUT closed boolean)
+ OUT user_name text, OUT valid boolean, OUT used_in_xact boolean,
+ OUT closed boolean)
RETURNS SETOF record
AS 'MODULE_PATHNAME', 'postgres_fdw_get_connections_1_2'
LANGUAGE C STRICT PARALLEL RESTRICTED;
diff --git a/contrib/postgres_fdw/sql/postgres_fdw.sql b/contrib/postgres_fdw/sql/postgres_fdw.sql
index 0734716ad90..372fe6dad15 100644
--- a/contrib/postgres_fdw/sql/postgres_fdw.sql
+++ b/contrib/postgres_fdw/sql/postgres_fdw.sql
@@ -3382,9 +3382,11 @@ SELECT server_name FROM postgres_fdw_get_connections() ORDER BY 1;
ALTER SERVER loopback OPTIONS (ADD use_remote_estimate 'off');
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;
+-- should be output as invalid connections. Also the server name and user name
+-- for loopback3 should be NULL because both server and user mapping were
+-- dropped.
+SELECT server_name, user_name = CURRENT_USER as "user_name = CURRENT_USER", valid, used_in_xact, closed
+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 468724e94ef..627bb5ab5cc 100644
--- a/doc/src/sgml/postgres-fdw.sgml
+++ b/doc/src/sgml/postgres-fdw.sgml
@@ -779,7 +779,8 @@ OPTIONS (ADD password_required 'false');
<varlistentry>
<term><function>postgres_fdw_get_connections(
IN check_conn boolean DEFAULT false, OUT server_name text,
- OUT valid boolean, OUT used_in_xact boolean, OUT closed boolean)
+ OUT user_name text, OUT valid boolean, OUT used_in_xact boolean,
+ OUT closed boolean)
returns setof record</function></term>
<listitem>
<para>
@@ -806,10 +807,12 @@ OPTIONS (ADD password_required 'false');
<para>
Example usage of the function:
<screen>
- server_name | valid | used_in_xact | closed
--------------+-------+--------------+--------
- loopback1 | t | t |
- loopback2 | f | t |
+postgres=# SELECT * FROM postgres_fdw_get_connections(true);
+ server_name | user_name | valid | used_in_xact | closed
+-------------+-----------+-------+--------------+--------
+ loopback1 | postgres | t | t | f
+ loopback2 | public | t | t | f
+ loopback3 | | f | t | f
</screen>
The output columns are described in
<xref linkend="postgres-fdw-get-connections-columns"/>.
@@ -837,6 +840,16 @@ OPTIONS (ADD password_required 'false');
</entry>
</row>
<row>
+ <entry><structfield>user_name</structfield></entry>
+ <entry><type>text</type></entry>
+ <entry>
+ Name of the local user mapped to the foreign server of this
+ connection, or <literal>public</literal> if a public mapping is used.
+ If the user mapping is dropped but the connection remains open
+ (i.e., marked as invalid), this will be <literal>NULL</literal>.
+ </entry>
+ </row>
+ <row>
<entry><structfield>valid</structfield></entry>
<entry><type>boolean</type></entry>
<entry>