Skip to content

Commit aa05c37

Browse files
committed
Add -d option to pg_basebackup and pg_receivexlog, for connection string.
Without this, there's no way to pass arbitrary libpq connection parameters to these applications. It's a bit strange that the option is called -d/--dbname, when in fact you can *not* pass a database name in it, but it's consistent with other client applications where a connection string is also passed using -d. Original patch by Amit Kapila, heavily modified by me.
1 parent 786170d commit aa05c37

File tree

6 files changed

+111
-25
lines changed

6 files changed

+111
-25
lines changed

doc/src/sgml/ref/pg_basebackup.sgml

+17
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,23 @@ PostgreSQL documentation
358358
The following command-line options control the database connection parameters.
359359

360360
<variablelist>
361+
<varlistentry>
362+
<term><option>-d <replaceable class="parameter">connstr</replaceable></option></term>
363+
<term><option>--dbname=<replaceable class="parameter">connstr</replaceable></option></term>
364+
<listitem>
365+
<para>
366+
Specifies parameters used to connect to the server, as a connection
367+
string. See <xref linkend="libpq-connstring"> for more information.
368+
</para>
369+
<para>
370+
The option is called <literal>--dbname</> for consistency with other
371+
client applications, but because <application>pg_basebackup</application>
372+
doesn't connect to any particular database in the cluster, database
373+
name in the connection string will be ignored.
374+
</para>
375+
</listitem>
376+
</varlistentry>
377+
361378
<varlistentry>
362379
<term><option>-h <replaceable class="parameter">host</replaceable></option></term>
363380
<term><option>--host=<replaceable class="parameter">host</replaceable></option></term>

doc/src/sgml/ref/pg_receivexlog.sgml

+17
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,23 @@ PostgreSQL documentation
122122
The following command-line options control the database connection parameters.
123123

124124
<variablelist>
125+
<varlistentry>
126+
<term><option>-d <replaceable class="parameter">connstr</replaceable></option></term>
127+
<term><option>--dbname=<replaceable class="parameter">connstr</replaceable></option></term>
128+
<listitem>
129+
<para>
130+
Specifies parameters used to connect to the server, as a connection
131+
string. See <xref linkend="libpq-connstring"> for more information.
132+
</para>
133+
<para>
134+
The option is called <literal>--dbname</> for consistency with other
135+
client applications, but because <application>pg_basebackup</application>
136+
doesn't connect to any particular database in the cluster, database
137+
name in the connection string will be ignored.
138+
</para>
139+
</listitem>
140+
</varlistentry>
141+
125142
<varlistentry>
126143
<term><option>-h <replaceable class="parameter">host</replaceable></option></term>
127144
<term><option>--host=<replaceable class="parameter">host</replaceable></option></term>

src/bin/pg_basebackup/pg_basebackup.c

+6-1
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ usage(void)
126126
printf(_(" -V, --version output version information, then exit\n"));
127127
printf(_(" -?, --help show this help, then exit\n"));
128128
printf(_("\nConnection options:\n"));
129+
printf(_(" -d, --dbname=CONNSTR connection string\n"));
129130
printf(_(" -h, --host=HOSTNAME database server host or socket directory\n"));
130131
printf(_(" -p, --port=PORT database server port number\n"));
131132
printf(_(" -s, --status-interval=INTERVAL\n"
@@ -1540,6 +1541,7 @@ main(int argc, char **argv)
15401541
{"gzip", no_argument, NULL, 'z'},
15411542
{"compress", required_argument, NULL, 'Z'},
15421543
{"label", required_argument, NULL, 'l'},
1544+
{"dbname", required_argument, NULL, 'd'},
15431545
{"host", required_argument, NULL, 'h'},
15441546
{"port", required_argument, NULL, 'p'},
15451547
{"username", required_argument, NULL, 'U'},
@@ -1572,7 +1574,7 @@ main(int argc, char **argv)
15721574
}
15731575
}
15741576

