`run_sql` leaks session state across requests in Postgres
Version Information
Server Version: 2.48.5 CLI Version (for CLI related issue): n/a
Environment
OSS
What is the current behaviour?
Any session-scoped state established within a run_sql request persists on the underlying Postgres connection after the request finishes, and is inherited by subsequent, unrelated requests — including GraphQL query execution — that reuse that connection from the pool. The engine performs no session reset (DISCARD / RESET ALL) when returning a connection to the pool.
One way this issue can manifest is via migrations. For example, let's say your migration contains a SET statement_timeout to limit how long your DDL can run. That statement_timeout will be applied to subsequent queries on that session until connection_lifetime or a similar setting kills the session.
What is the expected behaviour?
A session change made by one request should not affect subsequent, unrelated requests.
How to reproduce the issue?
- Configure a single Postgres source with
pool_settings.max_connections: 1. This forces connection reuse so the leak is deterministic. With a larger pool the leak still occurs, just nondeterministically on whichever connection ran the statement. - Call
run_sqland do something that modifies the session. E.g.SET statement_timeout = '1ms'. - Call
run_sqlagain and observe thatstatement_timeoutis now 1ms.
Screenshots or Screencast
Please provide any traces or logs that could help here.
Any possible solutions/workarounds you're aware of?
Hasura could call DISCARD ALL before returning connections to its pool. In lieu of that, it's up to callers to do that themselves in the SQL they run. But that is easier said then done:
-- Assume this is a migration that is not wrapped in a transaction.
SET statement_timeout = 1000;
-- Assume this times out
CREATE INDEX CONCURRENTLY ...;
-- This won't run
RESET statement_timeoutKeywords
Source: hasura/graphql-engine