|
| 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 | + */ |
1 | 15 | #include "postgres.h"
|
2 | 16 |
|
3 |
| -#include "fmgr.h" |
4 |
| -#include "miscadmin.h" |
5 |
| -#include "utils/hsearch.h" |
6 | 17 | #include "access/xact.h"
|
7 | 18 | #include "catalog/pg_shadow.h"
|
| 19 | +#include "fmgr.h" |
| 20 | +#include "funcapi.h" |
| 21 | +#include "miscadmin.h" |
8 | 22 | #include "nodes/execnodes.h"
|
9 |
| - |
10 | 23 | #include "pgstat.h"
|
| 24 | +#include "utils/hsearch.h" |
11 | 25 |
|
| 26 | +/* bogus ... these externs should be in a header file */ |
12 | 27 | extern Datum pg_stat_get_numscans(PG_FUNCTION_ARGS);
|
13 | 28 | extern Datum pg_stat_get_tuples_returned(PG_FUNCTION_ARGS);
|
14 | 29 | extern Datum pg_stat_get_tuples_fetched(PG_FUNCTION_ARGS);
|
@@ -181,40 +196,41 @@ pg_stat_get_blocks_hit(PG_FUNCTION_ARGS)
|
181 | 196 | Datum
|
182 | 197 | pg_stat_get_backend_idset(PG_FUNCTION_ARGS)
|
183 | 198 | {
|
184 |
| - FmgrInfo *fmgr_info = fcinfo->flinfo; |
| 199 | + FuncCallContext *funcctx; |
| 200 | + int *fctx; |
185 | 201 | int32 result;
|
186 | 202 |
|
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()) |
195 | 205 | {
|
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(); |
198 | 208 |
|
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(); |
203 | 215 | }
|
204 | 216 |
|
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]; |
207 | 223 |
|
208 |
| - if (result > ((int *) (fmgr_info->fn_extra))[1]) |
| 224 | + if (result <= fctx[1]) |
209 | 225 | {
|
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); |
214 | 233 | }
|
215 |
| - |
216 |
| - ((ReturnSetInfo *) (fcinfo->resultinfo))->isDone = ExprMultipleResult; |
217 |
| - PG_RETURN_INT32(result); |
218 | 234 | }
|
219 | 235 |
|
220 | 236 |
|
|
0 commit comments