From 9c40959b4d2773422b851ad76a705417c1d4c86a Mon Sep 17 00:00:00 2001 From: Aquiko <2252346860@qq.com> Date: Tue, 15 Sep 2026 19:11:54 +0800 Subject: [PATCH] fix: resolve reserve() hang with fetch_types disabled With `fetch_types: false`, a queued `reserve()` on a cold pool never settled: the ReadyForQuery handler returned early instead of falling through to `onopen()`, so nothing resolved the reserve. Fall through to match the `fetch_types: true` path, and add a cold-pool regression test. --- src/connection.js | 12 +++++++++--- tests/index.js | 10 ++++++++++ 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/connection.js b/src/connection.js index 10ab1bb..def6e9f 100644 --- a/src/connection.js +++ b/src/connection.js @@ -564,10 +564,16 @@ function Connection(options, queues = {}, { onopen = noop, onend = noop, onclose return fetchArrayTypes() } - initial && !initial.reserve && execute(initial) - options.shared.retries = retries = 0 + if (!initial.reserve) { + execute(initial) + options.shared.retries = retries = 0 + initial = null + return + } + + // `fetch_types: false` with a queued `reserve()` — there is nothing to + // execute, so fall through and let `onopen(connection)` below resolve it. initial = null - return } while (sent.length && (query = sent.shift()) && (query.active = true, query.cancelled)) diff --git a/tests/index.js b/tests/index.js index 845c6ce..e313a66 100644 --- a/tests/index.js +++ b/tests/index.js @@ -2707,6 +2707,16 @@ t('Ensure reserve on query throws proper error', async() => { ] }) +t('reserve with fetch_types: false on a cold pool', async() => { + const sql = postgres({ ...options, fetch_types: false }) // eslint-disable-line + const reserved = await sql.reserve() + const [{ x }] = await reserved`select 1 as x` + reserved.release() + await sql.end() + + return [1, x] +}) + t('query during copy error', async() => { const sql = postgres(options) // eslint-disable-line await sql`create table test (id serial primary key, name text)`