summaryrefslogtreecommitdiff
path: root/contrib/pgstattuple
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2002-08-29 17:14:33 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2002-08-29 17:14:33 +0000
commite4186762ffaa4188e16702e8f4f299ea70988b96 (patch)
tree2ee78b84ead113ad17b029743432c24a37a362f9 /contrib/pgstattuple
parent0201dac1c319599aad3feb752d7ee5162200e2c7 (diff)
downloadpostgresql-e4186762ffaa4188e16702e8f4f299ea70988b96.tar.gz
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.
Diffstat (limited to 'contrib/pgstattuple')
-rw-r--r--contrib/pgstattuple/README.pgstattuple10
-rw-r--r--contrib/pgstattuple/pgstattuple.c78
-rw-r--r--contrib/pgstattuple/pgstattuple.sql.in26
3 files changed, 41 insertions, 73 deletions
diff --git a/contrib/pgstattuple/README.pgstattuple b/contrib/pgstattuple/README.pgstattuple
index 804c37c6a9..42a7fc2165 100644
--- a/contrib/pgstattuple/README.pgstattuple
+++ b/contrib/pgstattuple/README.pgstattuple
@@ -1,4 +1,4 @@
-pgstattuple README 2002/08/22 Tatsuo Ishii
+pgstattuple README 2002/08/29 Tatsuo Ishii
1. What is pgstattuple?
@@ -40,15 +40,15 @@ free_percent -- free space in %
3. Using pgstattuple
- pgstattuple may be called as a SRF (set returning function) and is
+ pgstattuple may be called as a table function and is
defined as follows:
- CREATE OR REPLACE FUNCTION pgstattuple(text) RETURNS SETOF pgstattuple_view
+ CREATE OR REPLACE FUNCTION pgstattuple(text) RETURNS pgstattuple_type
AS 'MODULE_PATHNAME', 'pgstattuple'
LANGUAGE 'c' WITH (isstrict);
- The argument is the table name. Note that pgstattuple never
- returns more than 1 tuple.
+ The argument is the table name. Note that pgstattuple only returns
+ one row.
4. Notes
diff --git a/contrib/pgstattuple/pgstattuple.c b/contrib/pgstattuple/pgstattuple.c
index a357f6f412..4fbc60bcf2 100644
--- a/contrib/pgstattuple/pgstattuple.c
+++ b/contrib/pgstattuple/pgstattuple.c
@@ -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;
-
- /* 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;
- }
+ /*
+ * Build a tuple description for a pgstattupe_type tuple
+ */
+ tupdesc = RelationNameGetTupleDesc(DUMMY_TUPLE);
- /* 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;
+ /* allocate a slot for a tuple with this tupdesc */
+ slot = TupleDescGetSlot(tupdesc);
- /* 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);
}
diff --git a/contrib/pgstattuple/pgstattuple.sql.in b/contrib/pgstattuple/pgstattuple.sql.in
index 7c661a8ee3..d3370fb830 100644
--- a/contrib/pgstattuple/pgstattuple.sql.in
+++ b/contrib/pgstattuple/pgstattuple.sql.in
@@ -1,16 +1,16 @@
-DROP VIEW pgstattuple_view CASCADE;
-CREATE VIEW pgstattuple_view AS
- SELECT
- 0::BIGINT AS table_len, -- physical table length in bytes
- 0::BIGINT AS tuple_count, -- number of live tuples
- 0::BIGINT AS tuple_len, -- total tuples length in bytes
- 0.0::FLOAT AS tuple_percent, -- live tuples in %
- 0::BIGINT AS dead_tuple_count, -- number of dead tuples
- 0::BIGINT AS dead_tuple_len, -- total dead tuples length in bytes
- 0.0::FLOAT AS dead_tuple_percent, -- dead tuples in %
- 0::BIGINT AS free_space, -- free space in bytes
- 0.0::FLOAT AS free_percent; -- free space in %
+DROP TYPE pgstattuple_type CASCADE;
+CREATE TYPE pgstattuple_type AS (
+ table_len BIGINT, -- physical table length in bytes
+ tuple_count BIGINT, -- number of live tuples
+ tuple_len BIGINT, -- total tuples length in bytes
+ tuple_percent FLOAT, -- live tuples in %
+ dead_tuple_count BIGINT, -- number of dead tuples
+ dead_tuple_len BIGINT, -- total dead tuples length in bytes
+ dead_tuple_percent FLOAT, -- dead tuples in %
+ free_space BIGINT, -- free space in bytes
+ free_percent FLOAT -- free space in %
+);
-CREATE OR REPLACE FUNCTION pgstattuple(text) RETURNS SETOF pgstattuple_view
+CREATE OR REPLACE FUNCTION pgstattuple(text) RETURNS pgstattuple_type
AS 'MODULE_PATHNAME', 'pgstattuple'
LANGUAGE 'c' WITH (isstrict);