You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Bug: Regression in plugin v1.0.0-rc.10 table hangs while opening but works in v1.0.0-rc.8 #160
Accessing the users table hangs for over 120 seconds and then fails after upgrading from plugin v1.0.0-rc.8 to v1.0.0-rc.10 (v1.0.0-rc.9 is also affected). Other tables in the same database open normally.
Direct SQL queries against the users table also hang in v1.0.0-rc.10, while the same table and queries work fine in PgAdmin 4. Downgrading to v1.0.0-rc.8 restores normal behavior.
This appears to be a regression introduced between v1.0.0-rc.8 and v1.0.0-rc.9/rc.10. The users table has many columns, which may be related.
@judeVector — Thanks for the detailed report — this is a real regression and we've traced it. It was introduced in rc.9 (#149, which switched queries to the unnamed extended-query protocol for PgBouncer safety). On Supabase's transaction-mode pooler that protocol hangs where rc.8's two-round-trip named path worked. We have a fix in mind but want to confirm one thing before shipping it.
Three quick items:
1. Which Supabase endpoint are you on? Paste the host:port from your Tabularis connection (redact the project ref if you like — the form is what matters):
…pooler.supabase.com:6543 = transaction mode
…pooler.supabase.com:5432 = session mode
db.…supabase.co:5432 = direct
2. The exact error text when the hang finally fails (~120s in). Your screenshots didn't come through as text — could you paste it verbatim? Specifically whether it mentions "prepared statement", "timeout", a 5-digit SQLSTATE code (e.g. 26000), or "connection".
3. Direct-connection test (~2 min, the most useful one): With plugin rc.10 still installed, create a second PostgreSQL connection in Tabularis pointing at Supabase's direct endpoint — db.<project-ref>.supabase.co, port 5432, same database/user/password. You'll find it in the Supabase Dashboard → Project Settings → Database → "Connection string" → the Direct connection tab (not "Transaction pooler"). Open the users table through that direct connection.
Opens fine → confirms the hang is pooler-specific (matches our diagnosis).
Still hangs → tells us something different is going on and we'll dig further.
Once we have those, we can ship the fix with confidence. Workaround until then: stay on rc.8, or connect through the direct endpoint (which avoids the pooler entirely).
Error: Plugin call 'execute_query' timed out after 120s
Connection test results
Session pooler (*.pooler.supabase.com:5432): Connects successfully, but querying the users table hangs and times out after 120s.
Transaction pooler (*.pooler.supabase.com:6543): Connects successfully, but querying the users table still hangs and times out.
Direct connection (*.supabase.co:5432): Fails to connect entirely (error connecting to server).
Summary
Both the session pooler (:5432) and the transaction pooler (:6543) can establish a connection, but neither can successfully query the users table (timeout after 120s). The direct connection fails to connect at all.
@judeVector — really helpful, thanks. Two things jump out:
The timeout message (Plugin call 'execute_query' timed out after 120s) tells us the query never returned at all — no PostgreSQL error, just a hang. That matches what we expected.
The session pooler (:5432) hanging too is important and shifts our diagnosis — this isn't specific to transaction-mode pooling. Good that you tested both.
Two more quick tests (same rc.10 + session pooler connection you already have) would let us nail the mechanism:
A. Does a small table in the same database also hang? Pick a table with only a few columns (e.g. a lookup/config table, or any table with ≤5 columns) and open it the same way.
Works fine → the hang is specific to the users table (column count or a column type).
Also hangs → the hang is not size-driven.
B. Does SELECT * FROM users LIMIT 1 hang? Run this in the SQL editor (one row, all columns):
Hangs → the issue is column count / the table's column types, not row count.
Works fine → the issue is row count / streaming the full result set.
If you can run the SQL query directly in Supabase's SQL Editor (or PgAdmin) for comparison and confirm whether SELECT * FROM users returns there, that's also useful — it tells us the table itself is fine and the hang is plugin-side.
These should take about a minute. Once we know whether it's column-driven or row-driven, we can design the fix with confidence rather than guessing.
The fix for this shipped in #164 (merged): result-set queries on connections marked Pooler Mode = "Transaction" now take a pinned one-shot transaction path that clears stale prepared statements and pre-resolves column types while the backend is pinned, then runs the unnamed-protocol data fetch — so tokio-postgres's internal typeinfo_statement no longer collides across pooler backend reassignment (the root cause of the rc.9/rc.10 hang on non-builtin column types).
This is being released today in v1.0.0-rc.11.
Two notes for your Supabase setup:
Mark the connection's Pooler Mode as "Transaction" in Tabularis so the pinned path activates (without it, the query stays on the old path).
Plain PgBouncer gives a clean 42P05 error; the Supavisor hang (vs. error) shares the same underlying hazard, but Supavisor-specific confirmation still needs a real repro. If you still see the hang on rc.11 with Pooler Mode set to Transaction, please open a new issue with the rc.11 plugin version and the table's column types — that would mean the pinned path isn't catching the Supavisor variant and we need a real repro to dig further.
Follow-up: the rc.11 fix (#164) was incomplete — it only pre-resolved column types when Pooler Mode = "Transaction", so direct (non-pooler) connections still hung on a table with a non-builtin column type once the result was larger than a few KB (#166). The root cause is broader than the #164 framing: it's a tokio-postgres interleave (query_typed resolves non-builtin column types mid-stream via the internal typeinfo_statement, deadlocking once the row data fills the channel buffer) that deadlocks on any connection, not just pooler reassignment. The pooler additionally orphans the statement across backend reassignment (42P05), but the hang mechanism is the interleave.
A fix is in progress on fix/direct-enum-hang-166: pre-resolve column types via prepare on the shared cached client for direct connections too (rc.8's behavior, which worked), keeping the #164 pinned one-shot path for poolers. If the hang persists after that fix lands, please open a new issue.
Thanks for following up on this! I did notice that the issue was still present after updating to rc.11, but after rc.12 was released, everything started working as expected.
I really appreciate the continued investigation, the detailed explanations, and the quick turnaround on the fixes. Thanks for sticking with this until it was resolved!
Activity
judeVector commentedon Oct 17, 2026
After downgrading
aesslinger commentedon Oct 17, 2026
@judeVector — Thanks for the detailed report — this is a real regression and we've traced it. It was introduced in rc.9 (#149, which switched queries to the unnamed extended-query protocol for PgBouncer safety). On Supabase's transaction-mode pooler that protocol hangs where rc.8's two-round-trip named path worked. We have a fix in mind but want to confirm one thing before shipping it.
Three quick items:
1. Which Supabase endpoint are you on? Paste the
host:portfrom your Tabularis connection (redact the project ref if you like — the form is what matters):…pooler.supabase.com:6543= transaction mode…pooler.supabase.com:5432= session modedb.…supabase.co:5432= direct2. The exact error text when the hang finally fails (~120s in). Your screenshots didn't come through as text — could you paste it verbatim? Specifically whether it mentions "prepared statement", "timeout", a 5-digit SQLSTATE code (e.g.
26000), or "connection".3. Direct-connection test (~2 min, the most useful one): With plugin rc.10 still installed, create a second PostgreSQL connection in Tabularis pointing at Supabase's direct endpoint —
db.<project-ref>.supabase.co, port5432, same database/user/password. You'll find it in the Supabase Dashboard → Project Settings → Database → "Connection string" → the Direct connection tab (not "Transaction pooler"). Open theuserstable through that direct connection.Once we have those, we can ship the fix with confidence. Workaround until then: stay on rc.8, or connect through the direct endpoint (which avoids the pooler entirely).
judeVector commentedon Oct 18, 2026
Alright, here are the results I have
Supabase endpoint:
pooler.supabase.com:5432(session pooler)Error
Error: Plugin call 'execute_query' timed out after 120s
Connection test results
*.pooler.supabase.com:5432): Connects successfully, but querying theuserstable hangs and times out after 120s.*.pooler.supabase.com:6543): Connects successfully, but querying theuserstable still hangs and times out.*.supabase.co:5432): Fails to connect entirely (error connecting to server).Summary
Both the session pooler (
:5432) and the transaction pooler (:6543) can establish a connection, but neither can successfully query theuserstable (timeout after 120s). The direct connection fails to connect at all.aesslinger commentedon Oct 19, 2026
@judeVector — really helpful, thanks. Two things jump out:
Plugin call 'execute_query' timed out after 120s) tells us the query never returned at all — no PostgreSQL error, just a hang. That matches what we expected.:5432) hanging too is important and shifts our diagnosis — this isn't specific to transaction-mode pooling. Good that you tested both.Two more quick tests (same rc.10 + session pooler connection you already have) would let us nail the mechanism:
A. Does a small table in the same database also hang? Pick a table with only a few columns (e.g. a lookup/config table, or any table with ≤5 columns) and open it the same way.
userstable (column count or a column type).B. Does
SELECT * FROM users LIMIT 1hang? Run this in the SQL editor (one row, all columns):If you can run the SQL query directly in Supabase's SQL Editor (or PgAdmin) for comparison and confirm whether
SELECT * FROM usersreturns there, that's also useful — it tells us the table itself is fine and the hang is plugin-side.These should take about a minute. Once we know whether it's column-driven or row-driven, we can design the fix with confidence rather than guessing.
fix: pin backend for transaction-pooler result queries (#160, #163)
test: cover pooler_error_lead phrasing + pooler_mode whitespace (#160, …
refactor: parameterize build_search_path_sql + fix pinned-txn doc dri…
test: guard routing false side + correct vacuous discard-claim comment (
fix: skip redundant startup-script preflight on one-shot pool path (#160
fix: pin backend for transaction-pooler result queries on non-builtin…
aesslinger commentedon Oct 22, 2026
The fix for this shipped in #164 (merged): result-set queries on connections marked Pooler Mode = "Transaction" now take a pinned one-shot transaction path that clears stale prepared statements and pre-resolves column types while the backend is pinned, then runs the unnamed-protocol data fetch — so tokio-postgres's internal
typeinfo_statementno longer collides across pooler backend reassignment (the root cause of the rc.9/rc.10 hang on non-builtin column types).This is being released today in
v1.0.0-rc.11.Two notes for your Supabase setup:
42P05error; the Supavisor hang (vs. error) shares the same underlying hazard, but Supavisor-specific confirmation still needs a real repro. If you still see the hang on rc.11 with Pooler Mode set to Transaction, please open a new issue with the rc.11 plugin version and the table's column types — that would mean the pinned path isn't catching the Supavisor variant and we need a real repro to dig further.chore: release 1.0.0-rc.11
chore: release 1.0.0-rc.11 (#165)
aesslinger commentedon Oct 23, 2026
Follow-up: the rc.11 fix (#164) was incomplete — it only pre-resolved column types when Pooler Mode = "Transaction", so direct (non-pooler) connections still hung on a table with a non-builtin column type once the result was larger than a few KB (#166). The root cause is broader than the #164 framing: it's a tokio-postgres interleave (
query_typedresolves non-builtin column types mid-stream via the internaltypeinfo_statement, deadlocking once the row data fills the channel buffer) that deadlocks on any connection, not just pooler reassignment. The pooler additionally orphans the statement across backend reassignment (42P05), but the hang mechanism is the interleave.A fix is in progress on
fix/direct-enum-hang-166: pre-resolve column types viaprepareon the shared cached client for direct connections too (rc.8's behavior, which worked), keeping the #164 pinned one-shot path for poolers. If the hang persists after that fix lands, please open a new issue.fix: address pre-handoff-review findings on #173 classifier and routing
fix: keep bare [SET/CREATE TEMP, SELECT] batch on the shared client o…
fix: route ping/connect/cancel to dedicated lanes so stuck queries do…
judeVector commentedon Oct 24, 2026
Thanks for following up on this! I did notice that the issue was still present after updating to
rc.11, but afterrc.12was released, everything started working as expected.I really appreciate the continued investigation, the detailed explanations, and the quick turnaround on the fixes. Thanks for sticking with this until it was resolved!
Thanks again for your help.