1575-
while ((c = getopt_long(argc, argv, "D:F:RxX:l:zZ:c:h:p:U:s:wWvP",
1577+
while ((c = getopt_long(argc, argv, "D:F:RxX:l:zZ:d:c:h:p:U:s:wWvP",
15761578
long_options, &option_index)) != -1)
15771579
{
15781580
switch (c)
@@ -1663,6 +1665,9 @@ main(int argc, char **argv)
16631665
exit(1);
16641666
}
16651667
break;
1668+
case 'd':
1669+
connection_string = pg_strdup(optarg);
1670+
break;
16661671
case 'h':
16671672
dbhost = pg_strdup(optarg);
16681673
break;

src/bin/pg_basebackup/pg_receivexlog.c

+6-1
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ usage(void)
5858
printf(_(" -V, --version output version information, then exit\n"));
5959
printf(_(" -?, --help show this help, then exit\n"));
6060
printf(_("\nConnection options:\n"));
61+
printf(_(" -d, --dbname=CONNSTR connection string\n"));
6162
printf(_(" -h, --host=HOSTNAME database server host or socket directory\n"));
6263
printf(_(" -p, --port=PORT database server port number\n"));
6364
printf(_(" -s, --status-interval=INTERVAL\n"
@@ -306,6 +307,7 @@ main(int argc, char **argv)
306307
{"help", no_argument, NULL, '?'},
307308
{"version", no_argument, NULL, 'V'},
308309
{"directory", required_argument, NULL, 'D'},
310+
{"dbname", required_argument, NULL, 'd'},
309311
{"host", required_argument, NULL, 'h'},
310312
{"port", required_argument, NULL, 'p'},
311313
{"username", required_argument, NULL, 'U'},
@@ -338,14 +340,17 @@ main(int argc, char **argv)
338340
}
339341
}
340342

341-
while ((c = getopt_long(argc, argv, "D:h:p:U:s:nwWv",
343+
while ((c = getopt_long(argc, argv, "D:d:h:p:U:s:nwWv",
342344
long_options, &option_index)) != -1)
343345
{
344346
switch (c)
345347
{
346348
case 'D':
347349
basedir = pg_strdup(optarg);
348350
break;
351+
case 'd':
352+
connection_string = pg_strdup(optarg);
353+
break;
349354
case 'h':
350355
dbhost = pg_strdup(optarg);
351356
break;

src/bin/pg_basebackup/streamutil.c

+64-23
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include <string.h>
1919

2020
const char *progname;
21+
char *connection_string = NULL;
2122
char *dbhost = NULL;
2223
char *dbuser = NULL;
2324
char *dbport = NULL;
@@ -34,31 +35,67 @@ PGconn *
3435
GetConnection(void)
3536
{
3637
PGconn *tmpconn;
37-
int argcount = 4; /* dbname, replication, fallback_app_name,
38-
* password */
38+
int argcount = 7; /* dbname, replication, fallback_app_name,
39+
* host, user, port, password */
3940
int i;
4041
const char **keywords;
4142
const char **values;
4243
char *password = NULL;
4344
const char *tmpparam;
45+
PQconninfoOption *conn_opts = NULL;
46+
PQconninfoOption *conn_opt;
47+
char *err_msg = NULL;
48+
49+
/*
50+
* Merge the connection info inputs given in form of connection string,
51+
* options and default values (dbname=replication, replication=true,
52+
* etc.)
53+
*/
54+
i = 0;
55+
if (connection_string)
56+
{
57+
conn_opts = PQconninfoParse(connection_string, &err_msg);
58+
if (conn_opts == NULL)
59+
{
60+
fprintf(stderr, "%s: %s\n", progname, err_msg);
61+
return NULL;
62+
}
63+
64+
for (conn_opt = conn_opts; conn_opt->keyword != NULL; conn_opt++)
65+
{
66+
if (conn_opt->val != NULL && conn_opt->val[0] != '\0')
67+
argcount++;
68+
}
69+
70+
keywords = pg_malloc0((argcount + 1) * sizeof(*keywords));
71+
values = pg_malloc0((argcount + 1) * sizeof(*values));
72+
73+
for (conn_opt = conn_opts; conn_opt->keyword != NULL; conn_opt++)
74+
{
75+
if (conn_opt->val != NULL && conn_opt->val[0] != '\0')
76+
{
77+
keywords[i] = conn_opt->keyword;
78+
values[i] = conn_opt->val;
79+
i++;
80+
}
81+
}
82+
}
83+
else
84+
{
85+
keywords = pg_malloc0((argcount + 1) * sizeof(*keywords));
86+
values = pg_malloc0((argcount + 1) * sizeof(*values));
87+
}
88+
89+
keywords[i] = "dbname";
90+
values[i] = "replication";
91+
i++;
92+
keywords[i] = "replication";
93+
values[i] = "true";
94+
i++;
95+
keywords[i] = "fallback_application_name";
96+
values[i] = progname;
97+
i++;
4498

45-
if (dbhost)
46-
argcount++;
47-
if (dbuser)
48-
argcount++;
49-
if (dbport)
50-
argcount++;
51-
52-
keywords = pg_malloc0((argcount + 1) * sizeof(*keywords));
53-
values = pg_malloc0((argcount + 1) * sizeof(*values));
54-
55-
keywords[0] = "dbname";
56-
values[0] = "replication";
57-
keywords[1] = "replication";
58-
values[1] = "true";
59-
keywords[2] = "fallback_application_name";
60-
values[2] = progname;
61-
i = 3;
6299
if (dbhost)
63100
{
64101
keywords[i] = "host";
@@ -90,15 +127,15 @@ GetConnection(void)
90127
* meaning this is the call for a second session to the same
91128
* database, so just forcibly reuse that password.
92129
*/
93-
keywords[argcount - 1] = "password";
94-
values[argcount - 1] = dbpassword;
130+
keywords[i] = "password";
131+
values[i] = dbpassword;
95132
dbgetpassword = -1; /* Don't try again if this fails */
96133
}
97134
else if (dbgetpassword == 1)
98135
{
99136
password = simple_prompt(_("Password: "), 100, false);
100-
keywords[argcount - 1] = "password";
101-
values[argcount - 1] = password;
137+
keywords[i] = "password";
138+
values[i] = password;
102139
}
103140

104141
tmpconn = PQconnectdbParams(keywords, values, true);
@@ -130,12 +167,16 @@ GetConnection(void)
130167
PQfinish(tmpconn);
131168
free(values);
132169
free(keywords);
170+
if (conn_opts)
171+
PQconninfoFree(conn_opts);
133172
return NULL;
134173
}
135174

136175
/* Connection ok! */
137176
free(values);
138177
free(keywords);
178+
if (conn_opts)
179+
PQconninfoFree(conn_opts);
139180

140181
/*
141182
* Ensure we have the same value of integer timestamps as the server

src/bin/pg_basebackup/streamutil.h

+1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#include "libpq-fe.h"
22

33
extern const char *progname;
4+
extern char *connection_string;
45
extern char *dbhost;
56
extern char *dbuser;
67
extern char *dbport;

0 commit comments

Comments
 (0)