Skip to content

Commit 20be76d

Browse files
committed
Fix connection string handling in psql's \connect command.
psql's \connect claims to be able to re-use previous connection parameters, but in fact it only re-uses the database name, user name, host name (and possibly hostaddr, depending on version), and port. This is problematic for assorted use cases. Notably, pg_dump[all] emits "\connect databasename" commands which we would like to have re-use all other parameters. If such a script is loaded in a psql run that initially had "-d connstring" with some non-default parameters, those other parameters would be lost, potentially causing connection failure. (Thus, this is the same kind of bug addressed in commits a45bc8a and 8e5793a, although the details are much different.) To fix, redesign do_connect() so that it pulls out all properties of the old PGconn using PQconninfo(), and then replaces individual properties in that array. In the case where we don't wish to re-use anything, get libpq's default settings using PQconndefaults() and replace entries in that, so that we don't need different code paths for the two cases. This does result in an additional behavioral change for cases where the original connection parameters allowed multiple hosts, say "psql -h host1,host2", and the \connect request allows re-use of the host setting. Because the previous coding relied on PQhost(), it would only permit reconnection to the same host originally selected. Although one can think of scenarios where that's a good thing, there are others where it is not. Moreover, that behavior doesn't seem to meet the principle of least surprise, nor was it documented; nor is it even clear it was intended, since that coding long pre-dates the addition of multi-host support to libpq. Hence, this patch is content to drop it and re-use the host list as given. 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 c7658a4 commit 20be76d

File tree

2 files changed

+227
-87
lines changed

2 files changed

+227
-87
lines changed

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

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -880,32 +880,47 @@ testdb=>
880880
<para>
881881
Establishes a new connection to a <productname>PostgreSQL</productname>
882882
server. The connection parameters to use can be specified either
883-
using a positional syntax, or using <replaceable>conninfo</replaceable> connection
884-
strings as detailed in <xref linkend="libpq-connstring"/>.
883+
using a positional syntax (one or more of database name, user,
884+
host, and port), or using a <replaceable>conninfo</replaceable>
885+
connection string as detailed in
886+
<xref linkend="libpq-connstring"/>. If no arguments are given, a
887+
new connection is made using the same parameters as before.
885888
</para>
886889

887890
<para>
888-
Where the command omits database name, user, host, or port, the new
889-
connection can reuse values from the previous connection. By default,
890-
values from the previous connection are reused except when processing
891-
a <replaceable>conninfo</replaceable> string. Passing a first argument
892-
of <literal>-reuse-previous=on</literal>
893-
or <literal>-reuse-previous=off</literal> overrides that default.
894-
When the command neither specifies nor reuses a particular parameter,
895-
the <application>libpq</application> default is used. Specifying any
891+
Specifying any
896892
of <replaceable class="parameter">dbname</replaceable>,
897893
<replaceable class="parameter">username</replaceable>,
898894
<replaceable class="parameter">host</replaceable> or
899895
<replaceable class="parameter">port</replaceable>
900896
as <literal>-</literal> is equivalent to omitting that parameter.
901897
</para>
902898

899+
<para>
900+
The new connection can re-use connection parameters from the previous
901+
connection; not only database name, user, host, and port, but other
902+
settings such as <replaceable>sslmode</replaceable>. By default,
903+
parameters are re-used in the positional syntax, but not when
904+
a <replaceable>conninfo</replaceable> string is given. Passing a
905+
first argument of <literal>-reuse-previous=on</literal>
906+
or <literal>-reuse-previous=off</literal> overrides that default. If
907+
parameters are re-used, then any parameter not explicitly specified as
908+
a positional parameter or in the <replaceable>conninfo</replaceable>
909+
string is taken from the existing connection's parameters. An
910+
exception is that if the <replaceable>host</replaceable> setting
911+
is changed from its previous value using the positional syntax,
912+
any <replaceable>hostaddr</replaceable> setting present in the
913+
existing connection's parameters is dropped.
914+
When the command neither specifies nor reuses a particular parameter,
915+
the <application>libpq</application> default is used.
916+
</para>
917+
903918
<para>
904919
If the new connection is successfully made, the previous
905920
connection is closed.
906-
If the connection attempt failed (wrong user name, access
907-
denied, etc.), the previous connection will only be kept if
908-
<application>psql</application> is in interactive mode. When
921+
If the connection attempt fails (wrong user name, access
922+
denied, etc.), the previous connection will be kept if
923+
<application>psql</application> is in interactive mode. But when
909924
executing a non-interactive script, processing will
910925
immediately stop with an error. This distinction was chosen as
911926
a user convenience against typos on the one hand, and a safety
@@ -920,6 +935,7 @@ testdb=&gt;
920935
=&gt; \c mydb myuser host.dom 6432
921936
=&gt; \c service=foo
922937
=&gt; \c "host=localhost port=5432 dbname=mydb connect_timeout=10 sslmode=disable"
938+
=&gt; \c -reuse-previous=on sslmode=require -- changes only sslmode
923939
=&gt; \c postgresql://tom@localhost/mydb?application_name=myapp
924940
</programlisting>
925941
</listitem>

0 commit comments

Comments
 (0)