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

Commit b2a8f46

Browse files
author
Nikita Glukhov
committed
Add user-specified SRF state placement
1 parent 889305d commit b2a8f46

File tree

2 files changed

+29
-20
lines changed

2 files changed

+29
-20
lines changed

src/backend/utils/fmgr/funcapi.c

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ static TypeFuncClass get_type_func_class(Oid typid, Oid *base_typeid);
5050
* and error checking
5151
*/
5252
FuncCallContext *
53-
init_MultiFuncCall(PG_FUNCTION_ARGS)
53+
init_MultiFuncCall(PG_FUNCTION_ARGS, FuncCallContext **pfuncctx)
5454
{
5555
FuncCallContext *retval;
5656

@@ -62,7 +62,7 @@ init_MultiFuncCall(PG_FUNCTION_ARGS)
6262
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
6363
errmsg("set-valued function called in context that cannot accept a set")));
6464

65-
if (fcinfo->flinfo->fn_extra == NULL)
65+
if (*pfuncctx == NULL)
6666
{
6767
/*
6868
* First call
@@ -97,15 +97,15 @@ init_MultiFuncCall(PG_FUNCTION_ARGS)
9797
/*
9898
* save the pointer for cross-call use
9999
*/
100-
fcinfo->flinfo->fn_extra = retval;
100+
*pfuncctx = retval;
101101

102102
/*
103103
* Ensure we will get shut down cleanly if the exprcontext is not run
104104
* to completion.
105105
*/
106106
RegisterExprContextCallback(rsi->econtext,
107107
shutdown_MultiFuncCall,
108-
PointerGetDatum(fcinfo->flinfo));
108+
PointerGetDatum(pfuncctx));
109109
}
110110
else
111111
{
@@ -125,9 +125,9 @@ init_MultiFuncCall(PG_FUNCTION_ARGS)
125125
* Do Multi-function per-call setup
126126
*/
127127
FuncCallContext *
128-
per_MultiFuncCall(PG_FUNCTION_ARGS)
128+
per_MultiFuncCall(PG_FUNCTION_ARGS, FuncCallContext **pfuncctx)
129129
{
130-
FuncCallContext *retval = (FuncCallContext *) fcinfo->flinfo->fn_extra;
130+
FuncCallContext *retval = *pfuncctx;
131131

132132
return retval;
133133
}
@@ -137,17 +137,18 @@ per_MultiFuncCall(PG_FUNCTION_ARGS)
137137
* Clean up after init_MultiFuncCall
138138
*/
139139
void
140-
end_MultiFuncCall(PG_FUNCTION_ARGS, FuncCallContext *funcctx)
140+
end_MultiFuncCall(PG_FUNCTION_ARGS, FuncCallContext *funcctx,
141+
FuncCallContext **pfuncctx)
141142
{
142143
ReturnSetInfo *rsi = (ReturnSetInfo *) fcinfo->resultinfo;
143144

144145
/* Deregister the shutdown callback */
145146
UnregisterExprContextCallback(rsi->econtext,
146147
shutdown_MultiFuncCall,
147-
PointerGetDatum(fcinfo->flinfo));
148+
PointerGetDatum(pfuncctx));
148149

149150
/* But use it to do the real work */
150-
shutdown_MultiFuncCall(PointerGetDatum(fcinfo->flinfo));
151+
shutdown_MultiFuncCall(PointerGetDatum(pfuncctx));
151152
}
152153

153154
/*
@@ -157,11 +158,11 @@ end_MultiFuncCall(PG_FUNCTION_ARGS, FuncCallContext *funcctx)
157158
static void
158159
shutdown_MultiFuncCall(Datum arg)
159160
{
160-
FmgrInfo *flinfo = (FmgrInfo *) DatumGetPointer(arg);
161-
FuncCallContext *funcctx = (FuncCallContext *) flinfo->fn_extra;
161+
FuncCallContext **pfuncctx = (FuncCallContext **) DatumGetPointer(arg);
162+
FuncCallContext *funcctx = *pfuncctx;
162163

163164
/* unbind from flinfo */
164-
flinfo->fn_extra = NULL;
165+
*pfuncctx = NULL;
165166

