dataPool() function

A connection pool whose arrays of enums and JSON columns can be read.

Signature:

export declare function dataPool(config: PoolConfig, parsers?: TypeParsers): Pool;

Parameters

Parameter

Type

Description

config

PoolConfig

Pool configuration, as pg takes it.

parsers

TypeParsers

(Optional) The registry to register in. Defaults to this package's own, which is right whenever there is one copy of pg to have; a consumer that resolves the ORM through a different copy has to say so, because a parser added to the wrong registry is never read.

Returns:

Pool

The pool.

Remarks

node-postgres parses a value by its type's oid, and it knows only the built-in ones. An enum is numbered when it is created, so its array type is numbered too, and neither number can be known ahead of time — the driver therefore hands back the literal text {EMAIL,SMS} where the ORM requires an array, and every read of the column fails with RUNTIME.DECODE_FAILED. A scalar enum is unaffected, because its text *is* its value.

So the oids are asked for, once, and those columns are parsed the way a text[] is — which is what an array of enums is on the wire. The JSON types are corrected at the same time, for the reason on .

The lookup is deferred to the first connection rather than done here, because a pool is built where a client is built and that is not a place where anything can be awaited. It runs once; a query that arrives while it is in flight waits for it rather than starting a second one.

The registry is the one the *runtime* reads, not the one a pool carries: the ORM passes its own types to every query, and that object falls through to pg-types for anything it does not handle itself. A parser set on the pool is therefore never consulted.

Three things follow from the registry being global. A raw pg query in the same process reads a JSON column as text and has to parse it itself, which is the trade for the ORM reading it correctly. An enum type created *after* the first connection is not picked up — which is a migration applied to a running process, and migrations run at start, before anything connects. And a process holding pools onto two different databases would have them share one numbering, which no service here does: a service owns one database.

Example

const db = postgres<Contract>({
    contractJson,
    pg: dataPool({ connectionString }),
});

Read this page as plain markdown — no HTML, no navigation. For pasting into an LLM, or for an agent to fetch.