mirror of
https://github.com/postgres/postgres.git
synced 2025-06-11 20:28:21 +03:00
postgres_fdw: Allow application_name of remote connection to be set via GUC.
This commit adds postgres_fdw.application_name GUC which specifies a value for application_name configuration parameter used when postgres_fdw establishes a connection to a foreign server. This GUC setting always overrides application_name option of the foreign server object. This GUC is useful when we want to specify our own application_name per remote connection. Previously application_name of a remote connection could be set basically only via options of a server object. But which meant that every session connecting to the same foreign server basically should use the same application_name. Also if we want to change the setting, we had to execute "ALTER SERVER ... OPTIONS ..." command. It was inconvenient. Author: Hayato Kuroda Reviewed-by: Masahiro Ikeda, Fujii Masao Discussion: https://postgr.es/m/TYCPR01MB5870D1E8B949DAF6D3B84E02F5F29@TYCPR01MB5870.jpnprd01.prod.outlook.com
This commit is contained in:
@ -353,10 +353,11 @@ connect_pg_server(ForeignServer *server, UserMapping *user)
|
|||||||
/*
|
/*
|
||||||
* Construct connection params from generic options of ForeignServer
|
* Construct connection params from generic options of ForeignServer
|
||||||
* and UserMapping. (Some of them might not be libpq options, in
|
* and UserMapping. (Some of them might not be libpq options, in
|
||||||
* which case we'll just waste a few array slots.) Add 3 extra slots
|
* which case we'll just waste a few array slots.) Add 4 extra slots
|
||||||
* for fallback_application_name, client_encoding, end marker.
|
* for application_name, fallback_application_name, client_encoding,
|
||||||
|
* end marker.
|
||||||
*/
|
*/
|
||||||
n = list_length(server->options) + list_length(user->options) + 3;
|
n = list_length(server->options) + list_length(user->options) + 4;
|
||||||
keywords = (const char **) palloc(n * sizeof(char *));
|
keywords = (const char **) palloc(n * sizeof(char *));
|
||||||
values = (const char **) palloc(n * sizeof(char *));
|
values = (const char **) palloc(n * sizeof(char *));
|
||||||
|
|
||||||
@ -366,7 +367,23 @@ connect_pg_server(ForeignServer *server, UserMapping *user)
|
|||||||
n += ExtractConnectionOptions(user->options,
|
n += ExtractConnectionOptions(user->options,
|
||||||
keywords + n, values + n);
|
keywords + n, values + n);
|
||||||
|
|
||||||
/* Use "postgres_fdw" as fallback_application_name. */
|
/*
|
||||||
|
* Use pgfdw_application_name as application_name if set.
|
||||||
|
*
|
||||||
|
* PQconnectdbParams() processes the parameter arrays from start to
|
||||||
|
* end. If any key word is repeated, the last value is used. Therefore
|
||||||
|
* note that pgfdw_application_name must be added to the arrays after
|
||||||
|
* options of ForeignServer are, so that it can override
|
||||||
|
* application_name set in ForeignServer.
|
||||||
|
*/
|
||||||
|
if (pgfdw_application_name && *pgfdw_application_name != '\0')
|
||||||
|
{
|
||||||
|
keywords[n] = "application_name";
|
||||||
|
values[n] = pgfdw_application_name;
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Use "postgres_fdw" as fallback_application_name */
|
||||||
keywords[n] = "fallback_application_name";
|
keywords[n] = "fallback_application_name";
|
||||||
values[n] = "postgres_fdw";
|
values[n] = "postgres_fdw";
|
||||||
n++;
|
n++;
|
||||||
|
@ -10761,3 +10761,82 @@ ERROR: invalid value for integer option "fetch_size": 100$%$#$#
|
|||||||
CREATE FOREIGN TABLE inv_bsz (c1 int )
|
CREATE FOREIGN TABLE inv_bsz (c1 int )
|
||||||
SERVER loopback OPTIONS (batch_size '100$%$#$#');
|
SERVER loopback OPTIONS (batch_size '100$%$#$#');
|
||||||
ERROR: invalid value for integer option "batch_size": 100$%$#$#
|
ERROR: invalid value for integer option "batch_size": 100$%$#$#
|
||||||
|
-- ===================================================================
|
||||||
|
-- test postgres_fdw.application_name GUC
|
||||||
|
-- ===================================================================
|
||||||
|
-- Turn debug_discard_caches off for this test to make that
|
||||||
|
-- the remote connection is alive when checking its application_name.
|
||||||
|
-- For each test, close all the existing cached connections manually and
|
||||||
|
-- establish connection with new setting of application_name.
|
||||||
|
SET debug_discard_caches = 0;
|
||||||
|
-- If appname is set as GUC but not as options of server object,
|
||||||
|
-- the GUC setting is used as application_name of remote connection.
|
||||||
|
SET postgres_fdw.application_name TO 'fdw_guc_appname';
|
||||||
|
SELECT 1 FROM postgres_fdw_disconnect_all();
|
||||||
|
?column?
|
||||||
|
----------
|
||||||
|
1
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT 1 FROM ft6 LIMIT 1;
|
||||||
|
?column?
|
||||||
|
----------
|
||||||
|
1
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT application_name FROM pg_stat_activity
|
||||||
|
WHERE application_name IN ('loopback2', 'fdw_guc_appname');
|
||||||
|
application_name
|
||||||
|
------------------
|
||||||
|
fdw_guc_appname
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- If appname is set as options of server object but not as GUC,
|
||||||
|
-- appname of server object is used.
|
||||||
|
RESET postgres_fdw.application_name;
|
||||||
|
ALTER SERVER loopback2 OPTIONS (ADD application_name 'loopback2');
|
||||||
|
SELECT 1 FROM postgres_fdw_disconnect_all();
|
||||||
|
?column?
|
||||||
|
----------
|
||||||
|
1
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT 1 FROM ft6 LIMIT 1;
|
||||||
|
?column?
|
||||||
|
----------
|
||||||
|
1
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT application_name FROM pg_stat_activity
|
||||||
|
WHERE application_name IN ('loopback2', 'fdw_guc_appname');
|
||||||
|
application_name
|
||||||
|
------------------
|
||||||
|
loopback2
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- If appname is set both as GUC and as options of server object,
|
||||||
|
-- the GUC setting overrides appname of server object and is used.
|
||||||
|
SET postgres_fdw.application_name TO 'fdw_guc_appname';
|
||||||
|
SELECT 1 FROM postgres_fdw_disconnect_all();
|
||||||
|
?column?
|
||||||
|
----------
|
||||||
|
1
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT 1 FROM ft6 LIMIT 1;
|
||||||
|
?column?
|
||||||
|
----------
|
||||||
|
1
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT application_name FROM pg_stat_activity
|
||||||
|
WHERE application_name IN ('loopback2', 'fdw_guc_appname');
|
||||||
|
application_name
|
||||||
|
------------------
|
||||||
|
fdw_guc_appname
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
--Clean up
|
||||||
|
ALTER SERVER loopback2 OPTIONS (DROP application_name);
|
||||||
|
RESET postgres_fdw.application_name;
|
||||||
|
RESET debug_discard_caches;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*-------------------------------------------------------------------------
|
/*-------------------------------------------------------------------------
|
||||||
*
|
*
|
||||||
* option.c
|
* option.c
|
||||||
* FDW option handling for postgres_fdw
|
* FDW and GUC option handling for postgres_fdw
|
||||||
*
|
*
|
||||||
* Portions Copyright (c) 2012-2021, PostgreSQL Global Development Group
|
* Portions Copyright (c) 2012-2021, PostgreSQL Global Development Group
|
||||||
*
|
*
|
||||||
@ -45,6 +45,13 @@ static PgFdwOption *postgres_fdw_options;
|
|||||||
*/
|
*/
|
||||||
static PQconninfoOption *libpq_options;
|
static PQconninfoOption *libpq_options;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* GUC parameters
|
||||||
|
*/
|
||||||
|
char *pgfdw_application_name = NULL;
|
||||||
|
|
||||||
|
void _PG_init(void);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Helper functions
|
* Helper functions
|
||||||
*/
|
*/
|
||||||
@ -435,3 +442,29 @@ ExtractExtensionList(const char *extensionsString, bool warnOnMissing)
|
|||||||
list_free(extlist);
|
list_free(extlist);
|
||||||
return extensionOids;
|
return extensionOids;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Module load callback
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
_PG_init(void)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Unlike application_name GUC, don't set GUC_IS_NAME flag nor check_hook
|
||||||
|
* to allow postgres_fdw.application_name to be any string more than
|
||||||
|
* NAMEDATALEN characters and to include non-ASCII characters. Instead,
|
||||||
|
* remote server truncates application_name of remote connection to less
|
||||||
|
* than NAMEDATALEN and replaces any non-ASCII characters in it with a '?'
|
||||||
|
* character.
|
||||||
|
*/
|
||||||
|
DefineCustomStringVariable("postgres_fdw.application_name",
|
||||||
|
"Sets the application name to be used on the remote server.",
|
||||||
|
NULL,
|
||||||
|
&pgfdw_application_name,
|
||||||
|
NULL,
|
||||||
|
PGC_USERSET,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
@ -158,6 +158,7 @@ extern int ExtractConnectionOptions(List *defelems,
|
|||||||
const char **values);
|
const char **values);
|
||||||
extern List *ExtractExtensionList(const char *extensionsString,
|
extern List *ExtractExtensionList(const char *extensionsString,
|
||||||
bool warnOnMissing);
|
bool warnOnMissing);
|
||||||
|
extern char *pgfdw_application_name;
|
||||||
|
|
||||||
/* in deparse.c */
|
/* in deparse.c */
|
||||||
extern void classifyConditions(PlannerInfo *root,
|
extern void classifyConditions(PlannerInfo *root,
|
||||||
|
@ -3422,3 +3422,42 @@ CREATE FOREIGN TABLE inv_fsz (c1 int )
|
|||||||
-- Invalid batch_size option
|
-- Invalid batch_size option
|
||||||
CREATE FOREIGN TABLE inv_bsz (c1 int )
|
CREATE FOREIGN TABLE inv_bsz (c1 int )
|
||||||
SERVER loopback OPTIONS (batch_size '100$%$#$#');
|
SERVER loopback OPTIONS (batch_size '100$%$#$#');
|
||||||
|
|
||||||
|
-- ===================================================================
|
||||||
|
-- test postgres_fdw.application_name GUC
|
||||||
|
-- ===================================================================
|
||||||
|
-- Turn debug_discard_caches off for this test to make that
|
||||||
|
-- the remote connection is alive when checking its application_name.
|
||||||
|
-- For each test, close all the existing cached connections manually and
|
||||||
|
-- establish connection with new setting of application_name.
|
||||||
|
SET debug_discard_caches = 0;
|
||||||
|
|
||||||
|
-- If appname is set as GUC but not as options of server object,
|
||||||
|
-- the GUC setting is used as application_name of remote connection.
|
||||||
|
SET postgres_fdw.application_name TO 'fdw_guc_appname';
|
||||||
|
SELECT 1 FROM postgres_fdw_disconnect_all();
|
||||||
|
SELECT 1 FROM ft6 LIMIT 1;
|
||||||
|
SELECT application_name FROM pg_stat_activity
|
||||||
|
WHERE application_name IN ('loopback2', 'fdw_guc_appname');
|
||||||
|
|
||||||
|
-- If appname is set as options of server object but not as GUC,
|
||||||
|
-- appname of server object is used.
|
||||||
|
RESET postgres_fdw.application_name;
|
||||||
|
ALTER SERVER loopback2 OPTIONS (ADD application_name 'loopback2');
|
||||||
|
SELECT 1 FROM postgres_fdw_disconnect_all();
|
||||||
|
SELECT 1 FROM ft6 LIMIT 1;
|
||||||
|
SELECT application_name FROM pg_stat_activity
|
||||||
|
WHERE application_name IN ('loopback2', 'fdw_guc_appname');
|
||||||
|
|
||||||
|
-- If appname is set both as GUC and as options of server object,
|
||||||
|
-- the GUC setting overrides appname of server object and is used.
|
||||||
|
SET postgres_fdw.application_name TO 'fdw_guc_appname';
|
||||||
|
SELECT 1 FROM postgres_fdw_disconnect_all();
|
||||||
|
SELECT 1 FROM ft6 LIMIT 1;
|
||||||
|
SELECT application_name FROM pg_stat_activity
|
||||||
|
WHERE application_name IN ('loopback2', 'fdw_guc_appname');
|
||||||
|
|
||||||
|
--Clean up
|
||||||
|
ALTER SERVER loopback2 OPTIONS (DROP application_name);
|
||||||
|
RESET postgres_fdw.application_name;
|
||||||
|
RESET debug_discard_caches;
|
||||||
|
@ -905,6 +905,31 @@ postgres=# SELECT postgres_fdw_disconnect_all();
|
|||||||
</para>
|
</para>
|
||||||
</sect2>
|
</sect2>
|
||||||
|
|
||||||
|
<sect2>
|
||||||
|
<title>Configuration Parameters</title>
|
||||||
|
|
||||||
|
<variablelist>
|
||||||
|
<varlistentry>
|
||||||
|
<term>
|
||||||
|
<varname>postgres_fdw.application_name</varname> (<type>string</type>)
|
||||||
|
<indexterm>
|
||||||
|
<primary><varname>postgres_fdw.application_name</varname> configuration parameter</primary>
|
||||||
|
</indexterm>
|
||||||
|
</term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Specifies a value for <xref linkend="guc-application-name"/>
|
||||||
|
configuration parameter used when <filename>postgres_fdw</filename>
|
||||||
|
establishes a connection to a foreign server. This overrides
|
||||||
|
<varname>application_name</varname> option of the server object.
|
||||||
|
Note that change of this parameter doesn't affect any existing
|
||||||
|
connections until they are re-established.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
</variablelist>
|
||||||
|
</sect2>
|
||||||
|
|
||||||
<sect2>
|
<sect2>
|
||||||
<title>Examples</title>
|
<title>Examples</title>
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user