Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit94929f1

Browse files
committed
Clean up some unpleasant behaviors in psql's \connect command.
The check for whether to complain about not having an old connectionto get parameters from was seriously out of date: it had not beenrethought when we invented connstrings, nor when we invented the-reuse-previous option. Replace it with a check that throws anerror if reuse-previous is active and we lack an old connection toreuse. While that doesn't move the goalposts very far in terms ofeasing reconnection after a server crash, at least it's consistent.If the user specifies a connstring plus additional parameters(which is invalid per the documentation), the extra parameters weresilently ignored. That seems like it could be really confusing,so let's throw a syntax error instead.Teach the connstring code path to re-use the old connection's passwordin the same cases as the old-style-syntax code path would, ie if weare reusing parameters and the values of username, host/hostaddr, andport are not being changed. Document this behavior, too, since it wasunmentioned before. Also simplify the implementation a bit, givingrise to two new and useful properties: if there's a "password=xxx" inthe connstring, we'll use it not ignore it, and by default (i.e.,except with --no-password) we will prompt for a password if there-used password or connstring password doesn't work. The previouscode just failed if the re-used password didn't work.Given the paucity of field complaints about these issues, I don'tthink that they rise to the level of back-patchable bug fixes,and in any case they might represent undesirable behavior changesin minor releases. So no back-patch.Discussion:https://postgr.es/m/235210.1603321144@sss.pgh.pa.us
1 parent866e24d commit94929f1

File tree

2 files changed

+54
-39
lines changed

2 files changed

+54
-39
lines changed

‎doc/src/sgml/ref/psql-ref.sgml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -920,6 +920,8 @@ testdb=>
920920
is changed from its previous value using the positional syntax,
921921
any <replaceable>hostaddr</replaceable> setting present in the
922922
existing connection's parameters is dropped.
923+
Also, any password used for the existing connection will be re-used
924+
only if the user, host, and port settings are not changed.
923925
When the command neither specifies nor reuses a particular parameter,
924926
the <application>libpq</application> default is used.
925927
</para>

‎src/bin/psql/command.c

Lines changed: 52 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -3014,11 +3014,10 @@ param_is_newly_set(const char *old_val, const char *new_val)
30143014
/*
30153015
* do_connect -- handler for \connect
30163016
*
3017-
* Connects to a database with given parameters. Absent an established
3018-
* connection, all parameters are required. Given -reuse-previous=off or a
3019-
* connection string without -reuse-previous=on, NULL values will pass through
3020-
* to PQconnectdbParams(), so the libpq defaults will be used. Otherwise, NULL
3021-
* values will be replaced with the ones in the current connection.
3017+
* Connects to a database with given parameters. If we are told to re-use
3018+
* parameters, parameters from the previous connection are used where the
3019+
* command's own options do not supply a value. Otherwise, libpq defaults
3020+
* are used.
30223021
*
30233022
* In interactive mode, if connection fails with the given parameters,
30243023
* the old connection will be kept.
@@ -3038,20 +3037,16 @@ do_connect(enum trivalue reuse_previous_specification,
30383037
boolhas_connection_string;
30393038
boolreuse_previous;
30403039

3041-
if (!o_conn&& (!dbname|| !user|| !host|| !port))
3040+
has_connection_string=dbname ?
3041+
recognized_connection_string(dbname) : false;
3042+
3043+
/* Complain if we have additional arguments after a connection string. */
3044+
if (has_connection_string&& (user||host||port))
30423045
{
3043-
/*
3044-
* We don't know the supplied connection parameters and don't want to
3045-
* connect to the wrong database by using defaults, so require all
3046-
* parameters to be specified.
3047-
*/
3048-
pg_log_error("All connection parameters must be supplied because no "
3049-
"database connection exists");
3046+
pg_log_error("Do not give user, host, or port separately when using a connection string");
30503047
return false;
30513048
}
30523049

