Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 125bf34

Browse files
committed
Convert pg_stat_get_backend_idset to use the existing SRF support.
This seems the cleanest way of fixing its lack of a shutdown callback, which was preventing it from working correctly in a query that didn't run it to completion. Per bug report from Szima GÄbor.
1 parent b62aa83 commit 125bf34

File tree

1 file changed

+45
-29
lines changed

1 file changed

+45
-29
lines changed

src/backend/utils/adt/pgstatfuncs.c

Lines changed: 45 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,29 @@
1+
/*-------------------------------------------------------------------------
2+
*
3+
* pgstatfuncs.c
4+
* Functions for accessing the statistics collector data
5+
*
6+
* Portions Copyright (c) 1996-2004, PostgreSQL Global Development Group
7+
* Portions Copyright (c) 1994, Regents of the University of California
8+
*
9+
*
10+
* IDENTIFICATION
11+
* $PostgreSQL: pgsql/src/backend/utils/adt/pgstatfuncs.c,v 1.19 2004/10/01 21:03:42 tgl Exp $
12+
*
13+
*-------------------------------------------------------------------------
14+
*/
115
#include "postgres.h"
216

3-
#include "fmgr.h"
4-
#include "miscadmin.h"
5-
#include "utils/hsearch.h"
617
#include "access/xact.h"
718
#include "catalog/pg_shadow.h"
19+
#include "fmgr.h"
20+
#include "funcapi.h"
21+
#include "miscadmin.h"
822
#include "nodes/execnodes.h"
9-
1023
#include "pgstat.h"
24+
#include "utils/hsearch.h"
1125

26+
/* bogus ... these externs should be in a header file */
1227
extern Datum pg_stat_get_numscans(PG_FUNCTION_ARGS);
1328
extern Datum pg_stat_get_tuples_returned(PG_FUNCTION_ARGS);
1429
extern Datum pg_stat_get_tuples_fetched(PG_FUNCTION_ARGS);
@@ -181,40 +196,41 @@ pg_stat_get_blocks_hit(PG_FUNCTION_ARGS)
181196
Datum
182197
pg_stat_get_backend_idset(PG_FUNCTION_ARGS)
183198
{
184-
FmgrInfo *fmgr_info = fcinfo->flinfo;
199+
FuncCallContext *funcctx;
200+
int *fctx;
185201
int32 result;
186202

187-
if (fcinfo->resultinfo == NULL ||
188-
!IsA(fcinfo->resultinfo, ReturnSetInfo))
189-
ereport(ERROR,
190-
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
191-
errmsg("set-valued function called in context that "
192-
"cannot accept a set")));
193-
194-
if (fmgr_info->fn_extra == NULL)
203+
/* stuff done only on the first call of the function */
204+
if (SRF_IS_FIRSTCALL())
195205
{
196-
if (fmgr_info->fn_mcxt == NULL)
197-
elog(ERROR, "no function memory context in set-function");
206+
/* create a function context for cross-call persistence */
207+
funcctx = SRF_FIRSTCALL_INIT();
198208

199-
fmgr_info->fn_extra = MemoryContextAlloc(fmgr_info->fn_mcxt,
200-
2 * sizeof(int));
201-
((int *) (fmgr_info->fn_extra))[0] = 0;
202-
((int *) (fmgr_info->fn_extra))[1] = pgstat_fetch_stat_numbackends();
209+
fctx = MemoryContextAlloc(funcctx->multi_call_memory_ctx,
210+
2 * sizeof(int));
211+
funcctx->user_fctx = fctx;
212+
213+
fctx[0] = 0;
214+
fctx[1] = pgstat_fetch_stat_numbackends();
203215
}
204216

205-
((int *) (fmgr_info->fn_extra))[0] += 1;
206-
result = ((int *) (fmgr_info->fn_extra))[0];
217+
/* stuff done on every call of the function */
218+
funcctx = SRF_PERCALL_SETUP();
219+
fctx = funcctx->user_fctx;
220+
221+
fctx[0] += 1;
222+
result = fctx[0];
207223

208-
if (result > ((int *) (fmgr_info->fn_extra))[1])
224+
if (result <= fctx[1])
209225
{
210-
pfree(fmgr_info->fn_extra);
211-
fmgr_info->fn_extra = NULL;
212-
((ReturnSetInfo *) (fcinfo->resultinfo))->isDone = ExprEndResult;
213-
PG_RETURN_NULL();
226+
/* do when there is more left to send */
227+
SRF_RETURN_NEXT(funcctx, Int32GetDatum(result));
228+
}
229+
else
230+
{
231+
/* do when there is no more left */
232+
SRF_RETURN_DONE(funcctx);
214233
}
215-
216-
((ReturnSetInfo *) (fcinfo->resultinfo))->isDone = ExprMultipleResult;
217-
PG_RETURN_INT32(result);
218234
}
219235

220236

0 commit comments

Comments
 (0)