Skip to content

Commit bcee690

Browse files
committed
Allow pgxpool to more easily use LoadTypes
While LoadTypes is powerful on its own, retriving all salient type information in a single query, it is particularly powerful and useful when users of pgxpool can use this. To streamline its use, provide a helper function in pgxpool suitable for plugging directly into the AfterConnect configuration settings. It will load the types and register them, also reusing them if appropriate.
1 parent 7f85b19 commit bcee690

File tree

1 file changed

+63
-5
lines changed

1 file changed

+63
-5
lines changed

pgxpool/pool.go

Lines changed: 63 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
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

2428
type connResource struct {
2529
conn *pgx.Conn
@@ -102,6 +106,60 @@ 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+
switch os.Getenv("PGXPOOL_REUSE_TYPEMAP") {
121+
case "y":
122+
reuseTypeMap = true
123+
case "n":
124+
reuseTypeMap = false
125+
}
126+
if reuseTypeMap {
127+
mutex := new(sync.Mutex)
128+
var types []*pgtype.Type
129+
return func(ctx context.Context, conn *pgx.Conn) error {
130+
if types != nil {
131+
// avoid acquiring the mutex if the types are already available
132+
conn.TypeMap().RegisterTypes(types)
133+
return nil
134+
}
135+
mutex.Lock()
136+
defer mutex.Unlock()
137+
var err error
138+
139+
// types may have become available while waiting for the mutex
140+
if types != nil {
141+
conn.TypeMap().RegisterTypes(types)
142+
return nil
143+
}
144+
types, err = conn.LoadTypes(ctx, typeNames)
145+
if err != nil {
146+
types = nil
147+
return err
148+
}
149+
conn.TypeMap().RegisterTypes(types)
150+
return nil
151+
}
152+
}
153+
return func(ctx context.Context, conn *pgx.Conn) error {
154+
types, err := conn.LoadTypes(ctx, typeNames)
155+
if err != nil {
156+
return err
157+
}
158+
conn.TypeMap().RegisterTypes(types)
159+
return nil
160+
}
161+
}
162+
105163
// Config is the configuration struct for creating a pool. It must be created by [ParseConfig] and then it can be
106164
// modified.
107165
type Config struct {

0 commit comments

Comments
 (0)