Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 1814f91

Browse files
committed
Fix connection string handling in src/bin/scripts/ programs.
When told to process all databases, clusterdb, reindexdb, and vacuumdb would reconnect by replacing their --maintenance-db parameter with the name of the target database. If that parameter is a connstring (which has been allowed for a long time, though we failed to document that before this patch), we'd lose any other options it might specify, for example SSL or GSS parameters, possibly resulting in failure to connect. Thus, this is the same bug as commit a45bc8a4f fixed in pg_dump and pg_restore. We can fix it in the same way, by using libpq's rules for handling multiple "dbname" parameters to add the target database name separately. I chose to apply the same refactoring approach as in that patch, with a struct to handle the command line parameters that need to be passed through to connectDatabase. (Maybe someday we can unify the very similar functions here and in pg_dump/pg_restore.) Per Peter Eisentraut's comments on bug #16604. Back-patch to all supported branches. Discussion: https://postgr.es/m/16604-933f4b8791227b15@postgresql.org
1 parent 25378db commit 1814f91

16 files changed

+260
-206
lines changed

doc/src/sgml/ref/clusterdb.sgml

+13-7
Original file line numberDiff line numberDiff line change
@@ -90,9 +90,9 @@ PostgreSQL documentation
9090
<term><option><optional>--dbname=</optional><replaceable class="parameter">dbname</replaceable></option></term>
9191
<listitem>
9292
<para>
93-
Specifies the name of the database to be clustered.
94-
If this is not specified and <option>-a</option> (or
95-
<option>--all</option>) is not used, the database name is read
93+
Specifies the name of the database to be clustered,
94+
when <option>-a</option>/<option>--all</option> is not used.
95+
If this is not specified, the database name is read
9696
from the environment variable <envar>PGDATABASE</envar>. If
9797
that is not set, the user name specified for the connection is
9898
used. The <replaceable>dbname</replaceable> can be a <link
@@ -249,10 +249,16 @@ PostgreSQL documentation
249249
<term><option>--maintenance-db=<replaceable class="parameter">dbname</replaceable></option></term>
250250
<listitem>
251251
<para>
252-
Specifies the name of the database to connect to discover what other
253-
databases should be clustered. If not specified, the
254-
<literal>postgres</literal> database will be used,
255-
and if that does not exist, <literal>template1</literal> will be used.
252+
Specifies the name of the database to connect to to discover which
253+
databases should be clustered,
254+
when <option>-a</option>/<option>--all</option> is used.
255+
If not specified, the <literal>postgres</literal> database will be used,
256+
or if that does not exist, <literal>template1</literal> will be used.
257+
This can be a <link linkend="libpq-connstring">connection
258+
string</link>. If so, connection string parameters will override any
259+
conflicting command line options. Also, connection string parameters
260+
other than the database name itself will be re-used when connecting
261+
to other databases.
256262
</para>
257263
</listitem>
258264
</varlistentry>

doc/src/sgml/ref/createdb.sgml

+3
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,9 @@ PostgreSQL documentation
284284
database will be used; if that does not exist (or if it is the name
285285
of the new database being created), <literal>template1</literal> will
286286
be used.
287+
This can be a <link linkend="libpq-connstring">connection
288+
string</link>. If so, connection string parameters will override any
289+
conflicting command line options.
287290
</para>
288291
</listitem>
289292
</varlistentry>

doc/src/sgml/ref/dropdb.sgml

+3
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,9 @@ PostgreSQL documentation
217217
target database. If not specified, the <literal>postgres</literal>
218218
database will be used; if that does not exist (or is the database
219219
being dropped), <literal>template1</literal> will be used.
220+
This can be a <link linkend="libpq-connstring">connection
221+
string</link>. If so, connection string parameters will override any
222+
conflicting command line options.
220223
</para>
221224
</listitem>
222225
</varlistentry>

doc/src/sgml/ref/reindexdb.sgml

