From 125bf342fd98b2b1deef20bcf3028e4dda0445fb Mon Sep 17 00:00:00 2001 From: Tom Lane <tgl@sss.pgh.pa.us> Date: Fri, 1 Oct 2004 21:03:42 +0000 Subject: [PATCH] =?UTF-8?q?Convert=20pg=5Fstat=5Fget=5Fbackend=5Fidset=20t?= =?UTF-8?q?o=20use=20the=20existing=20SRF=20support.=20This=20seems=20the?= =?UTF-8?q?=20cleanest=20way=20of=20fixing=20its=20lack=20of=20a=20shutdow?= =?UTF-8?q?n=20callback,=20which=20was=20preventing=20it=20from=20working?= =?UTF-8?q?=20correctly=20in=20a=20query=20that=20didn't=20run=20it=20to?= =?UTF-8?q?=20completion.=20=20Per=20bug=20report=20from=20Szima=20G=C3=84?= =?UTF-8?q?bor.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/backend/utils/adt/pgstatfuncs.c | 74 ++++++++++++++++++----------- 1 file changed, 45 insertions(+), 29 deletions(-) diff --git a/src/backend/utils/adt/pgstatfuncs.c b/src/backend/utils/adt/pgstatfuncs.c index 03166eac482..f648b0c1cd2 100644 --- a/src/backend/utils/adt/pgstatfuncs.c +++ b/src/backend/utils/adt/pgstatfuncs.c @@ -1,14 +1,29 @@ +/*------------------------------------------------------------------------- + * + * pgstatfuncs.c + * Functions for accessing the statistics collector data + * + * Portions Copyright (c) 1996-2004, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * + * IDENTIFICATION + * $PostgreSQL: pgsql/src/backend/utils/adt/pgstatfuncs.c,v 1.19 2004/10/01 21:03:42 tgl Exp $ + * + *------------------------------------------------------------------------- + */ #include "postgres.h" -#include "fmgr.h" -#include "miscadmin.h" -#include "utils/hsearch.h" #include "access/xact.h" #include "catalog/pg_shadow.h" +#include "fmgr.h" +#include "funcapi.h" +#include "miscadmin.h" #include "nodes/execnodes.h" - #include "pgstat.h" +#include "utils/hsearch.h" +/* bogus ... these externs should be in a header file */ extern Datum pg_stat_get_numscans(PG_FUNCTION_ARGS); extern Datum pg_stat_get_tuples_returned(PG_FUNCTION_ARGS); extern Datum pg_stat_get_tuples_fetched(PG_FUNCTION_ARGS); @@ -181,40 +196,41 @@ pg_stat_get_blocks_hit(PG_FUNCTION_ARGS) Datum pg_stat_get_backend_idset(PG_FUNCTION_ARGS) { - FmgrInfo *fmgr_info = fcinfo->flinfo; + FuncCallContext *funcctx; + int *fctx; int32 result; - if (fcinfo->resultinfo == NULL || - !IsA(fcinfo->resultinfo, ReturnSetInfo)) - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("set-valued function called in context that " - "cannot accept a set"))); - - if (fmgr_info->fn_extra == NULL) + /* stuff done only on the first call of the function */ + if (SRF_IS_FIRSTCALL()) { - if (fmgr_info->fn_mcxt == NULL) - elog(ERROR, "no function memory context in set-function"); + /* create a function context for cross-call persistence */ + funcctx = SRF_FIRSTCALL_INIT(); - fmgr_info->fn_extra = MemoryContextAlloc(fmgr_info->fn_mcxt, - 2 * sizeof(int)); - ((int *) (fmgr_info->fn_extra))[0] = 0; - ((int *) (fmgr_info->fn_extra))[1] = pgstat_fetch_stat_numbackends(); + fctx = MemoryContextAlloc(funcctx->multi_call_memory_ctx, + 2 * sizeof(int)); + funcctx->user_fctx = fctx; + + fctx[0] = 0; + fctx[1] = pgstat_fetch_stat_numbackends(); } - ((int *) (fmgr_info->fn_extra))[0] += 1; - result = ((int *) (fmgr_info->fn_extra))[0]; + /* stuff done on every call of the function */ + funcctx = SRF_PERCALL_SETUP(); + fctx = funcctx->user_fctx; + + fctx[0] += 1; + result = fctx[0]; - if (result > ((int *) (fmgr_info->fn_extra))[1]) + if (result <= fctx[1]) { - pfree(fmgr_info->fn_extra); - fmgr_info->fn_extra = NULL; - ((ReturnSetInfo *) (fcinfo->resultinfo))->isDone = ExprEndResult; - PG_RETURN_NULL(); + /* do when there is more left to send */ + SRF_RETURN_NEXT(funcctx, Int32GetDatum(result)); + } + else + { + /* do when there is no more left */ + SRF_RETURN_DONE(funcctx); } - - ((ReturnSetInfo *) (fcinfo->resultinfo))->isDone = ExprMultipleResult; - PG_RETURN_INT32(result); } -- GitLab