Conversation
For a DSN such as postgresql://user@host/db?port=6432, the host list parser filled in the default port 5432 for the host, and the port query parameter was then ignored because a port was already set. The connection went to port 5432 instead of 6432. libpq, and asyncpg before multi-host support was added in v0.18.0, use the query parameter. Only an explicit port argument now takes precedence over the port query parameter; the query parameter overrides ports from the DSN host list.
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
A
portquery parameter is ignored when the DSN also has a host:connects to
db.internal:5432, not 6432._parse_hostlist()fills in the default port for every host in the DSN netloc, and the laterif 'port' in querybranch only applies the parameterif not port, which is never true at that point. This is easy to hit with a pgbouncer or a non-default port, and when something is listening on 5432 the connection silently goes to the wrong server. libpq uses the query parameter (psql "postgresql://postgres@127.0.0.1/postgres?port=54971"connects to 54971, and a queryportalso overrides a port in the netloc). asyncpg did too before multi-host support was added in v0.18.0.The fix remembers whether a
portargument was passed toconnect()before the netloc is parsed. Only that explicit argument still wins over the query parameter; the query parameter now overrides ports from the DSN host list, including a per-host list likehost1,host2/db?port=6432,6433.Tests: four new
TestConnectParamscases (?port=with a single host, overriding a netloc port, with multiple hosts, and an explicitportargument still winning). They fail on master (('host', 5432)instead of('host', 6432)) and pass with the fix. End to end, checked against a local PostgreSQL 16 on a non-default port: master fails with "Connect call failed ('127.0.0.1', 5432)", the fix connects.python -m unittest tests.test_connect tests.test_pool tests.test__sourcecodepasses (117 tests, 4 skipped, flake8 and mypy included).This bug was found and the fix prepared by an AI agent (breken-ai); the reproduction and all tests above were run before opening the PR.