Skip to content

Commit c219a40

Browse files
committed
Correct the check for the use of unnamed statement by introspection
1 parent dccb430 commit c219a40

File tree

2 files changed

+31
-15
lines changed

2 files changed

+31
-15
lines changed

asyncpg/connection.py

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,7 @@ async def _get_statement(self, query, timeout, *, named: bool=False):
272272
# Only use the cache when:
273273
# * `statement_cache_size` is greater than 0;
274274
# * query size is less than `max_cacheable_statement_size`.
275-
use_cache = cache_enabled = self._stmt_cache.get_max_size() > 0
275+
use_cache = self._stmt_cache.get_max_size() > 0
276276
if (use_cache and
277277
self._config.max_cacheable_statement_size and
278278
len(query) > self._config.max_cacheable_statement_size):
@@ -286,13 +286,13 @@ async def _get_statement(self, query, timeout, *, named: bool=False):
286286
statement = await self._protocol.prepare(stmt_name, query, timeout)
287287
ready = statement._init_types()
288288
if ready is not True:
289-
types = await self.__execute(self._intro_query, (list(ready),),
290-
0, timeout)
289+
types, intro_stmt = await self.__execute(
290+
self._intro_query, (list(ready),), 0, timeout)
291291
self._protocol.get_settings().register_data_types(types)
292-
if not cache_enabled:
293-
# The execution of the introspection query with statement
294-
# cache turned off has blown away the anonymous statement
295-
# we've prepared for the query, so we need to re-prepare it.
292+
if not intro_stmt.name and not statement.name:
293+
# The introspection query has used an anonymous statement,
294+
# which has blown away the anonymous statement we've prepared
295+
# for the query, so we need to re-prepare it.
296296
statement = await self._protocol.prepare(
297297
stmt_name, query, timeout)
298298

@@ -1199,8 +1199,9 @@ def _drop_global_statement_cache(self):
11991199

12001200
async def _execute(self, query, args, limit, timeout, return_status=False):
12011201
with self._stmt_exclusive_section:
1202-
return await self.__execute(query, args, limit, timeout,
1203-
return_status=return_status)
1202+
result, _ = await self.__execute(
1203+
query, args, limit, timeout, return_status=return_status)
1204+
return result
12041205

12051206
async def __execute(self, query, args, limit, timeout,
12061207
return_status=False):
@@ -1214,7 +1215,8 @@ async def _executemany(self, query, args, timeout):
12141215
stmt, args, '', timeout)
12151216
timeout = self._protocol._get_timeout(timeout)
12161217
with self._stmt_exclusive_section:
1217-
return await self._do_execute(query, executor, timeout)
1218+
result, _ = await self._do_execute(query, executor, timeout)
1219+
return result
12181220

12191221
async def _do_execute(self, query, executor, timeout, retry=True):
12201222
if timeout is None:
@@ -1263,10 +1265,10 @@ async def _do_execute(self, query, executor, timeout, retry=True):
12631265
if self._protocol.is_in_transaction() or not retry:
12641266
raise
12651267
else:
1266-
result = await self._do_execute(
1268+
return await self._do_execute(
12671269
query, executor, timeout, retry=False)
12681270

1269-
return result
1271+
return result, stmt
12701272

12711273

12721274
async def connect(dsn=None, *,

tests/test_introspection.py

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,7 @@ async def test_introspection_on_large_db(self):
4646
await self.con.fetchval('SELECT $1::int[]', [1, 2])
4747

4848
@tb.with_connection_options(statement_cache_size=0)
49-
async def test_introspection_no_stmt_cache(self):
50-
# Check that type introspection does not use prepared statements
51-
# when the statement cache is disabled.
49+
async def test_introspection_no_stmt_cache_01(self):
5250
self.assertEqual(self.con._stmt_cache.get_max_size(), 0)
5351
await self.con.fetchval('SELECT $1::int[]', [1, 2])
5452

@@ -63,3 +61,19 @@ async def test_introspection_no_stmt_cache(self):
6361
await self.con.execute('''
6462
DROP EXTENSION hstore
6563
''')
64+
65+
@tb.with_connection_options(max_cacheable_statement_size=1)
66+
async def test_introspection_no_stmt_cache_02(self):
67+
await self.con.fetchval('SELECT $1::int[]', [1, 2])
68+
69+
await self.con.execute('''
70+
CREATE EXTENSION IF NOT EXISTS hstore
71+
''')
72+
73+
try:
74+
await self.con.set_builtin_type_codec(
75+
'hstore', codec_name='pg_contrib.hstore')
76+
finally:
77+
await self.con.execute('''
78+
DROP EXTENSION hstore
79+
''')

0 commit comments

Comments
 (0)