Dear list,
I solved my own problem - as so often, once you write it down and press the
send button you get the idea.
The problem was:
> Currently I am working on a user C-Function which should create a cache
> object on the first call and afterwards return a set of computed values for
> each argument combination it is called with.
>
> My Problem is how to get the cache object saved over multiple calls. Without
> the SRF I could use fcinfo->flinfo->fn_extra for my pointer to the data. This
> is now used by the FuncCallContext structure. This structure is destroyed
> every time SRF_RETURN_DONE is called, thus user_fctx also is not the way to
> go.
My solution:
--------------------------------------------------- snip
---------------------------------------------------
struct myData {
FuncCallContext *funcctx;
// own Data
int cachedObject;
} myData
PG_FUNCTION_INFO_V1(test);
Datum test(PG_FUNCTION_ARGS)
{
MemoryContext old_context;
FuncCallContext *funcctx;
myData *str;
// Get fn_extra
str = fcinfo->flinfo->fn_extra;
if ( ! str) {
elog(NOTICE, "create new");
old_context = MemoryContextSwitchTo(fcinfo->flinfo->fn_mcxt);
// Fill str with data around here ...
MemoryContextSwitchTo(old_context);
str->funcctx = NULL;
}
// This is the situation the SRF-macros expect:
fcinfo->flinfo->fn_extra = str->funcctx;
if (SRF_IS_FIRSTCALL()) {
funcctx = SRF_FIRSTCALL_INIT();
// Your commands
}
funcctx = SRF_PERCALL_SETUP();
// This is the macro SRF_RETURN_DONE(funcctx);
// Before we finally return we save our str in fn_extra and fn_extra in
str->funcctx.
do {
ReturnSetInfo *rsi;
end_MultiFuncCall(fcinfo, funcctx);
rsi = (ReturnSetInfo *) fcinfo->resultinfo;
rsi->isDone = ExprEndResult;
// -- Modify macro here --
str->funcctx = fcinfo->flinfo->fn_extra;
fcinfo->flinfo->fn_extra = str;
// -- End modification --
PG_RETURN_NULL();
} while (0);
// Of course, SRF_RETURN_DATUM has to be adapted the same way!
}
--------------------------------------------------- snip
---------------------------------------------------
Regards,
Thilo Schneider
--
Sent via pgsql-general mailing list ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-general