diff options
-rw-r--r-- | contrib/postgres_fdw/connection.c | 57 | ||||
-rw-r--r-- | contrib/postgres_fdw/expected/postgres_fdw.out | 16 | ||||
-rw-r--r-- | contrib/postgres_fdw/postgres_fdw--1.1--1.2.sql | 3 | ||||
-rw-r--r-- | contrib/postgres_fdw/sql/postgres_fdw.sql | 8 | ||||
-rw-r--r-- | doc/src/sgml/postgres-fdw.sgml | 23 |
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> |