SRF's + SPI

Поиск
Список
Период
Сортировка
От Eric B.Ridge
Тема SRF's + SPI
Дата
Msg-id da7c7eb07f7d2f295e53b936ecf07983@tcdi.com
обсуждение исходный текст
Ответы Re: SRF's + SPI  (Tom Lane <tgl@sss.pgh.pa.us>)
Список pgsql-hackers
With pg v7.4.7 I've written an SRF that uses SPI to return the results 
of a query.  It's one of those functions that works perfectly for me in 
development but randomly crashes in production.  Thus far I've been 
unable to reproduce the crash.  The problem is surely in my code.  And 
before I dig into debugging the hard stuff I would love a sanity check 
to verify that I'm using SPI_connect()/SPI_finish() correctly within 
the context of the SRF.

The backtrace from a core dump:
(gdb) bt
#0  0x0820ee29 in pfree ()
#1  0x08204a18 in end_MultiFuncCall ()
#2  0x4cee0f99 in my_src (fcinfo=0xbfffccd0) at foo.c:93
#3  0x0811058b in ExecMakeTableFunctionResult ()
#4  0x08750c78 in ?? ()
#5  0x00004000 in ?? ()
#6  0xbfffccac in ?? ()
#7  0xbfffcd88 in ?? ()

And the code at foo.c:93SRF_RETURN_DONE(funcctx);

I'm wondering if I'm using SPI incorrectly.  In the past I've had 
issues with incorrectly using SPI (esp with recursion), and I'm not 
entirely sure how it should work with SRF's.  Like I said, everything 
usually works without problems, but from time to time it crashes.  
Below is the basic outline of my code.

Any input will be greatly appreciated.

thanks!

eric

------------------------------
Datum my_srf (PG_FUNCTION_ARGS) {FuncCallContext    *funcctx;
        if (SRF_IS_FIRSTCALL()) {            MemoryContext oldcontext;    char *query;
    if(PG_ARGISNULL(0))        SRF_RETURN_DONE(NULL);  /* nothing to expand when arg[0] is null */
    funcctx = SRF_FIRSTCALL_INIT();
                oldcontext = 
MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
    query = < function call to build a query string >;
    SPI_connect();    if (SPI_exec(query, 0) != SPI_OK_SELECT)        elog(ERROR, "unable to execute fulltext query");
    funcctx->slot = TupleDescGetSlot(SPI_tuptable->tupdesc);    funcctx->attinmeta =
TupleDescGetAttInMetadata(SPI_tuptable->tupdesc);   funcctx->user_fctx = SPI_tuptable;    funcctx->call_cntr = 0;
funcctx->max_calls= SPI_processed;
 
                 MemoryContextSwitchTo(oldcontext);        }
funcctx = SRF_PERCALL_SETUP();
        if (funcctx->call_cntr < funcctx->max_calls) {    SPITupleTable *tuptable = (SPITupleTable *)
funcctx->user_fctx;   HeapTuple tuple;    Datum result;
 
    tuple = tuptable->vals[funcctx->call_cntr];    result = TupleGetDatum(funcctx->slot, tuple);
    SRF_RETURN_NEXT(funcctx, result);        } else {    SPI_finish();
line_93:                SRF_RETURN_DONE(funcctx);  /** XXX: CRASH HERE **/}
PG_RETURN_NULL();
}



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

Предыдущее
От: "Andrew Dunstan"
Дата:
Сообщение: Re: ARC patent
Следующее
От: "Mark Woodward"
Дата:
Сообщение: Re: ARC patent