+13-7
Original file line numberDiff line numberDiff line change
@@ -134,9 +134,9 @@ PostgreSQL documentation
134134
<term><option><optional>--dbname=</optional><replaceable class="parameter">dbname</replaceable></option></term>
135135
<listitem>
136136
<para>
137-
Specifies the name of the database to be reindexed.
138-
If this is not specified and <option>-a</option> (or
139-
<option>--all</option>) is not used, the database name is read
137+
Specifies the name of the database to be reindexed,
138+
when <option>-a</option>/<option>--all</option> is not used.
139+
If this is not specified, the database name is read
140140
from the environment variable <envar>PGDATABASE</envar>. If
141141
that is not set, the user name specified for the connection is
142142
used. The <replaceable>dbname</replaceable> can be a <link
@@ -351,10 +351,16 @@ PostgreSQL documentation
351351
<term><option>--maintenance-db=<replaceable class="parameter">dbname</replaceable></option></term>
352352
<listitem>
353353
<para>
354-
Specifies the name of the database to connect to discover what other
355-
databases should be reindexed. If not specified, the
356-
<literal>postgres</literal> database will be used,
357-
and if that does not exist, <literal>template1</literal> will be used.
354+
Specifies the name of the database to connect to to discover which
355+
databases should be reindexed,
356+
when <option>-a</option>/<option>--all</option> is used.
357+
If not specified, the <literal>postgres</literal> database will be used,
358+
or if that does not exist, <literal>template1</literal> will be used.
359+
This can be a <link linkend="libpq-connstring">connection
360+
string</link>. If so, connection string parameters will override any
361+
conflicting command line options. Also, connection string parameters
362+
other than the database name itself will be re-used when connecting
363+
to other databases.
358364
</para>
359365
</listitem>
360366
</varlistentry>

doc/src/sgml/ref/vacuumdb.sgml

+13-7
Original file line numberDiff line numberDiff line change
@@ -92,9 +92,9 @@ PostgreSQL documentation
9292
<term><option><optional>--dbname=</optional><replaceable class="parameter">dbname</replaceable></option></term>
9393
<listitem>
9494
<para>
95-
Specifies the name of the database to be cleaned or analyzed.
96-
If this is not specified and <option>-a</option> (or
97-
<option>--all</option>) is not used, the database name is read
95+
Specifies the name of the database to be cleaned or analyzed,
96+
when <option>-a</option>/<option>--all</option> is not used.
97+
If this is not specified, the database name is read
9898
from the environment variable <envar>PGDATABASE</envar>. If
9999
that is not set, the user name specified for the connection is
100100
used. The <replaceable>dbname</replaceable> can be a <link
@@ -444,10 +444,16 @@ PostgreSQL documentation
444444
<term><option>--maintenance-db=<replaceable class="parameter">dbname</replaceable></option></term>
445445
<listitem>
446446
<para>
447-
Specifies the name of the database to connect to discover what other
448-
databases should be vacuumed. If not specified, the
449-
<literal>postgres</literal> database will be used,
450-
and if that does not exist, <literal>template1</literal> will be used.
447+
Specifies the name of the database to connect to to discover which
448+
databases should be vacuumed,
449+
when <option>-a</option>/<option>--all</option> is used.
450+
If not specified, the <literal>postgres</literal> database will be used,
451+
or if that does not exist, <literal>template1</literal> will be used.
452+
This can be a <link linkend="libpq-connstring">connection
453+
string</link>. If so, connection string parameters will override any
454+
conflicting command line options. Also, connection string parameters
455+
other than the database name itself will be re-used when connecting
456+
to other databases.
451457
</para>
452458
</listitem>
453459
</varlistentry>

src/bin/scripts/clusterdb.c

+29-38
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,10 @@
1717
#include "fe_utils/string_utils.h"
1818

1919

20-
static void cluster_one_database(const char *dbname, bool verbose, const char *table,
21-
const char *host, const char *port,
22-
const char *username, enum trivalue prompt_password,
23-
const char *progname, bool echo);
24-
static void cluster_all_databases(bool verbose, const char *maintenance_db,
25-
const char *host, const char *port,
26-
const char *username, enum trivalue prompt_password,
27-
const char *progname, bool echo, bool quiet);
28-
20+
static void cluster_one_database(const ConnParams *cparams, const char *table,
21+
const char *progname, bool verbose, bool echo);
22+
static void cluster_all_databases(ConnParams *cparams, const char *progname,
23+
bool verbose, bool echo, bool quiet);
2924
static void help(const char *progname);
3025

3126

@@ -58,6 +53,7 @@ main(int argc, char *argv[])
5853
char *port = NULL;
5954
char *username = NULL;
6055
enum trivalue prompt_password = TRI_DEFAULT;
56+
ConnParams cparams;
6157
bool echo = false;
6258
bool quiet = false;
6359
bool alldb = false;
@@ -134,6 +130,13 @@ main(int argc, char *argv[])
134130
exit(1);
135131
}
136132

