stdlib: Do not reuse ConnConfig strings

Previously, stdlib.RegisterConnConfig would sometimes reuse the same connection
string for different ConnConfig options (specifically, it happened when a connection
was open and then closed, and then a new, different connection was opened). This
behavior interferes with callers that expect that two connections with the same data
source name are connecting to the same backend database in the same way.

This fix updates stdlib.RegisterConnConfig to use an incrementing sequence
counter to uniquify all returned connection strings.

Fixes #947
pull/988/head
Andrew Kimball 2021-04-01 21:27:32 -07:00 committed by Jack Christensen
parent 88ede6efb5
commit 3ab8941921
2 changed files with 10 additions and 1 deletions

View File

@ -169,6 +169,7 @@ func GetDefaultDriver() driver.Driver {
type Driver struct {
configMutex sync.Mutex
configs map[string]*pgx.ConnConfig
sequence int
}
func (d *Driver) Open(name string) (driver.Conn, error) {
@ -188,7 +189,8 @@ func (d *Driver) OpenConnector(name string) (driver.Connector, error) {
func (d *Driver) registerConnConfig(c *pgx.ConnConfig) string {
d.configMutex.Lock()
connStr := fmt.Sprintf("registeredConnConfig%d", len(d.configs))
connStr := fmt.Sprintf("registeredConnConfig%d", d.sequence)
d.sequence++
d.configs[connStr] = c
d.configMutex.Unlock()
return connStr

View File

@ -1067,8 +1067,15 @@ func TestRegisterConnConfig(t *testing.T) {
logger := &testLogger{}
connConfig.Logger = logger
// Issue 947: Register and unregister a ConnConfig and ensure that the
// returned connection string is not reused.
connStr := stdlib.RegisterConnConfig(connConfig)
require.Equal(t, "registeredConnConfig0", connStr)
stdlib.UnregisterConnConfig(connStr)
connStr = stdlib.RegisterConnConfig(connConfig)
defer stdlib.UnregisterConnConfig(connStr)
require.Equal(t, "registeredConnConfig1", connStr)
db, err := sql.Open("pgx", connStr)
require.NoError(t, err)