- BeforeAcquire now marked as deprecated, and re-implemented in terms of PrepareConn
- PrepareConn now takes precidence over BeforeAcquire if both are provided
- New tests added, so both old and new behavior are tested
- One niggle: AcquireAllIdle does not return an error, so the only recourse
that seems reasonable when PrepareConn returns an error in that context,
is to destroy the connection. This more or less retains the spirit of
existing functionality, without changing the public API of that method.
Although maybe an error-returning variant would be a useful addition as
well.
Previously, PlanScan used a cache to improve performance. However, the
cache could get confused in certain cases. For example, the following
would fail:
m := pgtype.NewMap()
var err error
var tags any
err = m.Scan(pgtype.TextArrayOID, pgx.TextFormatCode, []byte("{foo,bar,baz}"), &tags)
require.NoError(t, err)
var cells [][]string
err = m.Scan(pgtype.TextArrayOID, pgx.TextFormatCode, []byte("{{foo,bar},{baz,quz}}"), &cells)
require.NoError(t, err)
This commit removes the memoization and adds a test to ensure that this
case works.
The benchmarks were also updated to include an array of strings to
ensure this path is benchmarked. As it turned out, there was next to no
performance difference between the cached and non-cached versions.
It's possible there may be a performance impact in certain complicated
cases, but I have not encountered any. If there are any performance
issues, we can optimize the narrower case rather than adding memoization
everywhere.
Previously, a conn.Write would simply unlock pgconn, leaving the
connection as Idle and reusable while the multiResultReader would be
closed. From this state, calling multiResultReader.Close won't try to
receiveMessage and thus won't unwatch and close the connection since it
is already closed. This leaves the connection "open" and the next time
it's used, a "Watch already in progress" panic could be triggered.
This patch fixes the issue by unwatching and closing the connection on a
batch write error. The same was done on Sync.Encode error even if the
path is unreachable as Sync.Error never returns an error.