Through my misreading of what the existing code actually did,
commits
85c54287a et al. broke psql's behavior for the case where
"\c connstring" provides a password in the connstring. We should
use that password in such a case, but as of
85c54287a we ignored it
(and instead, prompted for a password).
Commit
94929f1cf fixed that in HEAD, but since I thought it was
cleaning up a longstanding misbehavior and not one I'd just created,
I didn't back-patch it.
Hence, back-patch the portions of
94929f1cf having to do with
password management. In addition to fixing the introduced bug,
this means that "\c -reuse-previous=on connstring" will allow
re-use of an existing connection's password if the connstring
doesn't change user/host/port. That didn't happen before, but
it seems like a bug fix, and anyway I'm loath to have significant
differences in this code across versions.
Also fix an error with the same root cause about whether or not to
override a connstring's setting of client_encoding. As of
85c54287a
we always did so; restore the previous behavior of overriding only
when stdin/stdout are a terminal and there's no environment setting
of PGCLIENTENCODING. (I find that definition a bit surprising, but
right now doesn't seem like the time to revisit it.)
Per bug #16746 from Krzysztof Gradek. As with the previous patch,
back-patch to all supported branches.
Discussion: https://postgr.es/m/16746-
44b30e2edf4335d4@postgresql.org
int nconnopts = 0;
bool same_host = false;
char *password = NULL;
+ char *client_encoding;
bool success = true;
bool keep_password = true;
bool has_connection_string;
password = prompt_for_password(has_connection_string ? NULL : user);
}
+ /*
+ * Consider whether to force client_encoding to "auto" (overriding
+ * anything in the connection string). We do so if we have a terminal
+ * connection and there is no PGCLIENTENCODING environment setting.
+ */
+ if (pset.notty || getenv("PGCLIENTENCODING"))
+ client_encoding = NULL;
+ else
+ client_encoding = "auto";
+
/* Loop till we have a connection or fail, which we might've already */
while (success)
{
values[paramnum++] = password;
else if (strcmp(ci->keyword, "fallback_application_name") == 0)
values[paramnum++] = pset.progname;
- else if (strcmp(ci->keyword, "client_encoding") == 0)
- values[paramnum++] = (pset.notty || getenv("PGCLIENTENCODING")) ? NULL : "auto";
+ else if (client_encoding &&
+ strcmp(ci->keyword, "client_encoding") == 0)
+ values[paramnum++] = client_encoding;
else if (ci->val)
values[paramnum++] = ci->val;
/* else, don't bother making libpq parse this keyword */