@@ -216,8 +216,9 @@ typedef struct
216
216
{
217
217
AutoprepareStatementKey key ;
218
218
CachedPlanSource * plan ;
219
- dlist_node lru ; /* double linked list to implement LRU */
220
- int64 exec_count ; /* counter of execution of this query */
219
+ dlist_node lru ; /* double linked list to implement LRU */
220
+ int64 exec_count ; /* counter of execution of this query */
221
+ Size used_memory ; /* memory used by prepared statement */
221
222
} AutoprepareStatement ;
222
223
223
224
static AutoprepareStatement * autoprepare_stmt ;
@@ -255,14 +256,6 @@ static int autoprepare_match_fn(const void *key1, const void *key2, Size keysize
255
256
return strcmp (ask1 -> query_string , ask2 -> query_string );
256
257
}
257
258
258
- static Size
259
- get_memory_context_size (MemoryContext ctx )
260
- {
261
- MemoryContextCounters counters = {0 };
262
- ctx -> methods -> stats (ctx , NULL , NULL , & counters );
263
- return counters .totalspace ;
264
- }
265
-
266
259
/*
267
260
* This set returning function reads all the autoprepared statements and
268
261
* returns a set of (name, statement, prepare_time, param_types, from_sql).
@@ -295,13 +288,15 @@ pg_autoprepared_statement(PG_FUNCTION_ARGS)
295
288
* build tupdesc for result tuples. This must match the definition of the
296
289
* pg_prepared_statements view in system_views.sql
297
290
*/
298
- tupdesc = CreateTemplateTupleDesc (3 );
291
+ tupdesc = CreateTemplateTupleDesc (4 );
299
292
TupleDescInitEntry (tupdesc , (AttrNumber ) 1 , "statement" ,
300
293
TEXTOID , -1 , 0 );
301
294
TupleDescInitEntry (tupdesc , (AttrNumber ) 2 , "parameter_types" ,
302
295
REGTYPEARRAYOID , -1 , 0 );
303
296
TupleDescInitEntry (tupdesc , (AttrNumber ) 3 , "exec_count" ,
304
297
INT8OID , -1 , 0 );
298
+ TupleDescInitEntry (tupdesc , (AttrNumber ) 4 , "used_memory" ,
299
+ INT8OID , -1 , 0 );
305
300
306
301
/*
307
302
* We put all the tuples into a tuplestore in one scan of the hashtable.
@@ -325,14 +320,15 @@ pg_autoprepared_statement(PG_FUNCTION_ARGS)
325
320
{
326
321
if (autoprep_stmt -> plan != NULL )
327
322
{
328
- Datum values [3 ];
329
- bool nulls [3 ];
323
+ Datum values [4 ];
324
+ bool nulls [4 ];
330
325
MemSet (nulls , 0 , sizeof (nulls ));
331
326
332
327
values [0 ] = CStringGetTextDatum (autoprep_stmt -> key .query_string );
333
328
values [1 ] = build_regtype_array (autoprep_stmt -> key .param_types ,
334
329
autoprep_stmt -> key .num_params );
335
330
values [2 ] = Int64GetDatum (autoprep_stmt -> exec_count );
331
+ values [3 ] = Int64GetDatum (autoprep_stmt -> used_memory );
336
332
337
333
tuplestore_putvalues (tupstore , tupdesc , values , nulls );
338
334
}
@@ -1597,9 +1593,10 @@ exec_parse_message(const char *query_string, /* string to execute */
1597
1593
{
1598
1594
/* Drop invalidated plan: it will be reconstructed later */
1599
1595
if (autoprepare_memory_limit )
1600
- autoprepare_used_memory -= get_memory_context_size ( autoprepare_stmt -> plan -> context ) ;
1596
+ autoprepare_used_memory -= autoprepare_stmt -> used_memory ;
1601
1597
DropCachedPlan (autoprepare_stmt -> plan );
1602
1598
autoprepare_stmt -> plan = NULL ;
1599
+ autoprepare_stmt -> used_memory = 0 ;
1603
1600
}
1604
1601
else
1605
1602
{
@@ -1612,6 +1609,7 @@ exec_parse_message(const char *query_string, /* string to execute */
1612
1609
/* Initialize autoprepare hash entry */
1613
1610
autoprepare_cached_plans += 1 ;
1614
1611
autoprepare_stmt -> plan = NULL ;
1612
+ autoprepare_stmt -> used_memory = 0 ;
1615
1613
autoprepare_stmt -> exec_count = 1 ;
1616
1614
1617
1615
/* Copy query text and parameter type info to CacheMemoryContext */
@@ -1629,7 +1627,7 @@ exec_parse_message(const char *query_string, /* string to execute */
1629
1627
if (victim -> plan )
1630
1628
{
1631
1629
if (autoprepare_memory_limit )
1632
- autoprepare_used_memory -= get_memory_context_size ( victim -> plan -> context ) ;
1630
+ autoprepare_used_memory -= victim -> used_memory ;
1633
1631
DropCachedPlan (victim -> plan );
1634
1632
}
1635
1633
hash_search (autoprepare_hash , victim , HASH_REMOVE , NULL );
@@ -1795,7 +1793,11 @@ exec_parse_message(const char *query_string, /* string to execute */
1795
1793
{
1796
1794
SaveCachedPlan (psrc );
1797
1795
if (autoprepare_stmt )
1796
+ {
1798
1797
autoprepare_stmt -> plan = psrc ;
1798
+ autoprepare_stmt -> used_memory = CachedPlanMemoryUsage (autoprepare_stmt -> plan );
1799
+ autoprepare_used_memory += autoprepare_stmt -> used_memory ;
1800
+ }
1799
1801
else
1800
1802
/*
1801
1803
* We just save the CachedPlanSource into unnamed_stmt_psrc.
0 commit comments