Prioritize explicit endpoint options over PGHOST-derived defaults #742
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Hello! First of all, thank you for this amazing library
This PR addresses a bug where setting the
PGHOST
environment variable can unintentionally override explicitly passed connection options like:hostname
,:socket_dir
,:socket
, or:endpoints
.Summary
default_opts/1
to derive the host fromPGHOST
only if no endpoint-related options are explicitly provided (:socket
,:socket_dir
,:hostname
, or:endpoints
).Motivation
When
PGHOST
is set (e.g., to a Unix socket path), Postgrex currently prioritizes it over explicitly passed options like:hostname
. This causes surprising behavior: users trying to connect to a remote host (e.g., localhost over TCP) may find Postgrex silently attempting to connect over a non-existent socket.This PR brings Postgrex closer in behavior to
psql
, which properly prioritizes CLI-supplied options overPGHOST
.Replication Instructions
You can reproduce the issue as follows:
Set
PGHOST
to any path:Attempt to start a connection using valid TCP settings:
Expected: Should connect over TCP to
localhost
Actual: Fails, as Postgrex attempts to connect via
/whatever/.s.PGSQL.5432
socket specified via PGHOST.Current workaround (demonstrating expected behavior with a workaround using manual override to
socket_dir: nil
):Behavior Comparison with
psql
To reinforce expected behavior, here’s how
psql
treats similar inputs:Explicit
-h localhost
takes precedence overPGHOST
:PGHOST=/whatever psql -d postgres -h localhost -U postgres -c "SELECT 1"
This should fail as no
-h
is provided and thePGHOST
socket doesn't existPGHOST=/whatever psql -d postgres -U postgres -c "SELECT 1"