Skip to content

Commit 449ab63

Browse files
committed
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
1 parent 4c34788 commit 449ab63

File tree

6 files changed

+199
-5
lines changed

6 files changed

+199
-5
lines changed

contrib/postgres_fdw/connection.c

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -353,10 +353,11 @@ connect_pg_server(ForeignServer *server, UserMapping *user)
353353
/*
354354
* Construct connection params from generic options of ForeignServer
355355
* and UserMapping. (Some of them might not be libpq options, in
356-
* which case we'll just waste a few array slots.) Add 3 extra slots
357-
* for fallback_application_name, client_encoding, end marker.
356+
* which case we'll just waste a few array slots.) Add 4 extra slots
357+
* for application_name, fallback_application_name, client_encoding,
358+
* end marker.
358359
*/
359-
n = list_length(server->options) + list_length(user->options) + 3;
360+
n = list_length(server->options) + list_length(user->options) + 4;
360361
keywords = (const char **) palloc(n * sizeof(char *));
361362
values = (const char **) palloc(n * sizeof(char *));
362363

@@ -366,7 +367,23 @@ connect_pg_server(ForeignServer *server, UserMapping *user)
366367
n += ExtractConnectionOptions(user->options,
367368
keywords + n, values + n);
368369

369-
/* Use "postgres_fdw" as fallback_application_name. */
370+
/*
371+
* Use pgfdw_application_name as application_name if set.
372+
*
373+
* PQconnectdbParams() processes the parameter arrays from start to
374+
* end. If any key word is repeated, the last value is used. Therefore
375+
* note that pgfdw_application_name must be added to the arrays after
376+
* options of ForeignServer are, so that it can override
377+
* application_name set in ForeignServer.
378+
*/
379+
if (pgfdw_application_name && *pgfdw_application_name != '\0')
380+
{
381+
keywords[n] = "application_name";
382+
values[n] = pgfdw_application_name;
383+
n++;
384+
}
385+
386+
/* Use "postgres_fdw" as fallback_application_name */
370387
keywords[n] = "fallback_application_name";
371388
values[n] = "postgres_fdw";
372389
n++;

contrib/postgres_fdw/expected/postgres_fdw.out

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10761,3 +10761,82 @@ ERROR: invalid value for integer option "fetch_size": 100$%$#$#
1076110761
CREATE FOREIGN TABLE inv_bsz (c1 int )
1076210762
SERVER loopback OPTIONS (batch_size '100$%$#$#');
1076310763
ERROR: invalid value for integer option "batch_size": 100$%$#$#
10764+
-- ===================================================================
10765+
-- test postgres_fdw.application_name GUC
10766+
-- ===================================================================
10767+
-- Turn debug_discard_caches off for this test to make that
10768+
-- the remote connection is alive when checking its application_name.
10769+
-- For each test, close all the existing cached connections manually and
10770+
-- establish connection with new setting of application_name.
10771+
SET debug_discard_caches = 0;
10772+
-- If appname is set as GUC but not as options of server object,
10773+
-- the GUC setting is used as application_name of remote connection.
10774+
SET postgres_fdw.application_name TO 'fdw_guc_appname';
10775+
SELECT 1 FROM postgres_fdw_disconnect_all();
10776+
?column?
10777+
----------
10778+
1
10779+
(1 row)
10780+
10781+
SELECT 1 FROM ft6 LIMIT 1;
10782+
?column?
10783+
----------
10784+
1
10785+
(1 row)
10786+
10787+
SELECT application_name FROM pg_stat_activity
10788+
WHERE application_name IN ('loopback2', 'fdw_guc_appname');
10789+
application_name
10790+
------------------
10791+
fdw_guc_appname
10792+
(1 row)
10793+
10794+
-- If appname is set as options of server object but not as GUC,
10795+
-- appname of server object is used.
10796+
RESET postgres_fdw.application_name;
10797+
ALTER SERVER loopback2 OPTIONS (ADD application_name 'loopback2');
10798+
SELECT 1 FROM postgres_fdw_disconnect_all();
10799+
?column?
10800+
----------
10801+
1
10802+
(1 row)
10803+
10804+
SELECT 1 FROM ft6 LIMIT 1;
10805+
?column?
10806+
----------
10807+
1
10808+
(1 row)
10809+
10810+
SELECT application_name FROM pg_stat_activity
10811+
WHERE application_name IN ('loopback2', 'fdw_guc_appname');
10812+
application_name
10813+
------------------
10814+
loopback2
10815+
(1 row)
10816+
10817+
-- If appname is set both as GUC and as options of server object,
10818+
-- the GUC setting overrides appname of server object and is used.
10819+
SET postgres_fdw.application_name TO 'fdw_guc_appname';
10820+
SELECT 1 FROM postgres_fdw_disconnect_all();
10821+
?column?
10822+
----------
10823+
1
10824+
(1 row)
10825+
10826+
SELECT 1 FROM ft6 LIMIT 1;
10827+
?column?
10828+
----------
10829+
1
10830+
(1 row)
10831+
10832+
SELECT application_name FROM pg_stat_activity
10833+
WHERE application_name IN ('loopback2', 'fdw_guc_appname');
10834+
application_name
10835+
------------------
10836+
fdw_guc_appname
10837+
(1 row)
10838+
10839+
--Clean up
10840+
ALTER SERVER loopback2 OPTIONS (DROP application_name);
10841+
RESET postgres_fdw.application_name;
10842+
RESET debug_discard_caches;

contrib/postgres_fdw/option.c

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*-------------------------------------------------------------------------
22
*
33
* option.c
4-
* FDW option handling for postgres_fdw
4+
* FDW and GUC option handling for postgres_fdw
55
*
66
* Portions Copyright (c) 2012-2021, PostgreSQL Global Development Group
77
*
@@ -45,6 +45,13 @@ static PgFdwOption *postgres_fdw_options;
4545
*/
4646
static PQconninfoOption *libpq_options;
4747

48+
/*
49+
* GUC parameters
50+
*/
51+
char *pgfdw_application_name = NULL;
52+
53+
void _PG_init(void);
54+
4855
/*
4956
* Helper functions
5057
*/
@@ -435,3 +442,29 @@ ExtractExtensionList(const char *extensionsString, bool warnOnMissing)
435442
list_free(extlist);
436443
return extensionOids;
437444
}
445+
446+
/*
447+
* Module load callback
448+
*/
449+
void
450+
_PG_init(void)
451+
{
452+
/*
453+
* Unlike application_name GUC, don't set GUC_IS_NAME flag nor check_hook
454+
* to allow postgres_fdw.application_name to be any string more than
455+
* NAMEDATALEN characters and to include non-ASCII characters. Instead,
456+
* remote server truncates application_name of remote connection to less
457+
* than NAMEDATALEN and replaces any non-ASCII characters in it with a '?'
458+
* character.
459+
*/
460+
DefineCustomStringVariable("postgres_fdw.application_name",
461+
"Sets the application name to be used on the remote server.",
462+
NULL,
463+
&pgfdw_application_name,
464+
NULL,
465+
PGC_USERSET,
466+
0,
467+
NULL,
468+
NULL,
469+
NULL);
470+
}

contrib/postgres_fdw/postgres_fdw.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@ extern int ExtractConnectionOptions(List *defelems,
158158
const char **values);
159159
extern List *ExtractExtensionList(const char *extensionsString,
160160
bool warnOnMissing);
161+
extern char *pgfdw_application_name;
161162

162163
/* in deparse.c */
163164
extern void classifyConditions(PlannerInfo *root,

contrib/postgres_fdw/sql/postgres_fdw.sql

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3422,3 +3422,42 @@ CREATE FOREIGN TABLE inv_fsz (c1 int )
34223422
-- Invalid batch_size option
34233423
CREATE FOREIGN TABLE inv_bsz (c1 int )
34243424
SERVER loopback OPTIONS (batch_size '100$%$#$#');
3425+
3426+
-- ===================================================================
3427+
-- test postgres_fdw.application_name GUC
3428+
-- ===================================================================
3429+
-- Turn debug_discard_caches off for this test to make that
3430+
-- the remote connection is alive when checking its application_name.
3431+
-- For each test, close all the existing cached connections manually and
3432+
-- establish connection with new setting of application_name.
3433+
SET debug_discard_caches = 0;
3434+
3435+
-- If appname is set as GUC but not as options of server object,
3436+
-- the GUC setting is used as application_name of remote connection.
3437+
SET postgres_fdw.application_name TO 'fdw_guc_appname';
3438+
SELECT 1 FROM postgres_fdw_disconnect_all();
3439+
SELECT 1 FROM ft6 LIMIT 1;
3440+
SELECT application_name FROM pg_stat_activity
3441+
WHERE application_name IN ('loopback2', 'fdw_guc_appname');
3442+
3443+
-- If appname is set as options of server object but not as GUC,
3444+
-- appname of server object is used.
3445+
RESET postgres_fdw.application_name;
3446+
ALTER SERVER loopback2 OPTIONS (ADD application_name 'loopback2');
3447+
SELECT 1 FROM postgres_fdw_disconnect_all();
3448+
SELECT 1 FROM ft6 LIMIT 1;
3449+
SELECT application_name FROM pg_stat_activity
3450+
WHERE application_name IN ('loopback2', 'fdw_guc_appname');
3451+
3452+
-- If appname is set both as GUC and as options of server object,
3453+
-- the GUC setting overrides appname of server object and is used.
3454+
SET postgres_fdw.application_name TO 'fdw_guc_appname';
3455+
SELECT 1 FROM postgres_fdw_disconnect_all();
3456+
SELECT 1 FROM ft6 LIMIT 1;
3457+
SELECT application_name FROM pg_stat_activity
3458+
WHERE application_name IN ('loopback2', 'fdw_guc_appname');
3459+
3460+
--Clean up
3461+
ALTER SERVER loopback2 OPTIONS (DROP application_name);
3462+
RESET postgres_fdw.application_name;
3463+
RESET debug_discard_caches;

doc/src/sgml/postgres-fdw.sgml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -905,6 +905,31 @@ postgres=# SELECT postgres_fdw_disconnect_all();
905905
</para>
906906
</sect2>
907907

908+
<sect2>
909+
<title>Configuration Parameters</title>
910+
911+
<variablelist>
912+
<varlistentry>
913+
<term>
914+
<varname>postgres_fdw.application_name</varname> (<type>string</type>)
915+
<indexterm>
916+
<primary><varname>postgres_fdw.application_name</varname> configuration parameter</primary>
917+
</indexterm>
918+
</term>
919+
<listitem>
920+
<para>
921+
Specifies a value for <xref linkend="guc-application-name"/>
922+
configuration parameter used when <filename>postgres_fdw</filename>
923+
establishes a connection to a foreign server. This overrides
924+
<varname>application_name</varname> option of the server object.
925+
Note that change of this parameter doesn't affect any existing
926+
connections until they are re-established.
927+
</para>
928+
</listitem>
929+
</varlistentry>
930+
</variablelist>
931+
</sect2>
932+
908933
<sect2>
909934
<title>Examples</title>
910935

0 commit comments

Comments
 (0)