166167
/*
167168
* Delete context that holds all multi-call data, including the

src/include/funcapi.h

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -276,15 +276,20 @@ extern Datum HeapTupleHeaderGetDatum(HeapTupleHeader tuple);
276276
*/
277277

278278
/* from funcapi.c */
279-
extern FuncCallContext *init_MultiFuncCall(PG_FUNCTION_ARGS);
280-
extern FuncCallContext *per_MultiFuncCall(PG_FUNCTION_ARGS);
281-
extern void end_MultiFuncCall(PG_FUNCTION_ARGS, FuncCallContext *funcctx);
279+
extern FuncCallContext *init_MultiFuncCall(PG_FUNCTION_ARGS, FuncCallContext **pfuncctx);
280+
extern FuncCallContext *per_MultiFuncCall(PG_FUNCTION_ARGS, FuncCallContext **pfuncctx);
281+
extern void end_MultiFuncCall(PG_FUNCTION_ARGS, FuncCallContext *funcctx, FuncCallContext **pfuncctx);
282282

283-
#define SRF_IS_FIRSTCALL() (fcinfo->flinfo->fn_extra == NULL)
283+
#define SRF_DEFAULT_FCTX ((FuncCallContext **) &fcinfo->flinfo->fn_extra)
284284

285-
#define SRF_FIRSTCALL_INIT() init_MultiFuncCall(fcinfo)
285+
#define SRF_IS_FIRSTCALL_EXT(_pfuncctx) (*(_pfuncctx) == NULL)
286+
#define SRF_IS_FIRSTCALL() SRF_IS_FIRSTCALL_EXT(SRF_DEFAULT_FCTX)
286287

287-
#define SRF_PERCALL_SETUP() per_MultiFuncCall(fcinfo)
288+
#define SRF_FIRSTCALL_INIT_EXT(_pfuncctx) init_MultiFuncCall(fcinfo, _pfuncctx)
289+
#define SRF_FIRSTCALL_INIT() SRF_FIRSTCALL_INIT_EXT(SRF_DEFAULT_FCTX)
290+
291+
#define SRF_PERCALL_SETUP_EXT(_pfuncctx) per_MultiFuncCall(fcinfo, _pfuncctx)
292+
#define SRF_PERCALL_SETUP() SRF_PERCALL_SETUP_EXT(SRF_DEFAULT_FCTX)
288293

289294
#define SRF_RETURN_NEXT(_funcctx, _result) \
290295
do { \
@@ -304,15 +309,18 @@ extern void end_MultiFuncCall(PG_FUNCTION_ARGS, FuncCallContext *funcctx);
304309
PG_RETURN_NULL(); \
305310
} while (0)
306311

307-
#define SRF_RETURN_DONE(_funcctx) \
312+
#define SRF_RETURN_DONE_EXT(_funcctx, _pfuncctx) \
308313
do { \
309314
ReturnSetInfo *rsi; \
310-
end_MultiFuncCall(fcinfo, _funcctx); \
315+
end_MultiFuncCall(fcinfo, _funcctx, _pfuncctx); \
311316
rsi = (ReturnSetInfo *) fcinfo->resultinfo; \
312317
rsi->isDone = ExprEndResult; \
313318
PG_RETURN_NULL(); \
314319
} while (0)
315320

321+
#define SRF_RETURN_DONE(_funcctx) \
322+
SRF_RETURN_DONE_EXT(_funcctx, SRF_DEFAULT_FCTX)
323+
316324
/*----------
317325
* Support to ease writing of functions dealing with VARIADIC inputs
318326
*----------

0 commit comments

Comments
 (0)