Re: Set Returning C-Function with cache over multiple calls (with different arguments)

Поиск
Список
Период
Сортировка
От Thilo Schneider
Тема Re: Set Returning C-Function with cache over multiple calls (with different arguments)
Дата
Msg-id 0B1C85E5-77BF-4318-AFAE-E1C1E596AFFB@thiloschneider.net
обсуждение исходный текст
Ответ на Set Returning C-Function with cache over multiple calls (with different arguments)  (Thilo Schneider <Thilo.Schneider@math.uni-giessen.de>)
Список pgsql-general
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
returna 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_extrafor my pointer to the data. This is now used by the FuncCallContext structure. This structure
isdestroyed 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

В списке pgsql-general по дате отправления:

Предыдущее
От: Michael Felt
Дата:
Сообщение: Test build of postgres v8.4.2 available
Следующее
От: "tamanna madaan"
Дата:
Сообщение: does autovacuum in postgres-8.1.2 use prepared transactions ??