3053-
has_connection_string=dbname ?
3054-
recognized_connection_string(dbname) : false;
30553050
switch (reuse_previous_specification)
30563051
{
30573052
caseTRI_YES:
@@ -3065,16 +3060,14 @@ do_connect(enum trivalue reuse_previous_specification,
30653060
break;
30663061
}
30673062

3068-
/* If the old connection does not exist, there is nothing to reuse. */
3069-
if (!o_conn)
3070-
reuse_previous= false;
3071-
3072-
/* Silently ignore arguments subsequent to a connection string. */
3073-
if (has_connection_string)
3063+
/*
3064+
* If we are to re-use parameters, there'd better be an old connection to
3065+
* get them from.
3066+
*/
3067+
if (reuse_previous&& !o_conn)
30743068
{
3075-
user=NULL;
3076-
host=NULL;
3077-
port=NULL;
3069+
pg_log_error("No database connection exists to re-use parameters from");
3070+
return false;
30783071
}
30793072

30803073
/*
@@ -3103,6 +3096,7 @@ do_connect(enum trivalue reuse_previous_specification,
31033096
{
31043097
PQconninfoOption*ci;
31053098
PQconninfoOption*replci;
3099+
boolhave_password= false;
31063100

31073101
for (ci=cinfo,replci=replcinfo;
31083102
ci->keyword&&replci->keyword;
@@ -3121,6 +3115,26 @@ do_connect(enum trivalue reuse_previous_specification,
31213115

31223116
replci->val=ci->val;
31233117
ci->val=swap;
3118+
3119+
/*
3120+
* Check whether connstring provides options affecting
3121+
* password re-use. While any change in user, host,
3122+
* hostaddr, or port causes us to ignore the old
3123+
* connection's password, we don't force that for
3124+
* dbname, since passwords aren't database-specific.
3125+
*/
3126+
if (replci->val==NULL||
3127+
strcmp(ci->val,replci->val)!=0)
3128+
{
3129+
if (strcmp(replci->keyword,"user")==0||
3130+
strcmp(replci->keyword,"host")==0||
3131+
strcmp(replci->keyword,"hostaddr")==0||
3132+
strcmp(replci->keyword,"port")==0)
3133+
keep_password= false;
3134+
}
3135+
/* Also note whether connstring contains a password. */
3136+
if (strcmp(replci->keyword,"password")==0)
3137+
have_password= true;
31243138
}
31253139
}
31263140
Assert(ci->keyword==NULL&&replci->keyword==NULL);
@@ -3130,8 +3144,13 @@ do_connect(enum trivalue reuse_previous_specification,
31303144

31313145
PQconninfoFree(replcinfo);
31323146

3133-
/* We never re-use a password with a conninfo string. */
3134-
keep_password= false;
3147+
/*
3148+
* If the connstring contains a password, tell the loop below
3149+
* that we may use it, regardless of other settings (i.e.,
3150+
* cinfo's password is no longer an "old" password).
3151+
*/
3152+
if (have_password)
3153+
keep_password= true;
31353154

31363155
/* Don't let code below try to inject dbname into params. */
31373156
dbname=NULL;
@@ -3219,14 +3238,6 @@ do_connect(enum trivalue reuse_previous_specification,
32193238
*/
32203239
password=prompt_for_password(has_connection_string ?NULL :user);
32213240
}
3222-
elseif (o_conn&&keep_password)
3223-
{
3224-
password=PQpass(o_conn);
3225-
if (password&&*password)
3226-
password=pg_strdup(password);
3227-
else
3228-
password=NULL;
3229-
}
32303241

32313242
/* Loop till we have a connection or fail, which we might've already */
32323243
while (success)
@@ -3238,12 +3249,12 @@ do_connect(enum trivalue reuse_previous_specification,
32383249

32393250
/*
32403251
* Copy non-default settings into the PQconnectdbParams parameter
3241-
* arrays; but override any values specified old-style, as well as the
3242-
* password and a couple of fields we want to set forcibly.
3252+
* arrays; but inject any values specified old-style, as well as any
3253+
* interactively-obtained password, and a couple of fields we want to
3254+
* set forcibly.
32433255
*
32443256
* If you change this code, see also the initial-connection code in
3245-
* main(). For no good reason, a connection string password= takes
3246-
* precedence in main() but not here.
3257+
* main().
32473258
*/
32483259
for (ci=cinfo;ci->keyword;ci++)
32493260
{
@@ -3262,7 +3273,9 @@ do_connect(enum trivalue reuse_previous_specification,
32623273
}
32633274
elseif (port&&strcmp(ci->keyword,"port")==0)
32643275
values[paramnum++]=port;
3265-
elseif (strcmp(ci->keyword,"password")==0)
3276+
/* If !keep_password, we unconditionally drop old password */
3277+
elseif ((password|| !keep_password)&&
3278+
strcmp(ci->keyword,"password")==0)
32663279
values[paramnum++]=password;
32673280
elseif (strcmp(ci->keyword,"fallback_application_name")==0)
32683281
values[paramnum++]=pset.progname;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp