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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy