Skip to content

Commit

Permalink
Allow dbname in pg_basebackup/pg_receivewal connstring
Browse files Browse the repository at this point in the history
As physical replication work at the cluster level and not database
level, any dbname in the connection string is ignored. Proxies and
middleware used in connecting to the cluster might however need to
know the dbname in order to make the correct routing decision for
the connection.

With this the startup packet will include the dbname parameter.

Author: Jelte Fennema-Nio <[email protected]>
Reviewed-by: Tristen Raab <[email protected]>
Reviewed-by: Jim Jones <[email protected]>
Discussion: https://postgr.es/m/CAGECzQTw-dZkVT_RELRzfWRzY714-VaTjoBATYfZq93R8C-auA@mail.gmail.com
  • Loading branch information
danielgustafsson committed Sep 21, 2023
1 parent c621467 commit cca97ce
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 14 deletions.
5 changes: 4 additions & 1 deletion doc/src/sgml/ref/pg_basebackup.sgml
Original file line number Diff line number Diff line change
Expand Up @@ -778,7 +778,10 @@ PostgreSQL documentation
The option is called <literal>--dbname</literal> for consistency with other
client applications, but because <application>pg_basebackup</application>
doesn't connect to any particular database in the cluster, any database
name in the connection string will be ignored.
name in the connection string will be ignored
by <productname>PostgreSQL</productname>. Middleware, or proxies, used in
connecting to <productname>PostgreSQL</productname> might however
utilize the value.
</para>
</listitem>
</varlistentry>
Expand Down
7 changes: 5 additions & 2 deletions doc/src/sgml/ref/pg_receivewal.sgml
Original file line number Diff line number Diff line change
Expand Up @@ -316,8 +316,11 @@ PostgreSQL documentation
<para>
The option is called <literal>--dbname</literal> for consistency with other
client applications, but because <application>pg_receivewal</application>
doesn't connect to any particular database in the cluster, database
name in the connection string will be ignored.
doesn't connect to any particular database in the cluster, any database
name in the connection string will be ignored by
<productname>PostgreSQL</productname>. Middleware, or proxies, used in
connecting to <productname>PostgreSQL</productname> might however
utilize the value.
</para>
</listitem>
</varlistentry>
Expand Down
29 changes: 18 additions & 11 deletions src/bin/pg_basebackup/streamutil.c
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,6 @@ GetConnection(void)
/*
* Merge the connection info inputs given in form of connection string,
* options and default values (dbname=replication, replication=true, etc.)
* Explicitly discard any dbname value in the connection string;
* otherwise, PQconnectdbParams() would interpret that value as being
* itself a connection string.
*/
i = 0;
if (connection_string)
Expand All @@ -92,18 +89,24 @@ GetConnection(void)

for (conn_opt = conn_opts; conn_opt->keyword != NULL; conn_opt++)
{
if (conn_opt->val != NULL && conn_opt->val[0] != '\0' &&
strcmp(conn_opt->keyword, "dbname") != 0)
if (conn_opt->val != NULL && conn_opt->val[0] != '\0')
argcount++;
}

keywords = pg_malloc0((argcount + 1) * sizeof(*keywords));
values = pg_malloc0((argcount + 1) * sizeof(*values));

/*
* Set dbname here already, so it can be overridden by a dbname in the
* connection string.
*/
keywords[i] = "dbname";
values[i] = "replication";
i++;

for (conn_opt = conn_opts; conn_opt->keyword != NULL; conn_opt++)
{
if (conn_opt->val != NULL && conn_opt->val[0] != '\0' &&
strcmp(conn_opt->keyword, "dbname") != 0)
if (conn_opt->val != NULL && conn_opt->val[0] != '\0')
{
keywords[i] = conn_opt->keyword;
values[i] = conn_opt->val;
Expand All @@ -115,11 +118,11 @@ GetConnection(void)
{
keywords = pg_malloc0((argcount + 1) * sizeof(*keywords));
values = pg_malloc0((argcount + 1) * sizeof(*values));
keywords[i] = "dbname";
values[i] = dbname;
i++;
}

keywords[i] = "dbname";
values[i] = dbname == NULL ? "replication" : dbname;
i++;
keywords[i] = "replication";
values[i] = dbname == NULL ? "true" : "database";
i++;
Expand Down Expand Up @@ -171,7 +174,11 @@ GetConnection(void)
values[i] = NULL;
}

tmpconn = PQconnectdbParams(keywords, values, true);
/*
* Only expand dbname when we did not already parse the argument as a
* connection string ourselves.
*/
tmpconn = PQconnectdbParams(keywords, values, !connection_string);

/*
* If there is too little memory even to allocate the PGconn object
Expand Down

0 comments on commit cca97ce

Please sign in to comment.