44 "context"
55 "fmt"
66 "math/rand"
7+ "os"
78 "runtime"
89 "strconv"
910 "sync"
@@ -12,14 +13,17 @@ import (
1213
1314 "github.com/jackc/pgx/v5"
1415 "github.com/jackc/pgx/v5/pgconn"
16+ "github.com/jackc/pgx/v5/pgtype"
1517 "github.com/jackc/puddle/v2"
1618)
1719
18- var defaultMaxConns = int32 (4 )
19- var defaultMinConns = int32 (0 )
20- var defaultMaxConnLifetime = time .Hour
21- var defaultMaxConnIdleTime = time .Minute * 30
22- var defaultHealthCheckPeriod = time .Minute
20+ var (
21+ defaultMaxConns = int32 (4 )
22+ defaultMinConns = int32 (0 )
23+ defaultMaxConnLifetime = time .Hour
24+ defaultMaxConnIdleTime = time .Minute * 30
25+ defaultHealthCheckPeriod = time .Minute
26+ )
2327
2428type connResource struct {
2529 conn * pgx.Conn
@@ -102,6 +106,62 @@ type Pool struct {
102106 closeChan chan struct {}
103107}
104108
109+ // AutoloadAfterConnect is suitable for assigning to the AfterConnect configuration setting.
110+ // It will automatically load the named types for each connection in an efficient manner,
111+ // performing a single query to the database backend. The underlying call to pgx.LoadTypes
112+ // is smart enough to also retrieve any related types required to support the definition of the
113+ // named types.
114+ // If reuseTypeMap is enabled, it is assumed that the OID mapping is stable across all database
115+ // backends in this pool, resulting in only needing to query when creating the initial connection;
116+ // subsequent connections will reuse the same OID type mapping.
117+ // Because it is not always possible for a client to know the database topology in the final usage
118+ // context, PGXPOOL_REUSE_TYPEMAP, when given a value of y or n, will take precedence over this argument.
119+ func AutoloadAfterConnect (typeNames []string , reuseTypeMap bool ) func (context.Context , * pgx.Conn ) error {
120+ if envValue := os .Getenv ("PGXPOOL_REUSE_TYPEMAP" ); envValue != "" {
121+ switch envValue {
122+ case "y" :
123+ reuseTypeMap = true
124+ case "n" :
125+ reuseTypeMap = false
126+ }
127+ }
128+ if reuseTypeMap {
129+ mutex := new (sync.Mutex )
130+ var types []* pgtype.Type
131+ return func (ctx context.Context , conn * pgx.Conn ) error {
132+ if types != nil {
133+ // avoid acquiring the mutex if the types are already available
134+ conn .TypeMap ().RegisterTypes (types )
135+ return nil
136+ }
137+ mutex .Lock ()
138+ defer mutex .Unlock ()
139+ var err error
140+
141+ // types may have become available while waiting for the mutex
142+ if types != nil {
143+ conn .TypeMap ().RegisterTypes (types )
144+ return nil
145+ }
146+ types , err = conn .LoadTypes (ctx , typeNames )
147+ if err != nil {
148+ types = nil
149+ return err
150+ }
151+ conn .TypeMap ().RegisterTypes (types )
152+ return nil
153+ }
154+ }
155+ return func (ctx context.Context , conn * pgx.Conn ) error {
156+ types , err := conn .LoadTypes (ctx , typeNames )
157+ if err != nil {
158+ return err
159+ }
160+ conn .TypeMap ().RegisterTypes (types )
161+ return nil
162+ }
163+ }
164+
105165// Config is the configuration struct for creating a pool. It must be created by [ParseConfig] and then it can be
106166// modified.
107167type Config struct {
0 commit comments