Skip to content

Commit cc208ca

Browse files
committed
Simplify custom type autoloading with pgxpool
Provide a backwards-compatible configuration option for pgxpool which streamlines the use of the bulk loading and registration of types: - ReuseTypeMaps: if enabled, pgxpool will cache the typemap information, avoiding the need to perform any further queries as new connections are created. ReuseTypeMaps is disabled by default as in some situations, a connection string might resolve to a pool of servers which do not share the same type name -> OID mapping.
1 parent b8b9930 commit cc208ca

File tree

2 files changed

+36
-0
lines changed

2 files changed

+36
-0
lines changed

conn.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,12 @@ type ConnConfig struct {
4444

4545
// automatically call LoadTypes with these values
4646
AutoLoadTypes []string
47+
48+
// TypeRegistrationMap is used to register types which require special operations.
49+
// The type name is the key, the value is a function which will be called for each
50+
// connection, providing the OID of that type name for that connection.
51+
// The function will manipulate conn.TypeMap() in some way.
52+
TypeRegistrationMap map[string]CustomRegistrationFunction
4753
}
4854

4955
// ParseConfigOptions contains options that control how a config is built such as getsslpassword.

derived_types.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ import (
1010
"github.com/jackc/pgx/v5/pgtype"
1111
)
1212

13+
// CustomRegistrationFunction is capable of registering whatever is necessary for
14+
// a custom type. It is provided with the backend's OID for this type.
15+
type CustomRegistrationFunction func(ctx context.Context, m *pgtype.Map, oid uint32) error
16+
1317
/*
1418
buildLoadDerivedTypesSQL generates the correct query for retrieving type information.
1519
@@ -254,3 +258,29 @@ func serverVersion(c *Conn) (int64, error) {
254258
}
255259
return serverVersion, nil
256260
}
261+
262+
func fetchOidMapForCustomRegistration(ctx context.Context, conn *Conn) (map[string]uint32, error) {
263+
sql := `
264+
SELECT oid, typname
265+
FROM pg_type
266+
WHERE typname = ANY($1)`
267+
result := make(map[string]uint32)
268+
typeNames := make([]string, 0, len(conn.config.TypeRegistrationMap))
269+
for typeName := range conn.config.TypeRegistrationMap {
270+
typeNames = append(typeNames, typeName)
271+
}
272+
rows, err := conn.Query(ctx, sql, typeNames)
273+
if err != nil {
274+
return nil, fmt.Errorf("While collecting OIDs for custom registrations: %w", err)
275+
}
276+
defer rows.Close()
277+
var typeName string
278+
var oid uint32
279+
for rows.Next() {
280+
if err := rows.Scan(&typeName, &oid); err != nil {
281+
return nil, fmt.Errorf("While scanning a row for custom registrations: %w", err)
282+
}
283+
result[typeName] = oid
284+
}
285+
return result, nil
286+
}

0 commit comments

Comments
 (0)