1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-27 12:41:57 +03:00

Adjust nodeFunctionscan.c to reset transient memory context between calls

to the table function, thus preventing memory leakage accumulation across
calls.  This means that SRFs need to be careful to distinguish permanent
and local storage; adjust code and documentation accordingly.  Patch by
Joe Conway, very minor tweaks by Tom Lane.
This commit is contained in:
Tom Lane
2002-08-29 17:14:33 +00:00
parent 0201dac1c3
commit e4186762ff
10 changed files with 154 additions and 134 deletions

View File

@ -1,5 +1,5 @@
/*
* $Header: /cvsroot/pgsql/contrib/pgstattuple/pgstattuple.c,v 1.7 2002/08/23 08:19:49 ishii Exp $
* $Header: /cvsroot/pgsql/contrib/pgstattuple/pgstattuple.c,v 1.8 2002/08/29 17:14:31 tgl Exp $
*
* Copyright (c) 2001,2002 Tatsuo Ishii
*
@ -25,10 +25,10 @@
#include "postgres.h"
#include "fmgr.h"
#include "funcapi.h"
#include "access/heapam.h"
#include "access/transam.h"
#include "catalog/namespace.h"
#include "funcapi.h"
#include "utils/builtins.h"
@ -41,19 +41,19 @@ extern Datum pgstattuple(PG_FUNCTION_ARGS);
* returns live/dead tuples info
*
* C FUNCTION definition
* pgstattuple(TEXT) returns setof pgstattuple_view
* see pgstattuple.sql for pgstattuple_view
* pgstattuple(text) returns pgstattuple_type
* see pgstattuple.sql for pgstattuple_type
* ----------
*/
#define DUMMY_TUPLE "pgstattuple_view"
#define DUMMY_TUPLE "pgstattuple_type"
#define NCOLUMNS 9
#define NCHARS 32
Datum
pgstattuple(PG_FUNCTION_ARGS)
{
text *relname;
text *relname = PG_GETARG_TEXT_P(0);
RangeVar *relrv;
Relation rel;
HeapScanDesc scan;
@ -71,62 +71,30 @@ pgstattuple(PG_FUNCTION_ARGS)
double dead_tuple_percent;
uint64 free_space = 0; /* free/reusable space in bytes */
double free_percent; /* free/reusable space in % */
FuncCallContext *funcctx;
int call_cntr;
int max_calls;
TupleDesc tupdesc;
TupleTableSlot *slot;
AttInMetadata *attinmeta;
char **values;
int i;
Datum result;
char **values;
int i;
Datum result;
/*
* Build a tuple description for a pgstattupe_type tuple
*/
tupdesc = RelationNameGetTupleDesc(DUMMY_TUPLE);
/* stuff done only on the first call of the function */
if(SRF_IS_FIRSTCALL())
{
/* create a function context for cross-call persistence */
funcctx = SRF_FIRSTCALL_INIT();
/* total number of tuples to be returned */
funcctx->max_calls = 1;
/*
* Build a tuple description for a pgstattupe_view tuple
*/
tupdesc = RelationNameGetTupleDesc(DUMMY_TUPLE);
/* allocate a slot for a tuple with this tupdesc */
slot = TupleDescGetSlot(tupdesc);
/* assign slot to function context */
funcctx->slot = slot;
/*
* Generate attribute metadata needed later to produce tuples from raw
* C strings
*/
attinmeta = TupleDescGetAttInMetadata(tupdesc);
funcctx->attinmeta = attinmeta;
}
/* allocate a slot for a tuple with this tupdesc */
slot = TupleDescGetSlot(tupdesc);
/* stuff done on every call of the function */
funcctx = SRF_PERCALL_SETUP();
call_cntr = funcctx->call_cntr;
max_calls = funcctx->max_calls;
slot = funcctx->slot;
attinmeta = funcctx->attinmeta;
/* Are we done? */
if (call_cntr >= max_calls)
{
SRF_RETURN_DONE(funcctx);
}
/*
* Generate attribute metadata needed later to produce tuples from raw
* C strings
*/
attinmeta = TupleDescGetAttInMetadata(tupdesc);
/* open relation */
relname = PG_GETARG_TEXT_P(0);
relrv = makeRangeVarFromNameList(textToQualifiedNameList(relname,"pgstattuple"));
relrv = makeRangeVarFromNameList(textToQualifiedNameList(relname,
"pgstattuple"));
rel = heap_openrv(relrv, AccessShareLock);
nblocks = RelationGetNumberOfBlocks(rel);
@ -223,5 +191,5 @@ pgstattuple(PG_FUNCTION_ARGS)
}
pfree(values);
SRF_RETURN_NEXT(funcctx, result);
PG_RETURN_DATUM(result);
}