133+
/* fill cparams except for dbname, which is set below */
134+
cparams.pghost = host;
135+
cparams.pgport = port;
136+
cparams.pguser = username;
137+
cparams.prompt_password = prompt_password;
138+
cparams.override_dbname = NULL;
139+
137140
setup_cancel_handler(NULL);
138141

139142
if (alldb)
@@ -150,8 +153,9 @@ main(int argc, char *argv[])
150153
exit(1);
151154
}
152155

153-
cluster_all_databases(verbose, maintenance_db, host, port, username, prompt_password,
154-
progname, echo, quiet);
156+
cparams.dbname = maintenance_db;
157+
158+
cluster_all_databases(&cparams, progname, verbose, echo, quiet);
155159
}
156160
else
157161
{
@@ -165,39 +169,36 @@ main(int argc, char *argv[])
165169
dbname = get_user_name_or_exit(progname);
166170
}
167171

172+
cparams.dbname = dbname;
173+
168174
if (tables.head != NULL)
169175
{
170176
SimpleStringListCell *cell;
171177

172178
for (cell = tables.head; cell; cell = cell->next)
173179
{
174-
cluster_one_database(dbname, verbose, cell->val,
175-
host, port, username, prompt_password,
176-
progname, echo);
180+
cluster_one_database(&cparams, cell->val,
181+
progname, verbose, echo);
177182
}
178183
}
179184
else
180-
cluster_one_database(dbname, verbose, NULL,
181-
host, port, username, prompt_password,
182-
progname, echo);
185+
cluster_one_database(&cparams, NULL,
186+
progname, verbose, echo);
183187
}
184188

185189
exit(0);
186190
}
187191

188192

189193
static void
190-
cluster_one_database(const char *dbname, bool verbose, const char *table,
191-
const char *host, const char *port,
192-
const char *username, enum trivalue prompt_password,
193-
const char *progname, bool echo)
194+
cluster_one_database(const ConnParams *cparams, const char *table,
195+
const char *progname, bool verbose, bool echo)
194196
{
195197
PQExpBufferData sql;
196198

197199
PGconn *conn;
198200

199-
conn = connectDatabase(dbname, host, port, username, prompt_password,
200-
progname, echo, false, false);
201+
conn = connectDatabase(cparams, progname, echo, false, false);
201202

202203
initPQExpBuffer(&sql);
203204

@@ -228,22 +229,17 @@ cluster_one_database(const char *dbname, bool verbose, const char *table,
228229

229230

230231
static void
231-
cluster_all_databases(bool verbose, const char *maintenance_db,
232-
const char *host, const char *port,
233-
const char *username, enum trivalue prompt_password,
234-
const char *progname, bool echo, bool quiet)
232+
cluster_all_databases(ConnParams *cparams, const char *progname,
233+
bool verbose, bool echo, bool quiet)
235234
{
236235
PGconn *conn;
237236
PGresult *result;
238-
PQExpBufferData connstr;
239237
int i;
240238

241-
conn = connectMaintenanceDatabase(maintenance_db, host, port, username,
242-
prompt_password, progname, echo);
239+
conn = connectMaintenanceDatabase(cparams, progname, echo);
243240
result = executeQuery(conn, "SELECT datname FROM pg_database WHERE datallowconn ORDER BY 1;", echo);
244241
PQfinish(conn);
245242

246-
initPQExpBuffer(&connstr);
247243
for (i = 0; i < PQntuples(result); i++)
248244
{
249245
char *dbname = PQgetvalue(result, i, 0);
@@ -254,15 +250,10 @@ cluster_all_databases(bool verbose, const char *maintenance_db,
254250
fflush(stdout);
255251
}
256252

257-
resetPQExpBuffer(&connstr);
258-
appendPQExpBufferStr(&connstr, "dbname=");
259-
appendConnStrVal(&connstr, dbname);
253+
cparams->override_dbname = dbname;
260254

261-
cluster_one_database(connstr.data, verbose, NULL,
262-
host, port, username, prompt_password,
263-
progname, echo);
255+
cluster_one_database(cparams, NULL, progname, verbose, echo);
264256
}
265-
termPQExpBuffer(&connstr);
266257

267258
PQclear(result);
268259
}

0 commit comments

Comments
 (0)