Repository navigation
v1.0.0-rc.12
Pre-releaseFixed
-
Querying a table with a non-builtin PostgreSQL type (custom
enum,
composite, domain, range, or extension type likecitext/ Supabase
auth.uid) no longer hangs on a direct connection (#166, #168) once
the result is large enough to fill tokio-postgres's bounded response
channel — the rc.11 fix only covered the transaction-pooler path. The
direct path now pre-resolves result column types via aprepareon the
shared cached client before thequery_typeddata fetch, so
tokio-postgres's internaltypeinfo_statementresolves in a clean window
(not mid-stream) and the cache hit makesget_typereturn early. Same
mechanism thein_transactionbatch path uses; preserves pool reuse and
has zero overhead on builtin types. -
A batch or interactive-transaction session on a transaction-mode pooler
no longer deadlocks on a wide non-builtin-typed table (#169, #172) — the
rc.11 #166 fix and the rc.10 #164 one-shot path both only covered
non-session single result-set queries.run_batch_in_sessionnow makes
the same per-query routing decision as the single-query path: a
result-set query inside an open transaction pre-resolves on the shared
client (the user'sBEGINpins the backend); one with no open
transaction routes to the one-shot pinned path. The empty-rows
column-discovery fallback is guarded for the session-pinned pooler case. -
A bare batch (no
session_id, noBEGIN) that sets session-local state
in an earlier statement — a sessionSET(notSET LOCAL) or a
CREATE TEMP[ORARY] TABLE— then runs a result-setSELECTno longer
silently loses that state on apooler_mode = transactionconnection
(#173, #174). The rc.11 #172 fix routed theSELECTto a fresh one-shot
connection that never saw theSET/temp table (wrong precision, or
relation does not exist). The fix detects the prior session state and
keeps theSELECTon the shared batch client with a column-type
pre-resolve, restoringmain's within-batch guarantee. Handles the
optional deprecatedGLOBAL/LOCALqualifier beforeTEMP/TEMPORARY
and excludesSET LOCAL/SET TRANSACTION/SET CONSTRAINTS. -
A slow or hung query no longer starves
ping,test_connection,
initialize, and thecancelnotification for every connection (#167,
#176). The plugin had 4 workers fed by a single shared queue; every RPC
type shared them, so 4 stuck calls (any slow query up to the host's 120s
timeout) blocked health checks and new connects to other databases —
and thecancelnotification that's meant to relieve the stuck workers
queued behind them (a deadlock: only quitting Tabularis freed the
workers). RPCs are now routed by method into three lanes before a worker
pulls the line: a dedicated cancel lane (the relief valve, never queued
behind the workers it relieves), a 2-worker lifecycle lane
(ping/test_connection/initialize/shutdown), and the existing
4-worker general lane. TheSHUTDOWN_GRACEdrain (#155) covers all
lanes' worker handles.
Known limitations
-
A bare
[SET, SELECT]or[CREATE TEMP TABLE, SELECT]batch on a
real PgBouncer (pool_mode = transaction, not the direct +
pooler_mode = transactionflag config) can still lose session state
between autocommit statements (pre-existing onmain— the backend is
reassigned per transaction) and, in rare cases with non-builtin result
column types under backend reassignment during the pre-resolve
prepare, can hang (#175). Wrap such batches in explicit
BEGIN/COMMITto pin the backend. Tracked as a follow-up; the
direct +pooler_mode = transactionconfig (the common use) is
unaffected. -
A
SELECTagainst a table with a composite type that isALTER TYPE-ed
(same OID, new field layout) on a recycled pooled connection can read a
stale cachedTypeand produce wrong JSON for the composite's fields
(#171). Pre-existing (a tokio-postgres/deadpool cache-invalidation
limitation the plugin inherited); the rc.11/#168 pre-resolve widened the
cache-warming window but did not introduce the bug. Tracked as a
follow-up pending investigation of tokio-postgres'sclear_type_cache
API.