Hello,
I got that. I'm working on it, and on the other issues you raised.
The issue I see is what do we want when a name resolves to multiple
addresses. The answer is not fully obvious to me right now. I'll try to send
a patch over the week-end.
At Alvaro's request, here is a quick WIP patch, that does not do the right
thing, because there is no simple way to know whether hostaddr was set at
the libPQ level, so either we set it always, about which Noah complained,
or we don't, about which someone else will complain quite easily, i.e.
with this patch
\c "host=foo hostaddr=ip"
connects to ip, but then
\c
will reconnect to foo but ignore ip. Well, ISTM that this is back to the
previous doubtful behavior, so at least it is not a regression, just the
same bug:-)
A solution could be to have a PQdoestheconnectionuseshostaddr(conn)
function, but I cannot say I'd be thrilled.
Another option would be to import PGconn full definition in
"psql/command.c", but that would break the PQ interface, I cannot say I'd
be thrilled either.
The patch returns host as defined by the user, but the regenerated
hostaddr (aka connip), which is not an homogeneous behavior. PQhost should
probably use connip if host was set as an ip, but that needs guessing.
The underlying issue is that the host/hostaddr stuff is not that easy to
fix.
At least, after the patch the connection information (\conninfo) is still
the right one, which is an improvement.
--
Fabien.
diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c
index 695d6ba9f1..4bf4726981 100644
--- a/src/bin/psql/command.c
+++ b/src/bin/psql/command.c
@@ -2937,16 +2937,16 @@ do_connect(enum trivalue reuse_previous_specification,
if (host && strcmp(host, PQhost(o_conn)) == 0)
{
/*
- * if we are targeting the same host, reuse its hostaddr for
- * consistency
+ * if we are targeting the same host, we should reuse its hostaddr for
+ * consistency if hostaddr was explicitely set. However, the library
+ * does not allow to know that at the libPQ level.
*/
- hostaddr = PQhostaddr(o_conn);
+ ;
}
if (!host)
{
host = PQhost(o_conn);
- /* also set hostaddr for consistency */
- hostaddr = PQhostaddr(o_conn);
+ /* we should also set hostaddr for consistency, if hostaddr was set */
}
if (!port)
port = PQport(o_conn);
@@ -3129,7 +3129,10 @@ do_connect(enum trivalue reuse_previous_specification,
char *host = PQhost(pset.db);
char *hostaddr = PQhostaddr(pset.db);
- /* If the host is an absolute path, the connection is via socket */
+ /*
+ * If the host is an absolute path, the connection is via socket
+ * unless overriden by hostaddr
+ */
if (is_absolute_path(host))
{
if (hostaddr && *hostaddr)
diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
index e58fa6742a..5d88c15cc5 100644
--- a/src/interfaces/libpq/fe-connect.c
+++ b/src/interfaces/libpq/fe-connect.c
@@ -1536,9 +1536,7 @@ getHostaddr(PGconn *conn, char *host_addr, int host_addr_len)
{
struct sockaddr_storage *addr = &conn->raddr.addr;
- if (conn->connhost[conn->whichhost].type == CHT_HOST_ADDRESS)
- strlcpy(host_addr, conn->connhost[conn->whichhost].hostaddr, host_addr_len);
- else if (addr->ss_family == AF_INET)
+ if (addr->ss_family == AF_INET)
{
if (inet_net_ntop(AF_INET,
&((struct sockaddr_in *) addr)->sin_addr.s_addr,
@@ -6463,6 +6461,11 @@ PQhost(const PGconn *conn)
if (conn->connhost != NULL)
{
+ /*
+ * note this return the host=... value provided by the user,
+ * even if it is an IP, this it can include spaces and so,
+ * whereas the next function uses the regenerated IP.
+ */
if (conn->connhost[conn->whichhost].host != NULL &&
conn->connhost[conn->whichhost].host[0] != '\0')
return conn->connhost[conn->whichhost].host;
@@ -6480,15 +6483,8 @@ PQhostaddr(const PGconn *conn)
if (!conn)
return NULL;
- if (conn->connhost != NULL)
- {
- if (conn->connhost[conn->whichhost].hostaddr != NULL &&
- conn->connhost[conn->whichhost].hostaddr[0] != '\0')
- return conn->connhost[conn->whichhost].hostaddr;
-
- if (conn->connip != NULL)
- return conn->connip;
- }
+ if (conn->connhost != NULL && conn->connip != NULL)
+ return conn->connip;
return "";
}