diff --git a/async_postgres/pg_connection/lifecycle.nim b/async_postgres/pg_connection/lifecycle.nim index 775fe44..712127b 100644 --- a/async_postgres/pg_connection/lifecycle.nim +++ b/async_postgres/pg_connection/lifecycle.nim @@ -371,7 +371,7 @@ proc connectToHost*( # Discover extension type OIDs (hstore, etc.) conn.state = csBusy await conn.sendMsg( - encodeQuery("SELECT oid, typarray FROM pg_type WHERE typname = 'hstore' LIMIT 1") + encodeQuery("SELECT oid, typarray FROM pg_type WHERE oid = to_regtype('hstore')") ) block discoverLoop: while true: diff --git a/async_postgres/pg_connection/types.nim b/async_postgres/pg_connection/types.nim index 74205fa..6769aaf 100644 --- a/async_postgres/pg_connection/types.nim +++ b/async_postgres/pg_connection/types.nim @@ -215,7 +215,11 @@ type ## current cache size). Flushed by ``flushPendingStmtCloses`` at the ## start of the next Extended Query send phase so the leak is bounded ## to the gap until the next operation. - hstoreOid*: int32 ## Dynamic OID for hstore extension type; 0 if not available + hstoreOid*: int32 + ## Dynamic OID for the hstore extension type; 0 if not available. + ## Resolved once at connect time via ``to_regtype('hstore')``, which + ## follows the connection's ``search_path`` at that moment. Later + ## ``SET search_path`` changes do not refresh this value. hstoreArrayOid*: int32 ## Dynamic OID for hstore[] array; 0 if not available heldSessionLocks*: int ## Count of session-level `pg_advisory_lock` acquires through the typed diff --git a/tests/test_e2e.nim b/tests/test_e2e.nim index 1f90ac0..9de86f8 100644 --- a/tests/test_e2e.nim +++ b/tests/test_e2e.nim @@ -10519,6 +10519,25 @@ suite "E2E: Numeric / binary / JSON array types": waitFor t() + test "hstore OID discovery respects search_path": + # to_regtype('hstore') must return NULL — and hstoreOid must stay 0 — + # when the connection's startup search_path excludes the schema where + # hstore is installed. Guards against regressing to a typname-only + # lookup that would resolve hstore regardless of search_path. + proc t() {.async.} = + let setup = await connect(plainConfig()) + discard await setup.simpleQuery("CREATE EXTENSION IF NOT EXISTS hstore;") + await setup.close() + + var cfg = plainConfig() + cfg.extraParams = @[("search_path", "pg_catalog")] + let conn = await connect(cfg) + doAssert conn.hstoreOid == 0 + doAssert conn.hstoreArrayOid == 0 + await conn.close() + + waitFor t() + test "bytea array roundtrip": proc t() {.async.} = let conn = await connect(plainConfig())